From 90807f0f31287ffdea49b0222fe65b90bc2cb9ef Mon Sep 17 00:00:00 2001 From: Devesh Sarda Date: Mon, 12 Feb 2024 17:35:35 -0600 Subject: [PATCH] Simulator push --- .gitignore | 3 +- CMakeLists.txt | 2 +- simulator/configs/arvix.json | 8 + simulator/configs/papers.json | 3 + simulator/images/arvix.png | Bin 0 -> 29575 bytes simulator/main.py | 52 + simulator/src/__init__.py | 0 simulator/src/dataset_loader.py | 52 + simulator/src/features_loader.py | 21 + simulator/src/sampler.py | 10 + simulator/src/visualizer.py | 18 + src/cpp/src/data/dataloader.cpp | 4 +- src/cpp/src/nn/encoders/encoder.cpp | 4 +- src/cpp/src/nn/layers/gnn/gat_layer.cpp | 5 + src/cpp/src/nn/layers/gnn/layer_helpers.cpp | 2 + src/cpp/src/nn/model.cpp | 1 - src/cpp/src/pipeline/trainer.cpp | 1 - src/cpp/src/storage/buffer.cpp | 1 + src/cpp/src/storage/graph_storage.cpp | 19 +- src/cpp/src/storage/io.cpp | 1 - src/cpp/src/storage/storage.cpp | 3 + test/test_data/example_edges_with_weights.csv | 1200 +++++++++++++++++ test/test_data/reformat_test_data.py | 23 + test/test_data/train_edges_weights.txt | 1000 -------------- 24 files changed, 1421 insertions(+), 1012 deletions(-) create mode 100644 simulator/configs/arvix.json create mode 100644 simulator/configs/papers.json create mode 100644 simulator/images/arvix.png create mode 100644 simulator/main.py create mode 100644 simulator/src/__init__.py create mode 100644 simulator/src/dataset_loader.py create mode 100644 simulator/src/features_loader.py create mode 100644 simulator/src/sampler.py create mode 100644 simulator/src/visualizer.py create mode 100644 test/test_data/example_edges_with_weights.csv create mode 100644 test/test_data/reformat_test_data.py delete mode 100644 test/test_data/train_edges_weights.txt diff --git a/.gitignore b/.gitignore index cb30fe25..a21e76b8 100644 --- a/.gitignore +++ b/.gitignore @@ -173,4 +173,5 @@ Thumbs.db # End of https://www.toptal.com/developers/gitignore/api/python src/cpp/third_party -test_datasets \ No newline at end of file +test_datasets +simulator/datasets \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index f7450edb..dcd56246 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -247,4 +247,4 @@ pybind11_add_module(_storage ${STORAGE_BINDINGS}) target_link_libraries(_storage PRIVATE ${PROJECT_NAME} ${TORCH_PYTHON_LIBRARY}) add_custom_target(bindings) -add_dependencies(bindings _config _data _manager _nn _pipeline _report _storage) +add_dependencies(bindings _config _data _manager _nn _pipeline _report _storage) \ No newline at end of file diff --git a/simulator/configs/arvix.json b/simulator/configs/arvix.json new file mode 100644 index 00000000..5fc912d3 --- /dev/null +++ b/simulator/configs/arvix.json @@ -0,0 +1,8 @@ +{ + "dataset_name" : "ogbn_arxiv", + "features_stats" : { + "page_size" : "16 KB", + "feature_dimension" : 128, + "feature_size" : "float32" + } +} \ No newline at end of file diff --git a/simulator/configs/papers.json b/simulator/configs/papers.json new file mode 100644 index 00000000..a0378734 --- /dev/null +++ b/simulator/configs/papers.json @@ -0,0 +1,3 @@ +{ + "dataset_name" : "ogbn_papers100m" +} \ No newline at end of file diff --git a/simulator/images/arvix.png b/simulator/images/arvix.png new file mode 100644 index 0000000000000000000000000000000000000000..08be886b3cfc82c28f5cf04f7a3f57727bdce88d GIT binary patch literal 29575 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 Uv> 0: + pages_loaded.append(num_pages_read) + print("Got result for", len(pages_loaded), "nodes out of", len(nodes_to_sample), "nodes") + + # Save the histogram + save_path = os.path.join(IMAGES_SAVE_DIR, os.path.basename(arguments.config_file).replace("json", "png")) + visualize_results(pages_loaded, save_path, config["dataset_name"]) + + +if __name__ == "__main__": + main() diff --git a/simulator/src/__init__.py b/simulator/src/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/simulator/src/dataset_loader.py b/simulator/src/dataset_loader.py new file mode 100644 index 00000000..2e9ed74c --- /dev/null +++ b/simulator/src/dataset_loader.py @@ -0,0 +1,52 @@ +import subprocess +import os +import numpy as np +from collections import defaultdict + + +class DatasetLoader: + SAVE_DIR = "datasets" + EDGES_PATH = "edges/train_edges.bin" + + def __init__(self, name): + self.name = name + os.makedirs(DatasetLoader.SAVE_DIR, exist_ok=True) + self.save_dir = os.path.join(DatasetLoader.SAVE_DIR, self.name) + if not os.path.exists(self.save_dir): + self.create_dataset() + self.load_dataset() + + def create_dataset(self): + command_to_run = f"marius_preprocess --dataset {self.name} --output_directory {self.save_dir}" + print("Running command", command_to_run) + subprocess.check_output(command_to_run, shell=True) + + def load_dataset(self): + # Load the file + edges_path = os.path.join(self.save_dir, DatasetLoader.EDGES_PATH) + with open(edges_path, "rb") as reader: + edges_bytes = reader.read() + + # Create the adjacency map + edges_flaten_arr = np.frombuffer(edges_bytes, dtype=np.int32) + self.nodes = set(edges_flaten_arr) + edges_arr = edges_flaten_arr.reshape((-1, 2)) + self.num_edges = len(edges_arr) + + self.adjacency_map = {} + for source, target in edges_arr: + if source not in self.adjacency_map: + self.adjacency_map[source] = [] + self.adjacency_map[source].append(target) + + def get_num_nodes(self): + return len(self.nodes) + + def get_neigbhors_for_node(self, node_id): + if node_id not in self.adjacency_map: + return [] + + return self.adjacency_map[node_id] + + def get_num_edges(self): + return self.num_edges diff --git a/simulator/src/features_loader.py b/simulator/src/features_loader.py new file mode 100644 index 00000000..eb17a3ef --- /dev/null +++ b/simulator/src/features_loader.py @@ -0,0 +1,21 @@ +import humanfriendly +import os +import math + + +class FeaturesLoader: + def __init__(self, data_loader, features_stat): + self.data_loader = data_loader + self.page_size = humanfriendly.parse_size(features_stat["page_size"]) + self.feature_size = int("".join(c for c in features_stat["feature_size"] if c.isdigit())) + self.node_feature_size = self.feature_size * features_stat["feature_dimension"] + + self.nodes_per_page = max(int(self.page_size / self.node_feature_size), 1) + self.total_pages = int(math.ceil(data_loader.get_num_nodes() / (1.0 * self.nodes_per_page))) + + def get_node_page(self, node_id): + return int(node_id / self.nodes_per_page) + + def get_total_file_size(self): + total_bytes = self.page_size * self.total_bytes + return humanfriendly.format_size(total_bytes) diff --git a/simulator/src/sampler.py b/simulator/src/sampler.py new file mode 100644 index 00000000..f755d6c8 --- /dev/null +++ b/simulator/src/sampler.py @@ -0,0 +1,10 @@ +class SubgraphSampler: + def __init__(self, data_loader, features_loader): + self.data_loader = data_loader + self.features_loader = features_loader + + def perform_sampling_for_node(self, node_id): + pages_read = set() + for neighbor in self.data_loader.get_neigbhors_for_node(node_id): + pages_read.add(self.features_loader.get_node_page(neighbor)) + return len(pages_read) diff --git a/simulator/src/visualizer.py b/simulator/src/visualizer.py new file mode 100644 index 00000000..f75d2832 --- /dev/null +++ b/simulator/src/visualizer.py @@ -0,0 +1,18 @@ +import matplotlib.pyplot as plt +import os + + +def visualize_results(pages_loaded, save_path, dataset_name, num_bins=50): + # Create the histogram + plt.figure() + plt.ecdf(pages_loaded, label="CDF") + plt.hist(pages_loaded, bins=num_bins, histtype="step", density=True, cumulative=True, label="Cumulative histogram") + plt.xlabel("Number of pages loaded for node inference") + plt.ylabel("Percentage of nodes") + plt.title("Number of pages loaded for node inference on " + dataset_name) + plt.xlim(0, 50) + plt.legend() + + # Save the result + print("Saving the result to", save_path) + plt.savefig(save_path) diff --git a/src/cpp/src/data/dataloader.cpp b/src/cpp/src/data/dataloader.cpp index 14a19220..f9ce3bba 100644 --- a/src/cpp/src/data/dataloader.cpp +++ b/src/cpp/src/data/dataloader.cpp @@ -288,9 +288,9 @@ void DataLoader::setBufferOrdering() { if (graph_storage_->useInMemorySubGraph()) { auto tup = getEdgeBucketOrdering(options->edge_bucket_ordering, options->num_partitions, options->buffer_capacity, options->fine_to_coarse_ratio, options->num_cache_partitions, options->randomly_assign_edge_buckets); + buffer_states_ = std::get<0>(tup); edge_buckets_per_buffer_ = std::get<1>(tup); - edge_buckets_per_buffer_iterator_ = edge_buckets_per_buffer_.begin(); graph_storage_->setBufferOrdering(buffer_states_); @@ -304,7 +304,6 @@ void DataLoader::setBufferOrdering() { graph_storage_->getNumNodes(), options->num_partitions, options->buffer_capacity, options->fine_to_coarse_ratio, options->num_cache_partitions); buffer_states_ = std::get<0>(tup); node_ids_per_buffer_ = std::get<1>(tup); - node_ids_per_buffer_iterator_ = node_ids_per_buffer_.begin(); graph_storage_->setBufferOrdering(buffer_states_); @@ -367,6 +366,7 @@ shared_ptr DataLoader::getNextBatch() { } batch_lock.unlock(); batch_cv_->notify_all(); + return batch; } diff --git a/src/cpp/src/nn/encoders/encoder.cpp b/src/cpp/src/nn/encoders/encoder.cpp index 6245bedf..e231dc84 100644 --- a/src/cpp/src/nn/encoders/encoder.cpp +++ b/src/cpp/src/nn/encoders/encoder.cpp @@ -120,7 +120,7 @@ shared_ptr GeneralEncoder::initGNNLayer(std::shared_ptr laye auto options = std::dynamic_pointer_cast(layer_config->options); std::shared_ptr layer; - + bool is_none = options->type == GNNLayerType::NONE; if (options->type == GNNLayerType::GRAPH_SAGE) { string name = "graph_sage_layer:" + std::to_string(stage_id) + "_" + std::to_string(layer_id); layer = std::make_shared(layer_config, device_); @@ -138,7 +138,7 @@ shared_ptr GeneralEncoder::initGNNLayer(std::shared_ptr laye layer = std::make_shared(layer_config, num_relations_, device_); register_module(name, std::dynamic_pointer_cast(layer)); } else { - throw std::runtime_error("Unrecognized GNN layer type"); + throw std::runtime_error("Unrecognized GNN layer type of"); } return layer; diff --git a/src/cpp/src/nn/layers/gnn/gat_layer.cpp b/src/cpp/src/nn/layers/gnn/gat_layer.cpp index 6d2505ba..ea5eb63a 100644 --- a/src/cpp/src/nn/layers/gnn/gat_layer.cpp +++ b/src/cpp/src/nn/layers/gnn/gat_layer.cpp @@ -103,6 +103,11 @@ torch::Tensor GATLayer::forward(torch::Tensor inputs, DENSEGraph dense_graph, bo nbr_atn_weights = nbr_atn_weights.transpose(0, 2); // [total_num_nbrs, 1, num_heads_] self_atn_weights = self_atn_weights.transpose(0, 2); // [num_to_encode, 1, num_heads_] + std::cout << "nbr_atn_weights sizes " << nbr_atn_weights.sizes() << std::endl; + std::cout << "self_atn_weights sizes " << self_atn_weights.sizes() << std::endl; + std::cout << "neighbor_offsets sizes " << neighbor_offsets.sizes() << std::endl; + std::cout << "parent_ids sizes " << parent_ids.sizes() << std::endl; + std::cout << "total_neighbors sizes " << total_neighbors.sizes() << std::endl; std::tie(nbr_atn_weights, self_atn_weights) = attention_softmax(nbr_atn_weights, self_atn_weights, neighbor_offsets, parent_ids, total_neighbors); nbr_atn_weights = nbr_atn_weights.transpose(0, 2); diff --git a/src/cpp/src/nn/layers/gnn/layer_helpers.cpp b/src/cpp/src/nn/layers/gnn/layer_helpers.cpp index 62534f78..d4462448 100644 --- a/src/cpp/src/nn/layers/gnn/layer_helpers.cpp +++ b/src/cpp/src/nn/layers/gnn/layer_helpers.cpp @@ -46,7 +46,9 @@ std::tuple attention_softmax(torch::Tensor neighbo torch::Tensor has_nbrs_mask = torch::not_equal(num_nbrs, 0); has_nbrs_mask = has_nbrs_mask.reshape({-1, 1, 1}); + std::cout << "Neighbor attention of size " << neighbor_attention.sizes() << ", and segment offsets of size " << segment_offsets.sizes() << std::endl; torch::Tensor seg_max = segmented_max_with_offsets(neighbor_attention, segment_offsets); + std::cout << "seg_max of sizes " << seg_max.sizes() << ", and attention of sizes " << self_attention.sizes() << std::endl; torch::Tensor attention_max = torch::where(has_nbrs_mask, torch::maximum(seg_max, self_attention), self_attention); self_attention = torch::exp(self_attention - attention_max); diff --git a/src/cpp/src/nn/model.cpp b/src/cpp/src/nn/model.cpp index bd80c44f..98eb920e 100644 --- a/src/cpp/src/nn/model.cpp +++ b/src/cpp/src/nn/model.cpp @@ -300,7 +300,6 @@ void Model::train_batch(shared_ptr batch, bool call_step) { if (learning_task_ == LearningTask::LINK_PREDICTION) { auto all_scores = forward_lp(batch, true); - torch::Tensor pos_scores = std::get<0>(all_scores); torch::Tensor neg_scores = std::get<1>(all_scores); torch::Tensor inv_pos_scores = std::get<2>(all_scores); diff --git a/src/cpp/src/pipeline/trainer.cpp b/src/cpp/src/pipeline/trainer.cpp index 1af6dfa0..945637dd 100644 --- a/src/cpp/src/pipeline/trainer.cpp +++ b/src/cpp/src/pipeline/trainer.cpp @@ -118,7 +118,6 @@ void SynchronousTrainer::train(int num_epochs) { while (dataloader_->hasNextBatch()) { // gets data and parameters for the next batch shared_ptr batch = dataloader_->getBatch(); - if (dataloader_->graph_storage_->embeddingsOffDevice()) { // transfers batch to the GPU batch->to(model_->device_); diff --git a/src/cpp/src/storage/buffer.cpp b/src/cpp/src/storage/buffer.cpp index 1034d81e..ca94bb92 100644 --- a/src/cpp/src/storage/buffer.cpp +++ b/src/cpp/src/storage/buffer.cpp @@ -376,6 +376,7 @@ void PartitionBuffer::load() { SPDLOG_ERROR("Unable to allocate buffer memory\nError: {}", errno); throw std::runtime_error(""); } + memset_wrapper(buff_mem_, 0, capacity_ * partition_size_ * embedding_size_ * dtype_size_); buffer_tensor_view_ = torch::from_blob(buff_mem_, {capacity_ * partition_size_, embedding_size_}, dtype_); diff --git a/src/cpp/src/storage/graph_storage.cpp b/src/cpp/src/storage/graph_storage.cpp index 63a92adb..07b1db4e 100644 --- a/src/cpp/src/storage/graph_storage.cpp +++ b/src/cpp/src/storage/graph_storage.cpp @@ -352,10 +352,19 @@ bool GraphModelStorage::embeddingsOffDevice() { } } +void printTensor(std::string tensor_name, torch::Tensor tensor) { + auto data_ptr = tensor.data_ptr(); + int num_elements = tensor.numel(); + std::cout << "Tensor " << tensor_name << " has values: "; + for (int i = 0; i < num_elements; ++i) { + std::cout << data_ptr[i] << " "; + } + std::cout << std::endl; +} + void GraphModelStorage::initializeInMemorySubGraph(torch::Tensor buffer_state, int num_hash_maps) { if (useInMemorySubGraph()) { current_subgraph_state_ = std::make_shared(); - buffer_state = buffer_state.to(torch::kInt64); int buffer_size = buffer_state.size(0); @@ -378,6 +387,7 @@ void GraphModelStorage::initializeInMemorySubGraph(torch::Tensor buffer_state, i torch::Tensor edge_bucket_sizes = torch::from_blob(edge_bucket_sizes_.data(), {(int)edge_bucket_sizes_.size()}, torch::kInt64); torch::Tensor edge_bucket_ends_disk = edge_bucket_sizes.cumsum(0); torch::Tensor edge_bucket_starts_disk = edge_bucket_ends_disk - edge_bucket_sizes; + auto edge_bucket_sizes_accessor = edge_bucket_sizes.accessor(); auto edge_bucket_starts_disk_accessor = edge_bucket_starts_disk.accessor(); @@ -398,10 +408,9 @@ void GraphModelStorage::initializeInMemorySubGraph(torch::Tensor buffer_state, i torch::Tensor in_mem_edge_bucket_starts = in_mem_edge_bucket_sizes.cumsum(0); int64_t total_size = in_mem_edge_bucket_starts[-1].item(); in_mem_edge_bucket_starts = in_mem_edge_bucket_starts - in_mem_edge_bucket_sizes; - auto in_mem_edge_bucket_starts_accessor = in_mem_edge_bucket_starts.accessor(); - current_subgraph_state_->all_in_memory_edges_ = torch::empty({total_size, storage_ptrs_.edges->dim1_size_}, torch::kInt64); + if (hasEdgeWeights()) { current_subgraph_state_->all_in_memory_edges_weights_ = torch::empty({total_size, storage_ptrs_.edges_weights->dim1_size_}, torch::kFloat32); } @@ -455,10 +464,13 @@ void GraphModelStorage::initializeInMemorySubGraph(torch::Tensor buffer_state, i mapped_edges_weights = current_subgraph_state_->all_in_memory_edges_weights_.select(1, 0); } + // Get the edges sorted by src std::tuple sorted_mapped_edges = merge_sorted_edge_buckets(mapped_edges, mapped_edges_weights, in_mem_edge_bucket_starts, buffer_size, true); mapped_edges = std::get<0>(sorted_mapped_edges); mapped_edges_src_weights = std::get<1>(sorted_mapped_edges); + + // Get the edges sorted by dst std::tuple sorted_mapped_edges_dst_sort = merge_sorted_edge_buckets(mapped_edges, mapped_edges_weights, in_mem_edge_bucket_starts, buffer_size, false); mapped_edges_dst_sort = std::get<0>(sorted_mapped_edges_dst_sort); @@ -485,6 +497,7 @@ void GraphModelStorage::initializeInMemorySubGraph(torch::Tensor buffer_state, i getNextSubGraph(); } } + } else { // Either nothing buffered (in memory training) or eval and doing full graph evaluation current_subgraph_state_ = std::make_shared(); diff --git a/src/cpp/src/storage/io.cpp b/src/cpp/src/storage/io.cpp index a65990a1..7dc7f3bf 100644 --- a/src/cpp/src/storage/io.cpp +++ b/src/cpp/src/storage/io.cpp @@ -207,7 +207,6 @@ std::map> initializeEdges(shared_ptrdataset->dataset_dir + PathConstants::edges_directory + PathConstants::test + PathConstants::edge_partition_offsets_file; if (train_edge_storage != nullptr) { - std::cout << "Reading train edges partitions from file " << train_edges_partitions << std::endl; train_edge_storage->readPartitionSizes(train_edges_partitions); } diff --git a/src/cpp/src/storage/storage.cpp b/src/cpp/src/storage/storage.cpp index f95f390a..10a3a988 100644 --- a/src/cpp/src/storage/storage.cpp +++ b/src/cpp/src/storage/storage.cpp @@ -75,6 +75,7 @@ PartitionBufferStorage::PartitionBufferStorage(string filename, int64_t dim0_siz int64_t partition_size = ceil((double)dim0_size_ / options_->num_partitions); device_ = torch::kCPU; + std::cout << "Creating buffer with file " << filename_ << std::endl; buffer_ = new PartitionBuffer(options_->buffer_capacity, options_->num_partitions, options_->fine_to_coarse_ratio, partition_size, dim1_size_, dim0_size_, dtype_, filename_, options_->prefetching); } @@ -91,6 +92,7 @@ PartitionBufferStorage::PartitionBufferStorage(string filename, torch::Tensor da int64_t partition_size = ceil((double)dim0_size_ / options_->num_partitions); device_ = torch::kCPU; + std::cout << "Creating buffer with file " << filename_ << std::endl; buffer_ = new PartitionBuffer(options_->buffer_capacity, options_->num_partitions, options_->fine_to_coarse_ratio, partition_size, dim1_size_, dim0_size_, dtype_, filename_, options_->prefetching); } @@ -105,6 +107,7 @@ PartitionBufferStorage::PartitionBufferStorage(string filename, shared_ptrnum_partitions); device_ = torch::kCPU; + std::cout << "Creating buffer with file " << filename_ << std::endl; buffer_ = new PartitionBuffer(options_->buffer_capacity, options_->num_partitions, options_->fine_to_coarse_ratio, partition_size, dim1_size_, dim0_size_, dtype_, filename_, options_->prefetching); } diff --git a/test/test_data/example_edges_with_weights.csv b/test/test_data/example_edges_with_weights.csv new file mode 100644 index 00000000..c92d4243 --- /dev/null +++ b/test/test_data/example_edges_with_weights.csv @@ -0,0 +1,1200 @@ +80,6,73,-0.1598800758762462 +83,8,2,-0.7861948991897743 +50,8,66,0.2984680877277146 +64,5,42,0.843276671430816 +31,5,91,0.6755376739095242 +40,8,92,0.8655005710540409 +18,2,32,0.005141808312792762 +21,5,64,0.4039071549119815 +47,8,19,-0.45111733173855306 +71,2,71,0.8826584381005864 +12,5,11,-0.2895510191237527 +76,6,58,0.15667980280002758 +12,6,24,0.32892100115496414 +69,9,11,0.2120564547900674 +12,3,55,0.015394800772497108 +77,4,14,-0.21742663350898672 +12,8,8,-0.39008200967966933 +29,5,14,-0.6829363358493405 +46,8,8,-0.11726075753760945 +30,0,60,-0.2550462933069684 +46,6,7,0.2931729454365368 +51,6,69,-0.7353460050136769 +0,2,52,0.31621332033589167 +81,9,26,0.16114445150459256 +50,0,78,0.3501778516948524 +59,9,93,0.17830238841951362 +62,5,12,0.10911131898443505 +93,0,14,0.9192943471929118 +72,7,31,-0.10426509079382718 +46,2,12,0.8322840193487371 +44,3,67,0.19725920603456526 +45,1,46,-0.7530092121641938 +0,2,56,-0.9078672453548329 +68,7,49,-0.6295757320284636 +51,2,21,0.4262008323298021 +66,9,99,0.40083173008128425 +93,2,74,0.2628672751732377 +59,9,9,0.4475820104592285 +12,6,3,-0.20224570299633404 +26,6,11,0.5064352275009263 +8,7,13,0.251738625068598 +46,8,70,0.21235548278956595 +50,8,2,-0.9257646228039029 +10,8,5,-0.6368800765582652 +20,1,3,-0.21359960693966484 +43,3,46,0.9346930149823833 +51,5,70,-0.4776311223975691 +73,4,74,-0.05939650972903032 +95,7,50,0.38701145747608945 +59,8,12,0.9697347621665047 +46,4,99,-0.18125194095438246 +20,3,55,0.5601816300464162 +39,3,24,-0.6680814352899731 +28,8,8,-0.21525309010697713 +31,5,22,0.824669477564784 +84,3,95,0.5566352036074742 +48,3,50,-0.5445511201098807 +81,4,10,-0.5125146424347486 +66,7,4,-0.7406819699396598 +15,2,78,-0.022019767593068895 +68,6,23,0.08508991805432964 +55,0,0,-0.9619450849459921 +58,0,48,0.8709095121429578 +75,4,50,0.06996735991047554 +9,4,20,0.4110613154543201 +48,9,87,0.9113826291017983 +97,3,94,0.8155103846491709 +44,9,83,0.8325189913581863 +87,8,37,-0.6438942700062709 +74,6,33,-0.45699062592218787 +10,9,8,-0.6262477971601201 +81,3,18,-0.3823476991995174 +42,0,7,0.07168133655237985 +74,3,37,-0.10964089639706387 +37,7,33,0.6304212322114389 +35,7,47,-0.2746633304956214 +19,4,8,0.409477590523704 +19,4,78,-0.9190487825978466 +87,4,2,-0.45968623028916555 +39,2,21,0.020080016993011318 +79,8,74,-0.9826622179541111 +21,1,24,-0.7659217612193829 +25,5,33,0.33565860433202044 +24,2,33,0.6798554273657504 +12,6,98,-0.6526491686274505 +47,8,6,0.2977469544952882 +30,2,94,-0.8246477411424611 +61,1,78,0.5221860563154934 +80,0,83,0.32736769735243 +91,1,97,0.8013967421989838 +24,6,5,0.4587193460947039 +32,8,82,0.519795951828812 +40,7,34,-0.6788317061109161 +68,6,98,0.032760644131982986 +76,8,19,-0.42011108895469307 +90,3,40,-0.4838224928105126 +90,1,77,-0.9545902434490754 +11,4,49,0.3664152054517682 +10,3,82,0.1491353806704545 +39,9,2,0.8020300902785371 +15,0,85,-0.5817514965758246 +85,3,81,-0.7114241371249004 +67,2,80,-0.41559203961738134 +0,8,58,-0.7211497930047048 +77,9,48,0.09457720819102988 +93,6,20,0.9836738468682378 +67,4,62,-0.45638056365561375 +51,9,36,-0.9937755641405277 +74,3,76,0.07910090565624417 +7,4,94,-0.048957844171512166 +23,9,46,0.6266738236110072 +2,5,32,-0.4525581726839474 +48,7,49,0.7054040442632736 +35,6,19,0.9444940059921991 +52,2,33,-0.7203251526638565 +31,1,2,-0.2811289655701452 +54,3,26,0.25214036637889237 +63,3,85,0.44644223022007923 +40,1,43,-0.19707145122775538 +57,7,51,-0.2844170269425097 +74,3,59,0.5636577958036453 +11,1,82,0.1561451435921657 +13,9,23,-0.21817416946518464 +70,5,83,-0.5035236653356614 +6,2,25,0.6488940840188466 +86,7,59,-0.7675202266055208 +71,0,62,-0.879274566727068 +77,0,82,-0.8163027097511877 +63,8,88,0.018490528397113737 +4,7,10,-0.4142806306683542 +36,6,73,0.287286037627581 +77,5,58,-0.34945658741432295 +6,2,4,-0.650620682150292 +89,8,84,-0.5963381510510255 +8,8,80,-0.7980241255751892 +27,3,32,-0.4569465641323607 +22,1,96,0.8470034047737354 +58,0,45,0.5684523385849971 +62,8,19,0.15360240092191768 +10,4,67,-0.8925203383590654 +5,7,21,0.5166720841074095 +18,7,3,0.4328417083378009 +59,0,96,-0.8569623541358384 +17,6,49,0.7220029804406667 +82,3,39,-0.6092848312634731 +41,2,24,0.41810614477419694 +43,0,22,0.40959310074062194 +4,5,79,-0.8405808778950268 +76,7,29,0.6152456387404037 +13,7,3,0.6615514201998243 +2,9,52,0.9448875679549609 +65,9,37,0.7960322958322061 +46,1,65,0.10696295140647272 +72,0,67,-0.21315218655552037 +42,8,83,-0.6478822288486925 +92,3,72,0.05605986189172074 +46,4,97,0.6909719212980316 +7,1,35,0.8124542738782106 +10,5,23,-0.9938895895287527 +39,4,28,-0.6205804421599688 +78,3,7,0.9856635409926642 +23,0,94,-0.9365653158564831 +86,1,22,0.14418389384725194 +13,6,47,-0.024119136759316318 +15,4,8,0.7895775354948515 +63,4,73,-0.5489011475760879 +63,7,54,0.5168198257697236 +51,8,22,0.8170571422593138 +74,7,90,-0.2046688008342319 +55,9,68,0.40598195674203286 +55,8,89,-0.7113785833793091 +95,4,86,0.8890743765511278 +70,8,34,0.57565360134886 +11,1,42,-0.5258427667369641 +74,8,32,0.8246789351344737 +90,9,33,0.5873111206807096 +25,8,65,0.007812041865123298 +60,1,59,-0.5694017088632253 +34,9,45,0.6957072358839325 +59,8,53,0.2951319951212654 +1,2,75,-0.15423777641776049 +8,5,63,-0.8677093791716814 +79,9,30,-0.011615795542439189 +21,9,32,0.35995775805398544 +4,5,2,0.7866222726495657 +40,1,94,-0.34073787816873025 +3,2,20,-0.191007481810616 +20,5,11,-0.5942487688074836 +52,9,77,0.9847563926425762 +60,4,38,-0.7298094456971473 +22,8,68,0.23280203254602516 +64,4,26,0.9316476440463122 +44,7,32,0.4850306392622503 +82,7,62,0.9455921350332495 +58,8,55,0.3573562462280966 +7,3,18,0.5858786167473 +15,6,53,0.7431712106428352 +21,6,62,-0.09647065087248441 +99,0,22,-0.37213153205203153 +37,1,51,0.1466903639170225 +1,6,46,0.589703946956778 +68,5,78,0.7286031263520298 +34,0,92,0.1756915176325895 +9,4,41,-0.5483451520501272 +8,5,46,0.8233796226378436 +43,1,87,-0.8236733799623464 +96,5,78,-0.13481996247074202 +84,7,43,-0.6233187018165458 +72,3,60,-0.36017812277203043 +59,7,57,-0.4609044238018447 +28,0,83,0.5724092235831089 +93,5,34,-0.8607748185925734 +78,2,36,-0.7684034520085674 +15,2,89,0.7473341128367699 +68,3,71,0.5472309412482725 +51,1,26,-0.7680149195245962 +67,2,67,0.7053768118079458 +68,2,79,0.424528317157548 +85,3,66,0.4701414300684663 +68,3,74,-0.46211965310469516 +21,3,28,0.8834858893015267 +25,8,87,-0.05185113384615292 +82,3,67,-0.8368605377554637 +36,5,2,-0.506905174983936 +38,9,12,0.22537251434767525 +30,1,25,-0.4436936353238836 +89,7,45,0.4331971352674435 +31,1,7,-0.5082015386794985 +22,8,72,0.35330262076215546 +30,4,56,-0.5376649777269842 +14,7,60,-0.18376090355004493 +26,4,74,0.18967019107218852 +74,0,1,0.9336543641646506 +42,3,70,-0.24395683112955013 +91,0,85,0.5020669465028338 +74,5,87,-0.3154480260287096 +83,0,0,-0.359214896806584 +14,0,33,-0.37119677205825075 +48,4,18,0.8142540093668167 +47,7,3,-0.09858720293687817 +34,8,74,-0.09332357468283914 +91,7,3,0.5918810433216053 +13,6,56,0.7364849354582776 +5,6,19,0.622698442113707 +43,5,80,0.6587848641024412 +45,5,68,0.35058805157416684 +41,2,29,0.5792264360767809 +88,3,83,-0.5298311304597392 +39,4,42,-0.4563877931961031 +31,1,4,-0.10370910627533858 +51,6,13,-0.29055837055255473 +49,0,59,0.1007273944021223 +0,0,37,0.7608857030094298 +28,6,41,-0.24189020050876553 +58,0,94,-0.8708381777150083 +86,1,86,-0.697781890434259 +96,0,22,-0.2707765445228594 +11,7,91,0.06870200397752901 +61,2,5,-0.10189899789234547 +93,6,55,0.15347798942540147 +17,5,63,-0.3133447889147265 +47,2,17,0.7870358646376845 +93,6,42,-0.18622028580401673 +96,5,4,0.7119644922756281 +73,1,35,0.31862439627137484 +41,6,46,-0.40101350596226637 +8,3,69,-0.6472230002025832 +5,7,9,-0.44891902809383644 +38,3,27,0.10060372287921715 +7,9,61,-0.298430305746747 +10,9,75,-0.6350304699331928 +55,9,37,-0.3992385554466884 +53,1,18,0.30340093007792635 +9,8,19,0.5668766834758379 +58,1,56,-0.6117575267863788 +10,7,90,-0.32954005218731 +15,2,13,0.4440986291282414 +47,3,45,0.528836821348571 +74,6,60,-0.261867439956714 +38,5,40,-0.8846208315169484 +32,4,30,-0.3018359053458093 +9,2,74,0.010061094047687291 +85,5,37,-0.6481370342163442 +74,9,13,-0.9640749486704594 +4,5,37,0.920885966510899 +17,5,20,-0.8943039423076176 +88,8,11,0.673496535392212 +5,5,70,-0.10245889481604298 +71,2,74,-0.9540802439807154 +88,7,4,0.10183235156991643 +71,4,89,0.385909959413983 +50,7,50,0.5123592576894755 +3,2,77,-0.1368925341799958 +8,6,83,-0.07430511682193353 +30,9,74,0.9612884526935048 +87,7,3,-0.7909145546092311 +58,3,32,-0.7229077141830111 +48,4,1,-0.5090140661737037 +93,5,99,-0.3317232958674037 +15,4,48,0.5870323777643505 +59,6,18,0.8268257372837216 +13,5,14,0.6838181587954706 +42,0,4,-0.9010234206855487 +97,0,55,0.5869892898999203 +41,7,7,0.18385184166871582 +45,1,70,0.051802410040148406 +47,1,49,0.37569683924337993 +72,9,73,0.20302658663227402 +73,6,18,-0.8157212264404627 +12,4,57,-0.6799972228368563 +65,6,2,0.7614581507091291 +7,9,52,-0.7673793051438618 +76,3,78,0.532886805837752 +60,4,70,0.8419623386870163 +69,2,17,0.8410806864915854 +65,9,25,0.5145323686070962 +44,7,7,-0.09283528418755571 +59,9,15,-0.178649583300595 +39,4,7,0.7827822373398035 +91,9,26,-0.7354589394131379 +82,9,51,0.13179663904090644 +70,2,28,0.5636292300484063 +29,3,38,-0.00019648212695067002 +52,9,35,-0.01776287450075542 +22,5,83,-0.5714884816214414 +5,7,5,-0.5048315442707338 +61,7,98,0.4825138222322838 +12,9,65,-0.5820376520193529 +44,7,89,-0.29737233474188374 +62,9,6,-0.3794256246757479 +87,4,26,-0.2886381383107348 +66,4,10,-0.8335574106193657 +84,9,49,-0.9609548101378942 +68,9,39,0.37322453074616946 +56,0,52,0.18738537201666428 +26,6,22,0.4033725164202082 +42,6,64,-0.7988642116200408 +61,9,90,0.2855977418492346 +78,5,39,-0.6595856439024328 +71,7,19,0.17227787316553056 +1,0,89,-0.9457421890832898 +87,4,23,-0.9400836572747759 +23,0,52,-0.9537672912713122 +94,4,57,0.8276123467225107 +7,0,85,0.7694543805366685 +98,4,89,0.06367557384671185 +87,7,39,0.0770841193512124 +94,8,4,0.21165466755482587 +45,1,93,0.1709924070886497 +99,8,45,-0.9398587752365872 +21,1,79,-0.804225838510287 +65,9,97,-0.8513777408231555 +85,5,14,-0.3090193098673164 +45,0,65,-0.4071870508508042 +41,5,12,-0.6509153939634835 +58,3,27,-0.10116568863526587 +88,4,86,0.05030842227788512 +13,1,8,-0.7493906039306328 +71,4,39,0.4718204359288978 +66,2,22,0.7287469278452392 +89,6,53,-0.36481992304649546 +13,7,66,0.9831501768452808 +61,5,91,0.07517894886383836 +99,0,73,-0.007527603899489588 +76,3,3,-0.6137529085099978 +7,3,51,-0.8465348386155138 +61,6,93,-0.7130072122010376 +63,0,13,0.765390426069031 +33,7,96,0.7415527359546297 +6,2,69,0.41047597279359826 +68,2,65,-0.32005883601998564 +76,4,9,0.1104879038781248 +66,0,37,0.1797610893032735 +4,4,63,0.13663706615145088 +76,2,26,0.11610234056270619 +28,5,63,0.5757392708193527 +92,9,82,0.0002026699989212677 +1,1,49,-0.4669207659763057 +43,5,20,-0.6183832710406039 +34,0,18,0.0015998285720126848 +38,7,2,-0.6776324655401911 +74,3,72,0.6847608035819523 +71,5,76,-0.5277810084821102 +53,8,58,0.266536352380367 +61,7,45,0.7835470200718566 +57,9,55,-0.14670861326069695 +79,7,87,-0.5322959962281526 +55,5,95,0.12114531352525448 +10,1,54,0.7018697646537644 +83,1,32,-0.3448551554167347 +74,6,61,0.9758965758513953 +50,1,1,0.0904927967172986 +89,5,87,-0.5685965977409067 +54,7,40,-0.2316945439135345 +83,7,48,-0.0825287000393864 +20,1,76,-0.8178990384787443 +57,2,80,-0.058846669677262486 +18,7,54,-0.3875158605847806 +56,2,13,-0.9613716793123288 +9,4,15,-0.9740293851737352 +76,7,48,0.6410208095198127 +20,8,29,0.14296691545863593 +34,3,95,-0.2091057681628643 +80,0,85,-0.10767530591566565 +79,4,17,-0.5646970186274947 +94,2,23,-0.3450482102758392 +46,2,94,0.9437705965617924 +13,8,70,0.2571059845791295 +31,2,28,-0.24501938513529264 +63,8,49,-0.47235416871434843 +83,2,97,0.42104343562678714 +51,6,28,-0.5691197324965447 +64,0,5,-0.0037954350172637596 +19,9,52,0.07561343940259002 +69,0,27,-0.7008429628104675 +80,7,4,0.2506442217687055 +39,9,81,-0.42765799829414597 +98,9,82,-0.6901381199644334 +28,9,81,-0.5195431824742132 +73,9,58,0.9209307957412391 +68,7,40,-0.26643355406570324 +72,4,48,0.9961471482487367 +9,2,65,-0.19375264085355792 +34,3,35,0.5669119349965484 +62,0,3,-0.5029085011471339 +73,8,54,0.33084051567295436 +13,2,38,0.10850897296029172 +50,0,29,0.7923749798607054 +81,2,96,-0.46650629864705007 +48,3,4,0.8725048389888841 +58,5,97,-0.6310769216603713 +22,1,91,0.9622540936884416 +41,7,14,-0.2164871377915476 +47,1,0,-0.13065917941699423 +44,8,58,-0.6938567946686691 +77,6,92,-0.542952624709844 +65,6,73,-0.8667816498570735 +8,8,61,-0.4009806407566239 +74,0,2,-0.9491663348050194 +21,0,83,0.1502601552503322 +80,9,92,-0.026433035376467462 +53,0,34,-0.5964954848726058 +85,8,55,0.030463439927452818 +53,3,83,0.9883420499024063 +32,6,33,0.02462034645645983 +52,3,14,-0.5485074399736132 +34,1,14,-0.18165823456687424 +45,0,55,-0.948631139948092 +93,5,79,0.10178672981638126 +33,9,65,-0.5069504831556693 +79,7,27,-0.5711489072471048 +5,9,4,-0.10472663550058403 +99,7,26,0.6638614991876481 +26,2,78,-0.2603215894729798 +36,4,9,0.7724267369360387 +56,6,92,-0.6145179255305009 +82,7,21,0.9685201537475214 +82,9,46,-0.6697249713255191 +99,2,90,0.3656320379557525 +57,6,25,-0.9270396997145349 +97,4,4,0.7157298456898709 +66,7,53,0.6649168379714556 +79,3,23,-0.19178192323463628 +56,5,16,0.8450497152448646 +23,8,88,0.008539163981933218 +61,9,36,0.29156368847450387 +27,1,51,0.024547809747987648 +7,1,93,0.028030513283247904 +27,7,38,-0.6456295315456784 +15,1,60,-0.5246611960920007 +83,1,5,-0.6196382356240138 +58,2,6,-0.7069182646915482 +14,4,95,-0.8544053216460088 +33,3,90,0.36971014106210465 +45,8,88,-0.07786675544791866 +96,5,24,-0.7964977519178476 +42,5,94,0.1646502204791509 +46,6,80,-0.8035195416491596 +31,2,65,0.7110781706817717 +59,6,4,-0.548948112687045 +16,4,13,0.013310933554629534 +10,2,41,-0.07357941918240707 +81,3,73,0.34258581873628735 +83,0,68,0.6298073638069843 +11,0,26,-0.7055881083677189 +52,2,11,0.9159609401292492 +75,3,81,0.3103950471488861 +89,5,29,0.192177254102323 +75,9,66,0.5921532018936402 +87,4,15,0.7534371183536548 +73,3,10,0.7265662873578154 +4,9,67,0.867320059579211 +76,2,35,0.14705650926840685 +15,0,43,0.4945844746744148 +37,5,93,-0.6564155121213882 +37,2,55,-0.3187708499300972 +61,4,12,-0.3822367862332092 +2,2,81,-0.3251977794304417 +4,0,69,0.31197202296257975 +1,8,95,0.239228863787176 +7,4,72,-0.5213978714660574 +9,1,16,-0.018589393986849778 +25,8,88,0.44690193827531344 +8,2,74,-0.8741557934007325 +65,3,30,0.7825383325217874 +83,3,67,-0.6877520906357795 +42,4,1,0.19390366886346677 +36,3,30,-0.501684477558084 +19,1,23,0.48895847549377347 +76,5,90,0.8886604356919936 +83,8,13,-0.4159639327330964 +31,6,79,0.2692030165621706 +87,6,36,0.3097900854643254 +7,1,74,0.7553704328382955 +0,6,69,0.38716851313501177 +30,1,52,-0.7890824249176378 +57,0,89,-0.16572263495827477 +0,2,62,-0.08412495996150393 +55,8,25,-0.7894661917697039 +28,8,13,0.4927705173602759 +50,9,20,0.5554792512660631 +44,1,33,-0.8981359000116842 +48,2,77,-0.47144471570261937 +93,5,56,-0.1312341302302915 +29,6,97,-0.992438003677496 +93,3,21,0.19366662482087604 +4,2,94,0.9966072499893364 +26,7,43,-0.6914522180985676 +20,0,28,0.29405992852380036 +76,6,63,0.8287172357058563 +15,5,66,0.8769436447064844 +59,1,60,0.7451501134227105 +29,4,7,-0.8001929158669989 +41,7,27,-0.5500859706316741 +40,4,97,-0.5387068769181567 +10,2,43,-0.6885829436715662 +44,6,76,-0.07450902217814215 +73,9,38,-0.8481609579259204 +88,4,89,0.1665931317234164 +44,9,21,-0.04209168474059366 +73,9,17,0.5413786898075474 +8,5,21,-0.36900504127067446 +9,0,85,0.7985005208111644 +84,0,48,-0.5100376279657495 +36,3,89,0.86440376407299 +58,2,25,-0.7560075787973639 +27,5,5,-0.1638702059725996 +13,1,90,-0.3475728527784203 +50,3,51,-0.9378454346737066 +3,8,41,-0.27597838225899407 +79,3,69,-0.8122325507535635 +73,5,75,0.2293205876454265 +71,6,32,-0.3073226155175335 +95,4,65,-0.28067236166574894 +65,0,98,-0.14717572511646626 +12,1,46,-0.6647586686784381 +93,8,60,0.40354420768931787 +81,7,95,0.7671858526577382 +48,5,30,-0.7138681237833857 +8,8,14,0.07929426566190045 +83,1,47,0.22613842009368001 +38,8,37,0.7809253938372174 +58,7,12,0.2055925786255497 +52,1,89,-0.6000218446666297 +86,0,0,0.49003342177165843 +36,1,69,-0.47965044842001126 +20,0,56,-0.8227531588182526 +71,3,2,-0.15703637979282914 +94,6,92,-0.7252325991880864 +20,7,14,0.681801245157132 +53,2,1,0.7559536943753977 +50,2,77,-0.6448700476416982 +91,6,57,-0.5807068123274397 +28,1,15,-0.3123225769835807 +26,9,97,-0.4818169888445345 +52,5,73,-0.4540568513685488 +19,7,32,-0.1359950222399846 +5,7,63,-0.7552104828294179 +27,7,73,0.9725895882005207 +5,7,13,0.7347020745148933 +48,9,89,0.5688522134713163 +13,5,84,-0.4868502010408826 +48,8,11,-0.011398571773783672 +12,5,66,0.8242911837793185 +13,8,39,0.3777625916713485 +10,5,35,-0.5848170461607758 +30,0,79,0.3446564858997081 +41,8,79,-0.4920670624706087 +72,9,70,-0.5393143233381976 +82,2,93,-0.08543970085218211 +49,9,5,0.7906001378674654 +85,7,48,0.9843874373925967 +95,4,22,-0.07829174307125242 +58,6,7,-0.14816792881118168 +45,5,87,0.1731586643333205 +81,8,46,0.45194726873093916 +69,7,99,-0.7051432358770475 +34,0,29,0.48413309880458155 +57,3,57,0.6222556424784926 +65,0,84,-0.37003992409925246 +29,3,78,-0.05735882554655847 +12,4,10,0.5614999167727364 +93,7,5,-0.39327654197658024 +74,9,99,-0.024797709579015947 +53,0,77,-0.6842249825340194 +26,3,87,-0.8773603887802197 +62,0,99,0.5351568706945546 +12,3,73,0.775794065787395 +58,3,92,0.16527265756995524 +42,7,46,0.7267170641464598 +98,7,15,0.5257040946584861 +33,5,82,0.18075877471166701 +51,3,66,0.5259471923345362 +39,0,18,0.8053228220631654 +23,0,14,-0.3248756184774886 +64,8,22,0.018211458245544376 +31,9,42,-0.2815031525980738 +96,0,91,-0.11582840113665105 +73,0,21,-0.8793904166446003 +69,5,15,0.4212154001671635 +46,7,47,-0.7253823341626537 +82,6,87,-0.257673829381015 +96,3,79,0.7933773323024802 +1,8,69,-0.14245686909288935 +31,7,5,-0.9087965087689176 +16,3,90,-0.5867204370477768 +45,7,94,0.2844915378725834 +58,2,82,0.02968380336471732 +51,0,44,-0.8519235098448013 +43,7,34,0.016235006409151875 +2,3,26,-0.09729857049392865 +99,1,48,0.00672299367632867 +17,8,45,-0.20093964026440392 +37,1,38,-0.873071170173048 +12,5,81,0.45661219181432666 +79,9,35,0.8714541342487407 +69,3,76,0.2725357945080651 +13,8,21,0.30886291293942714 +8,5,67,0.10971581738419145 +41,5,30,-0.8625761049147673 +74,2,53,-0.6788440372142337 +56,9,70,-0.7385361611328869 +86,6,8,0.1904981106275594 +47,8,44,0.7215580378673647 +46,9,82,0.4965556122668642 +0,4,14,-0.8285921556364133 +80,1,47,-0.6052479776853135 +20,8,18,-0.7865833380548501 +83,2,22,-0.04471152958569791 +75,9,82,-0.36353292465966747 +71,8,55,-0.5737022552989597 +0,5,46,-0.6138643086266995 +93,7,11,-0.3186779167844307 +65,3,22,-0.196547439009237 +26,8,88,-0.9958597799363096 +4,8,18,-0.36091428777405254 +23,5,6,0.4339338220463893 +32,6,22,0.5483628261510636 +26,3,94,0.9251845178046505 +40,2,16,0.2483269288292438 +4,0,77,0.31828979024796933 +82,2,71,0.8653458379162347 +2,8,74,-0.5693911045404891 +90,0,9,-0.019387377530574845 +92,4,98,0.13076362455301993 +48,8,44,0.12541024758689345 +47,2,53,-0.31727635008846833 +58,9,2,0.9437870765068339 +97,9,12,0.31950918371937176 +5,5,67,0.06344154438000316 +24,9,56,0.20791919099736278 +99,2,85,-0.2929656543604262 +19,1,14,-0.9849542789666756 +88,2,47,0.6065257964097495 +95,2,49,0.8045341738582059 +14,6,57,0.3445208736131473 +56,7,94,0.6007958864933542 +84,5,31,0.7574468027749761 +5,6,96,-0.7909273130355414 +94,0,0,-0.04142648382058689 +33,0,38,-0.6458609218421458 +24,0,83,0.44007514205570364 +77,5,62,0.8160175049004867 +73,2,28,-0.5874833863247657 +53,4,21,-0.3155786019977669 +4,0,46,-0.503316660884302 +30,5,34,0.17320518281063157 +9,6,4,0.7054792234377065 +11,3,31,-0.5806120565459394 +1,1,3,0.18462353083451122 +86,5,42,-0.5829813108123889 +31,1,13,-0.07513199389011804 +73,4,13,-0.024343096415868404 +36,9,13,0.02588355664177744 +27,4,2,-0.9837981199022725 +5,2,48,-0.9027563258663653 +60,9,19,0.1669186820655275 +96,2,52,0.8366920368719191 +69,9,96,0.04142591545038132 +17,2,2,0.9681121327335089 +73,8,67,0.25799085714637426 +71,9,58,-0.9043461038828415 +31,1,54,-0.28691998276741004 +38,5,82,0.0221133203317867 +3,0,67,-0.2199547506056201 +69,3,25,0.3182195555647471 +50,6,98,0.32708775231627185 +93,9,4,-0.05401079348188875 +48,7,47,-0.5815479898047811 +19,3,13,-0.5560651976841389 +40,5,77,-0.7305516913076957 +21,2,42,0.47899579362380207 +42,1,23,-0.5680996953569104 +14,3,29,-0.2410359171618235 +42,4,38,0.03432126937670876 +76,0,34,-0.5885585160275135 +85,6,0,-0.9778544228921655 +91,1,79,0.5233528369968701 +75,8,58,-0.7337435037544271 +60,1,44,-0.8015833453654391 +29,2,4,0.02755516039127981 +88,0,37,0.5807756018872445 +53,8,28,-0.4220999485982353 +88,8,10,0.11332654980364776 +54,6,24,0.9024218929258394 +25,6,56,-0.7427076174862333 +26,8,79,0.22953350474328982 +76,2,87,-0.23341347670811707 +36,9,84,0.6202007694312595 +38,3,68,-0.1300904269986074 +84,7,50,-0.6976827147561753 +60,6,84,0.47633536090119777 +60,3,24,0.7656449643581531 +86,3,49,0.6250896534245594 +52,7,56,-0.8576371153598212 +59,1,77,-0.46941671883250136 +26,4,19,0.12367194184840313 +92,8,94,0.2619132378018678 +18,3,6,-0.45723264528144325 +40,2,56,0.3633852712130565 +38,2,49,0.025038121908132815 +60,6,11,-0.04371417390968002 +35,9,30,-0.3089571159661626 +4,9,17,-0.5996808527177371 +24,5,51,-0.39508687989248736 +33,5,2,0.9622650919078444 +3,7,82,0.9749205194484281 +99,8,57,-0.09192997590552432 +61,9,28,0.4166606597884972 +11,7,28,-0.47250144816636563 +31,6,73,0.9085182588695127 +67,4,68,-0.5922047392805558 +43,5,56,-0.8264440811393332 +49,6,57,0.9373534265577768 +78,2,87,0.8825407812057342 +94,6,93,0.6520944745822257 +85,2,47,0.16014643604660495 +65,1,99,0.9322033510266896 +98,1,63,0.2121947975984193 +47,3,2,-0.6512546966903059 +50,8,4,-0.8317488793411318 +42,5,30,-0.309533142422042 +77,0,85,0.591821536425764 +67,9,65,-0.34868137198790405 +26,3,65,0.03372515355142425 +59,1,24,-0.5476525114052613 +36,0,76,-0.20002403446528727 +68,3,95,0.8401036575316543 +34,6,96,0.03602375223684251 +61,5,7,-0.4937338128848554 +44,0,59,-0.5043677780049782 +30,7,15,0.700221994039222 +81,2,14,0.9743015639834116 +78,4,30,-0.4654767375390836 +20,3,65,0.8643908227272037 +85,6,42,0.15595961237371858 +41,7,43,-0.4878184484783221 +51,2,6,-0.9712363089520886 +26,7,25,-0.11198618428127105 +92,5,49,-0.9805677398303274 +90,0,61,-0.18060285326185643 +11,8,15,0.07369039508350395 +77,2,31,-0.7010029743817492 +30,9,48,-0.2110400906862253 +88,9,93,-0.7160508772973584 +90,5,70,-0.5657785592021811 +57,5,17,0.06342308325988566 +18,9,23,0.5173456095019053 +56,2,82,0.2833632161189672 +25,7,34,0.13587326612955453 +26,1,9,-0.5431327692228078 +91,9,30,-0.8970012827330485 +49,8,99,-0.42889218845900157 +96,8,88,-0.060936180061244016 +93,2,65,-0.1273048813615829 +36,8,67,-0.9617362658568824 +40,5,76,0.381676648499115 +8,2,31,0.664872016961052 +92,4,66,-0.5373243447144307 +92,4,28,-0.718296556017745 +13,2,73,0.5336100209798815 +4,1,30,-0.10949186973067815 +83,4,6,-0.9750209787640229 +96,0,3,-0.03481257940896776 +12,9,45,0.8569738919528889 +85,5,29,0.07051289958974061 +34,0,39,0.4518726824642021 +51,7,97,0.6628001613484145 +3,9,85,-0.757100575150947 +19,5,73,-0.5355692663064995 +92,2,38,0.7570855804467163 +51,5,83,0.26581785792787094 +71,9,79,-0.24551279646675006 +83,4,60,0.38495491293800654 +62,8,77,-0.7354754991024217 +0,9,32,-0.34866512409399575 +70,7,95,0.6020641685012478 +72,6,0,-0.1721041143039297 +69,4,95,-0.7538066135341497 +3,1,43,0.7334202768412164 +62,9,20,-0.4566824166552206 +76,9,85,-0.05419690663475585 +84,4,79,-0.7910717758650789 +21,1,3,-0.9622315020829335 +20,5,83,0.2764575343972824 +91,2,22,-0.3478869794761985 +83,3,21,-0.8095357656272777 +75,6,25,-0.1080977386761528 +56,1,74,0.6096882459894475 +31,2,30,-0.6912992584515594 +66,8,3,-0.3388913867242469 +19,9,37,-0.5545919144973104 +19,5,11,0.4618845796133102 +81,5,93,-0.3080034453251701 +68,4,38,0.6406759208649713 +37,2,39,0.17105247283021763 +56,8,97,0.24433610285446816 +82,5,58,0.2738305903705649 +81,2,65,-0.7497538336030165 +98,5,40,-0.4738475917337661 +78,6,53,0.4194003445686416 +18,5,45,0.6879859307674836 +42,9,29,-0.17955986985948647 +75,9,93,-0.3575999196379094 +99,8,14,0.5027729860457828 +97,7,35,-0.503185649193725 +33,4,41,0.5379889850767654 +36,8,85,0.3259687044010191 +42,3,54,-0.8418190312400591 +58,7,50,-0.9020606107206979 +3,7,53,0.577987784012221 +64,3,80,-0.2804406582376149 +0,7,23,0.07534234744615187 +98,5,30,0.05761130360152489 +71,8,86,-0.9859435467061832 +37,8,11,-0.391621422561488 +90,2,12,0.9674195339838996 +5,9,41,-0.8240785014594594 +54,9,58,0.5331372217984753 +14,4,96,-0.3802300068796496 +16,5,97,0.474088829372465 +1,9,15,0.9952477423675579 +41,4,9,0.704989533205088 +32,5,17,-0.12020395632383707 +96,7,71,0.9093851084876037 +83,4,61,-0.22396563316059614 +21,3,81,0.4371200066023937 +28,9,31,0.2511019581315057 +96,8,39,-0.5452742333218767 +90,5,46,0.4610900206344395 +65,6,63,0.7289984347925584 +50,4,7,0.3795967888139895 +43,7,21,-0.3639496141725733 +23,9,76,0.5295538522685552 +54,0,47,0.1476958092635885 +39,8,11,-0.808882404472534 +71,4,90,-0.2476427443438869 +47,8,99,-0.032128945494069194 +46,5,71,0.7957932002393298 +90,4,57,-0.3075703146212925 +81,4,89,-0.7278962412070007 +43,1,90,-0.5898795844576856 +32,1,72,0.9634917708414745 +0,4,70,0.0652074749457463 +47,5,34,-0.0576288638490039 +43,1,28,-0.8467568688893239 +13,1,69,0.2083366943897751 +49,4,9,0.2593474422882027 +36,7,38,-0.9602007298833706 +94,0,24,-0.987836088409823 +64,4,11,0.38860204682236055 +53,7,12,0.2093641679434075 +17,5,12,-0.33492068022395793 +96,2,69,-0.17543190387691943 +99,7,75,-0.15617792857819235 +70,4,85,0.5518887478835943 +93,6,64,0.3761691566821983 +61,7,2,0.8509976057759998 +47,2,50,-0.5707130065333095 +50,1,58,0.46524457000930153 +3,4,18,0.010538507005882325 +41,2,31,-0.12689797203696562 +45,2,49,-0.07805343748896187 +98,2,83,-0.5175467980889465 +88,2,40,-0.617445697511043 +34,2,59,-0.3773716984358706 +86,2,99,-0.31990783809334733 +49,4,28,-0.7615038716777367 +20,0,24,-0.390797884131707 +98,0,0,-0.2007677025222916 +51,4,78,-0.6743789388431076 +66,8,50,-0.02336313890366104 +37,2,77,-0.5391883701581177 +62,5,53,0.4398809096173324 +97,1,20,-0.7565325994093066 +84,2,15,0.7711006558375268 +48,3,95,-0.9552062038290292 +18,4,17,0.1725647674585018 +20,5,9,0.02873082427349205 +56,0,24,-0.16528637951550929 +90,8,64,0.0663684113941494 +13,7,5,0.9690732525339412 +80,5,19,0.6380833920106159 +49,1,33,0.04694560788948232 +20,2,12,0.8977322668977219 +92,8,4,0.20396876767179672 +25,7,28,-0.15878665751106524 +47,7,24,-0.3018597436182151 +84,4,61,0.293040841571522 +2,7,84,-0.7773941720551703 +0,0,25,0.08348486211595496 +13,9,62,0.06589451279100955 +17,4,4,-0.5870751276972674 +1,0,96,-0.5612264482478788 +59,6,6,-0.20383859847375163 +50,5,76,0.41833585218124614 +69,1,60,0.3217588999478256 +64,0,82,0.3316128403208145 +37,0,96,-0.8195028207998669 +57,0,77,0.7733797368461277 +60,5,89,-0.34873398644154774 +83,3,1,0.9601740999808783 +23,5,86,-0.8526284698992754 +54,5,87,-0.3450291231173044 +83,8,76,0.2978278588924177 +12,4,15,-0.9316844629220393 +13,6,86,-0.8329977753427418 +89,7,97,-0.02216821045289752 +12,8,2,-0.28502624634584284 +26,0,13,0.7839598723695935 +64,4,48,0.423196475972196 +3,1,12,-0.07289004922506348 +86,1,68,0.23222218739860945 +78,8,4,0.11819878492393188 +96,3,14,-0.5716953093001578 +64,7,71,-0.3520110697138308 +51,7,72,-0.3702056400381202 +66,5,73,-0.004491593450492326 +86,4,17,0.4572825600171442 +1,1,82,-0.3987973213362812 +91,9,71,-0.20824204254047363 +50,5,88,-0.7923166295794302 +60,6,81,0.451989590244684 +57,5,45,0.031357170990674366 +30,7,6,0.4606276953448125 +50,1,11,0.02320090564624211 +84,7,30,-0.8296776077635468 +66,6,86,-0.6043214617185635 +39,4,47,0.2724409416528937 +29,8,1,0.1216617853245292 +82,7,30,0.8410775793465428 +82,2,54,0.453344216950625 +35,3,74,0.9136266112592997 +38,9,9,0.6432772794405304 +64,8,88,0.4914968202501022 +74,6,51,-0.6019959996682491 +58,4,30,0.4171897660450721 +8,4,6,0.42648035200088863 +72,3,63,-0.18211611017672413 +81,4,44,0.1412528962391586 +90,4,1,-0.9124326778522314 +91,3,62,-0.9575875218059129 +19,4,53,0.18135014893044232 +2,9,78,-0.11351214583364988 +70,0,84,0.05669675622814263 +89,1,74,-0.81053058554258 +66,3,0,0.6830704476679568 +95,5,73,-0.8558307072706217 +44,9,94,-0.2084106541723738 +18,3,87,-0.015688850366448737 +6,5,90,-0.16146263890866552 +42,9,45,0.05919966234441043 +17,1,41,-0.3857803045843642 +81,6,70,-0.5649759730242834 +72,0,42,0.6493312387065426 +45,8,43,-0.8974144836371409 +16,5,31,-0.7028493438345214 +61,5,69,-0.5835455580792936 +87,3,6,-0.017255953270925772 +80,7,33,-0.3524561854556687 +43,8,81,0.5023141898689312 +55,7,34,-0.724363151862252 +93,2,75,0.6337861197451506 +24,1,13,-0.4069137794380089 +92,5,16,0.30297626629631447 +6,7,17,-0.13076613884453026 +93,9,91,0.44581048006521606 +94,2,21,-0.255107965298899 +29,5,79,0.4771594608320102 +32,5,35,0.0733520560265537 +47,8,62,0.09683061307549479 +1,2,23,0.27225957013435265 +23,5,18,-0.8676551677897648 +81,1,78,-0.29968703516884965 +12,6,7,0.6539838892656642 +90,6,16,-0.3460294276136904 +54,5,66,-0.3765842035349638 +96,2,43,-0.9864719053608981 +88,1,94,0.039731370233010876 +18,7,78,0.5960882945813746 +68,8,4,0.7853073608719559 +49,1,3,-0.6417079948916717 +1,8,61,0.07668289565304076 +5,6,16,0.7772349814040684 +79,6,82,-0.6323524757466688 +29,0,42,0.8993699590408564 +36,0,55,-0.028024296153068562 +14,8,19,-0.2665255855745374 +41,1,69,-0.420619130145788 +71,0,23,0.9802003591424171 +14,8,90,-0.6379803456983983 +78,4,14,-0.04681560249385819 +32,1,4,-0.8373248681158318 +46,5,30,-0.6502636910528266 +61,0,99,0.7992829958339733 +79,0,11,0.005814255128033796 +30,2,87,-0.48896547391467515 +17,7,61,-0.6953435607049265 +93,1,72,0.39316813229581826 +89,1,59,-0.19049286424189904 +80,4,25,0.22856459355298253 +3,0,32,-0.809653785927033 +80,9,77,-0.9347230409844729 +86,3,69,-0.3453844374185979 +1,7,18,0.5736122694844936 +95,7,67,0.6034455858791885 +80,4,74,-0.4116374512861436 +81,8,17,0.11333222390076525 +3,3,35,0.6382461992372375 +99,6,74,-0.3599523082985778 +36,9,16,0.963619116003529 +70,8,19,0.05221574024873887 +92,8,99,-0.4093740690650727 +47,4,4,-0.8593567786674658 +32,8,51,0.2857181391555552 +4,5,91,-0.3871557262275256 +1,5,88,-0.5961399996596912 +54,8,35,0.989941405813924 +34,0,78,-0.6389354882345544 +78,8,43,-0.5709692365104313 +65,6,44,0.06816889969217721 +67,0,42,-0.6002533172366717 +89,4,69,-0.5634228212393548 +42,6,31,0.09237907622914654 +70,2,61,-0.19753902527798295 +23,8,59,-0.3955289227467309 +90,2,43,0.5078502012741317 +92,7,23,-0.3994535167774833 +87,3,90,0.0021997487294667106 +50,0,89,0.7107564598719973 +80,0,64,0.09863469425181215 +6,9,53,-0.20553131235990652 +97,7,45,-0.9580602351800196 +41,0,40,-0.9988928951927187 +28,2,14,0.7595981031433301 +24,4,39,-0.9001663272948417 +9,1,71,0.9525862707784398 +28,7,11,-0.7285748191521659 +43,2,53,0.0434761111490527 +61,4,48,0.44299464662957777 +0,7,22,0.40637290467062015 +93,1,94,-0.3490362468902459 +41,7,8,-0.042993105247545405 +70,8,67,-0.6910697087202142 +96,6,21,0.818094112182078 +88,3,16,-0.07293464891278534 +36,6,68,-0.23079921303294015 +27,8,3,-0.42962726095313486 +97,4,33,0.6552874591516247 +51,3,29,0.6680332697880889 +78,1,92,-0.9234064830791213 +18,1,85,-0.1029186753553406 +88,1,84,-0.9665615440081938 +72,1,15,-0.7294581406210738 +32,2,96,0.24838140423269217 +36,0,64,-0.7942263955819058 +34,2,50,-0.7027824375024583 +71,3,61,-0.4500890386660219 +11,5,96,-0.43749660703127935 +42,1,95,0.3009383241858148 +85,3,62,0.7280423428288896 +2,6,94,0.47553393929606536 +10,0,17,0.8702057572708282 +18,8,57,0.8210927167343238 +66,4,38,0.10532177621229111 +41,9,82,0.9320948093077634 +42,8,63,-0.7422801886450985 +59,2,36,-0.4054385196428705 +62,8,39,-0.13478029784855905 +2,1,50,0.7724212210595023 +31,7,12,0.45951635497380194 +61,4,64,0.7358418011947423 +23,9,65,0.48040555482425473 +32,8,69,-0.00844911497099754 +7,0,62,-0.4852074041085592 +81,2,68,0.6552723733769301 +22,7,35,-0.4532355131050376 +17,5,94,-0.20755322399972842 +23,8,37,-0.49531626852762867 +99,8,77,-0.22935537473618584 +40,0,87,0.880523447273182 +95,9,69,-0.7571055460165872 +91,8,29,0.2540159103027635 +35,5,27,0.12958523023830293 +74,3,31,0.686838986371179 +59,8,29,0.3729499772821985 +92,3,22,-0.6153121776209587 +26,4,49,0.44110195319243317 +6,8,36,-0.45793306977215864 +89,5,42,0.4419512166415802 +42,3,67,0.9939962430776323 +95,1,61,0.526592888947139 +11,7,58,-0.10960764534771439 +67,2,9,0.7299969108002988 +28,6,73,-0.560039598199289 +6,7,43,-0.6231064202805767 +2,3,86,0.7073861131829606 +39,3,77,0.10152888289421935 +7,3,30,0.24254864863800107 +30,5,73,0.48059489544231404 +77,5,20,-0.5002246167206466 +8,9,0,-0.771345568258845 +25,0,4,-0.7883367747824988 +61,5,11,-0.5164111712299326 +80,2,24,-0.38461266816220463 +48,9,40,0.13392095317252872 +97,3,42,-0.7840946848768833 +70,2,44,0.8622112660039105 +96,2,7,0.14217663121113233 +34,4,75,-0.09501796896263492 +83,4,84,0.687950247452028 +52,9,3,-0.7121081060931276 +72,5,6,-0.8626289452086549 +62,5,5,0.466506275983126 +62,3,92,-0.5317340510113464 +24,3,95,0.757866508750165 +5,9,52,-0.6343858850366688 +83,8,64,-0.8237952949698106 +88,2,39,0.8437453025991424 +4,9,66,0.0827651327871255 +41,7,75,-0.47171218849987295 +86,7,46,0.3309971394694893 +54,0,86,0.9139067114604842 +13,2,13,-0.10000116765373823 +1,1,7,0.31530360359275567 +72,4,14,-0.6859864619289415 +0,9,82,0.197901681705569 +90,8,39,-0.4163941760321046 +76,4,21,-0.5810838159419436 +9,9,45,0.8812146737512878 +74,7,94,0.596842572411119 +44,0,39,-0.627708790210354 +15,5,34,0.35405812211030696 +41,1,58,0.5420185311207879 +61,6,82,-0.09901956470648221 +7,3,7,-0.8022567463816235 +32,0,48,-0.09677861700658341 +28,2,98,-0.1353610816960309 +96,4,37,-0.1756636622355754 +9,5,89,-0.18029545348171205 +40,1,25,-0.5700828181569104 +69,3,79,-0.10401783090138039 +6,8,73,-0.4215056737797904 +75,4,61,0.8334031453611017 +67,4,5,0.792303918413261 +73,5,33,0.8490223480004508 +79,1,89,0.9050222156557075 +98,4,50,-0.9655424103957981 +81,2,66,-0.9871774043308457 +40,8,68,0.14887273903852494 +26,1,34,-0.45821613339048595 +66,7,90,0.12019070197101422 +78,1,35,-0.8912871266810962 +58,2,84,-0.45458677214513 +59,8,1,-0.3903686661549257 +79,5,14,0.8820801262688984 +70,3,31,-0.315389774286732 +46,9,55,-0.826334194156938 +37,8,68,0.8147570593805591 +19,7,45,0.5433969713755009 diff --git a/test/test_data/reformat_test_data.py b/test/test_data/reformat_test_data.py new file mode 100644 index 00000000..e3501e1b --- /dev/null +++ b/test/test_data/reformat_test_data.py @@ -0,0 +1,23 @@ +import argparse +import os + +import numpy as np +import pandas as pd + + +def load_txt_as_df(file_path): + return pd.read_csv(file_path, sep=" ", header=None, names=["src", "edge_type", "dst"]) + + +def main(): + train_df = load_txt_as_df("train_edges.txt") + test_df = load_txt_as_df("test_edges.txt") + valid_df = load_txt_as_df("valid_edges.txt") + + combined_df = pd.concat([train_df, test_df, valid_df]) + combined_df["edge_weights"] = np.random.uniform(-1.0, 1.0, len(combined_df.index)) + combined_df.to_csv("test_edges_with_weights.csv", index=False, header=False) + + +if __name__ == "__main__": + main() diff --git a/test/test_data/train_edges_weights.txt b/test/test_data/train_edges_weights.txt deleted file mode 100644 index 5baa0644..00000000 --- a/test/test_data/train_edges_weights.txt +++ /dev/null @@ -1,1000 +0,0 @@ -80 6 73 0 -83 8 2 1 -50 8 66 2 -64 5 42 3 -31 5 91 4 -40 8 92 5 -18 2 32 6 -21 5 64 7 -47 8 19 8 -71 2 71 9 -12 5 11 10 -76 6 58 11 -12 6 24 12 -69 9 11 13 -12 3 55 14 -77 4 14 15 -12 8 8 16 -29 5 14 17 -46 8 8 18 -30 0 60 19 -46 6 7 20 -51 6 69 21 -0 2 52 22 -81 9 26 23 -50 0 78 24 -59 9 93 25 -62 5 12 26 -93 0 14 27 -72 7 31 28 -46 2 12 29 -44 3 67 30 -45 1 46 31 -0 2 56 32 -68 7 49 33 -51 2 21 34 -66 9 99 35 -93 2 74 36 -59 9 9 37 -12 6 3 38 -26 6 11 39 -8 7 13 40 -46 8 70 41 -50 8 2 42 -10 8 5 43 -20 1 3 44 -43 3 46 45 -51 5 70 46 -73 4 74 47 -95 7 50 48 -59 8 12 49 -46 4 99 50 -20 3 55 51 -39 3 24 52 -28 8 8 53 -31 5 22 54 -84 3 95 55 -48 3 50 56 -81 4 10 57 -66 7 4 58 -15 2 78 59 -68 6 23 60 -55 0 0 61 -58 0 48 62 -75 4 50 63 -9 4 20 64 -48 9 87 65 -97 3 94 66 -44 9 83 67 -87 8 37 68 -74 6 33 69 -10 9 8 70 -81 3 18 71 -42 0 7 72 -74 3 37 73 -37 7 33 74 -35 7 47 75 -19 4 8 76 -19 4 78 77 -87 4 2 78 -39 2 21 79 -79 8 74 80 -21 1 24 81 -25 5 33 82 -24 2 33 83 -12 6 98 84 -47 8 6 85 -30 2 94 86 -61 1 78 87 -80 0 83 88 -91 1 97 89 -24 6 5 90 -32 8 82 91 -40 7 34 92 -68 6 98 93 -76 8 19 94 -90 3 40 95 -90 1 77 96 -11 4 49 97 -10 3 82 98 -39 9 2 99 -15 0 85 100 -85 3 81 101 -67 2 80 102 -0 8 58 103 -77 9 48 104 -93 6 20 105 -67 4 62 106 -51 9 36 107 -74 3 76 108 -7 4 94 109 -23 9 46 110 -2 5 32 111 -48 7 49 112 -35 6 19 113 -52 2 33 114 -31 1 2 115 -54 3 26 116 -63 3 85 117 -40 1 43 118 -57 7 51 119 -74 3 59 120 -11 1 82 121 -13 9 23 122 -70 5 83 123 -6 2 25 124 -86 7 59 125 -71 0 62 126 -77 0 82 127 -63 8 88 128 -4 7 10 129 -36 6 73 130 -77 5 58 131 -6 2 4 132 -89 8 84 133 -8 8 80 134 -27 3 32 135 -22 1 96 136 -58 0 45 137 -62 8 19 138 -10 4 67 139 -5 7 21 140 -18 7 3 141 -59 0 96 142 -17 6 49 143 -82 3 39 144 -41 2 24 145 -43 0 22 146 -4 5 79 147 -76 7 29 148 -13 7 3 149 -2 9 52 150 -65 9 37 151 -46 1 65 152 -72 0 67 153 -42 8 83 154 -92 3 72 155 -46 4 97 156 -7 1 35 157 -10 5 23 158 -39 4 28 159 -78 3 7 160 -23 0 94 161 -86 1 22 162 -13 6 47 163 -15 4 8 164 -63 4 73 165 -63 7 54 166 -51 8 22 167 -74 7 90 168 -55 9 68 169 -55 8 89 170 -95 4 86 171 -70 8 34 172 -11 1 42 173 -74 8 32 174 -90 9 33 175 -25 8 65 176 -60 1 59 177 -34 9 45 178 -59 8 53 179 -1 2 75 180 -8 5 63 181 -79 9 30 182 -21 9 32 183 -4 5 2 184 -40 1 94 185 -3 2 20 186 -20 5 11 187 -52 9 77 188 -60 4 38 189 -22 8 68 190 -64 4 26 191 -44 7 32 192 -82 7 62 193 -58 8 55 194 -7 3 18 195 -15 6 53 196 -21 6 62 197 -99 0 22 198 -37 1 51 199 -1 6 46 200 -68 5 78 201 -34 0 92 202 -9 4 41 203 -8 5 46 204 -43 1 87 205 -96 5 78 206 -84 7 43 207 -72 3 60 208 -59 7 57 209 -28 0 83 210 -93 5 34 211 -78 2 36 212 -15 2 89 213 -68 3 71 214 -51 1 26 215 -67 2 67 216 -68 2 79 217 -85 3 66 218 -68 3 74 219 -21 3 28 220 -25 8 87 221 -82 3 67 222 -36 5 2 223 -38 9 12 224 -30 1 25 225 -89 7 45 226 -31 1 7 227 -22 8 72 228 -30 4 56 229 -14 7 60 230 -26 4 74 231 -74 0 1 232 -42 3 70 233 -91 0 85 234 -74 5 87 235 -83 0 0 236 -14 0 33 237 -48 4 18 238 -47 7 3 239 -34 8 74 240 -91 7 3 241 -13 6 56 242 -5 6 19 243 -43 5 80 244 -45 5 68 245 -41 2 29 246 -88 3 83 247 -39 4 42 248 -31 1 4 249 -51 6 13 250 -49 0 59 251 -0 0 37 252 -28 6 41 253 -58 0 94 254 -86 1 86 255 -96 0 22 256 -11 7 91 257 -61 2 5 258 -93 6 55 259 -17 5 63 260 -47 2 17 261 -93 6 42 262 -96 5 4 263 -73 1 35 264 -41 6 46 265 -8 3 69 266 -5 7 9 267 -38 3 27 268 -7 9 61 269 -10 9 75 270 -55 9 37 271 -53 1 18 272 -9 8 19 273 -58 1 56 274 -10 7 90 275 -15 2 13 276 -47 3 45 277 -74 6 60 278 -38 5 40 279 -32 4 30 280 -9 2 74 281 -85 5 37 282 -74 9 13 283 -4 5 37 284 -17 5 20 285 -88 8 11 286 -5 5 70 287 -71 2 74 288 -88 7 4 289 -71 4 89 290 -50 7 50 291 -3 2 77 292 -8 6 83 293 -30 9 74 294 -87 7 3 295 -58 3 32 296 -48 4 1 297 -93 5 99 298 -15 4 48 299 -59 6 18 300 -13 5 14 301 -42 0 4 302 -97 0 55 303 -41 7 7 304 -45 1 70 305 -47 1 49 306 -72 9 73 307 -73 6 18 308 -12 4 57 309 -65 6 2 310 -7 9 52 311 -76 3 78 312 -60 4 70 313 -69 2 17 314 -65 9 25 315 -44 7 7 316 -59 9 15 317 -39 4 7 318 -91 9 26 319 -82 9 51 320 -70 2 28 321 -29 3 38 322 -52 9 35 323 -22 5 83 324 -5 7 5 325 -61 7 98 326 -12 9 65 327 -44 7 89 328 -62 9 6 329 -87 4 26 330 -66 4 10 331 -84 9 49 332 -68 9 39 333 -56 0 52 334 -26 6 22 335 -42 6 64 336 -61 9 90 337 -78 5 39 338 -71 7 19 339 -1 0 89 340 -87 4 23 341 -23 0 52 342 -94 4 57 343 -7 0 85 344 -98 4 89 345 -87 7 39 346 -94 8 4 347 -45 1 93 348 -99 8 45 349 -21 1 79 350 -65 9 97 351 -85 5 14 352 -45 0 65 353 -41 5 12 354 -58 3 27 355 -88 4 86 356 -13 1 8 357 -71 4 39 358 -66 2 22 359 -89 6 53 360 -13 7 66 361 -61 5 91 362 -99 0 73 363 -76 3 3 364 -7 3 51 365 -61 6 93 366 -63 0 13 367 -33 7 96 368 -6 2 69 369 -68 2 65 370 -76 4 9 371 -66 0 37 372 -4 4 63 373 -76 2 26 374 -28 5 63 375 -92 9 82 376 -1 1 49 377 -43 5 20 378 -34 0 18 379 -38 7 2 380 -74 3 72 381 -71 5 76 382 -53 8 58 383 -61 7 45 384 -57 9 55 385 -79 7 87 386 -55 5 95 387 -10 1 54 388 -83 1 32 389 -74 6 61 390 -50 1 1 391 -89 5 87 392 -54 7 40 393 -83 7 48 394 -20 1 76 395 -57 2 80 396 -18 7 54 397 -56 2 13 398 -9 4 15 399 -76 7 48 400 -20 8 29 401 -34 3 95 402 -80 0 85 403 -79 4 17 404 -94 2 23 405 -46 2 94 406 -13 8 70 407 -31 2 28 408 -63 8 49 409 -83 2 97 410 -51 6 28 411 -64 0 5 412 -19 9 52 413 -69 0 27 414 -80 7 4 415 -39 9 81 416 -98 9 82 417 -28 9 81 418 -73 9 58 419 -68 7 40 420 -72 4 48 421 -9 2 65 422 -34 3 35 423 -62 0 3 424 -73 8 54 425 -13 2 38 426 -50 0 29 427 -81 2 96 428 -48 3 4 429 -58 5 97 430 -22 1 91 431 -41 7 14 432 -47 1 0 433 -44 8 58 434 -77 6 92 435 -65 6 73 436 -8 8 61 437 -74 0 2 438 -21 0 83 439 -80 9 92 440 -53 0 34 441 -85 8 55 442 -53 3 83 443 -32 6 33 444 -52 3 14 445 -34 1 14 446 -45 0 55 447 -93 5 79 448 -33 9 65 449 -79 7 27 450 -5 9 4 451 -99 7 26 452 -26 2 78 453 -36 4 9 454 -56 6 92 455 -82 7 21 456 -82 9 46 457 -99 2 90 458 -57 6 25 459 -97 4 4 460 -66 7 53 461 -79 3 23 462 -56 5 16 463 -23 8 88 464 -61 9 36 465 -27 1 51 466 -7 1 93 467 -27 7 38 468 -15 1 60 469 -83 1 5 470 -58 2 6 471 -14 4 95 472 -33 3 90 473 -45 8 88 474 -96 5 24 475 -42 5 94 476 -46 6 80 477 -31 2 65 478 -59 6 4 479 -16 4 13 480 -10 2 41 481 -81 3 73 482 -83 0 68 483 -11 0 26 484 -52 2 11 485 -75 3 81 486 -89 5 29 487 -75 9 66 488 -87 4 15 489 -73 3 10 490 -4 9 67 491 -76 2 35 492 -15 0 43 493 -37 5 93 494 -37 2 55 495 -61 4 12 496 -2 2 81 497 -4 0 69 498 -1 8 95 499 -7 4 72 500 -9 1 16 501 -25 8 88 502 -8 2 74 503 -65 3 30 504 -83 3 67 505 -42 4 1 506 -36 3 30 507 -19 1 23 508 -76 5 90 509 -83 8 13 510 -31 6 79 511 -87 6 36 512 -7 1 74 513 -0 6 69 514 -30 1 52 515 -57 0 89 516 -0 2 62 517 -55 8 25 518 -28 8 13 519 -50 9 20 520 -44 1 33 521 -48 2 77 522 -93 5 56 523 -29 6 97 524 -93 3 21 525 -4 2 94 526 -26 7 43 527 -20 0 28 528 -76 6 63 529 -15 5 66 530 -59 1 60 531 -29 4 7 532 -41 7 27 533 -40 4 97 534 -10 2 43 535 -44 6 76 536 -73 9 38 537 -88 4 89 538 -44 9 21 539 -73 9 17 540 -8 5 21 541 -9 0 85 542 -84 0 48 543 -36 3 89 544 -58 2 25 545 -27 5 5 546 -13 1 90 547 -50 3 51 548 -3 8 41 549 -79 3 69 550 -73 5 75 551 -71 6 32 552 -95 4 65 553 -65 0 98 554 -12 1 46 555 -93 8 60 556 -81 7 95 557 -48 5 30 558 -8 8 14 559 -83 1 47 560 -38 8 37 561 -58 7 12 562 -52 1 89 563 -86 0 0 564 -36 1 69 565 -20 0 56 566 -71 3 2 567 -94 6 92 568 -20 7 14 569 -53 2 1 570 -50 2 77 571 -91 6 57 572 -28 1 15 573 -26 9 97 574 -52 5 73 575 -19 7 32 576 -5 7 63 577 -27 7 73 578 -5 7 13 579 -48 9 89 580 -13 5 84 581 -48 8 11 582 -12 5 66 583 -13 8 39 584 -10 5 35 585 -30 0 79 586 -41 8 79 587 -72 9 70 588 -82 2 93 589 -49 9 5 590 -85 7 48 591 -95 4 22 592 -58 6 7 593 -45 5 87 594 -81 8 46 595 -69 7 99 596 -34 0 29 597 -57 3 57 598 -65 0 84 599 -29 3 78 600 -12 4 10 601 -93 7 5 602 -74 9 99 603 -53 0 77 604 -26 3 87 605 -62 0 99 606 -12 3 73 607 -58 3 92 608 -42 7 46 609 -98 7 15 610 -33 5 82 611 -51 3 66 612 -39 0 18 613 -23 0 14 614 -64 8 22 615 -31 9 42 616 -96 0 91 617 -73 0 21 618 -69 5 15 619 -46 7 47 620 -82 6 87 621 -96 3 79 622 -1 8 69 623 -31 7 5 624 -16 3 90 625 -45 7 94 626 -58 2 82 627 -51 0 44 628 -43 7 34 629 -2 3 26 630 -99 1 48 631 -17 8 45 632 -37 1 38 633 -12 5 81 634 -79 9 35 635 -69 3 76 636 -13 8 21 637 -8 5 67 638 -41 5 30 639 -74 2 53 640 -56 9 70 641 -86 6 8 642 -47 8 44 643 -46 9 82 644 -0 4 14 645 -80 1 47 646 -20 8 18 647 -83 2 22 648 -75 9 82 649 -71 8 55 650 -0 5 46 651 -93 7 11 652 -65 3 22 653 -26 8 88 654 -4 8 18 655 -23 5 6 656 -32 6 22 657 -26 3 94 658 -40 2 16 659 -4 0 77 660 -82 2 71 661 -2 8 74 662 -90 0 9 663 -92 4 98 664 -48 8 44 665 -47 2 53 666 -58 9 2 667 -97 9 12 668 -5 5 67 669 -24 9 56 670 -99 2 85 671 -19 1 14 672 -88 2 47 673 -95 2 49 674 -14 6 57 675 -56 7 94 676 -84 5 31 677 -5 6 96 678 -94 0 0 679 -33 0 38 680 -24 0 83 681 -77 5 62 682 -73 2 28 683 -53 4 21 684 -4 0 46 685 -30 5 34 686 -9 6 4 687 -11 3 31 688 -1 1 3 689 -86 5 42 690 -31 1 13 691 -73 4 13 692 -36 9 13 693 -27 4 2 694 -5 2 48 695 -60 9 19 696 -96 2 52 697 -69 9 96 698 -17 2 2 699 -73 8 67 700 -71 9 58 701 -31 1 54 702 -38 5 82 703 -3 0 67 704 -69 3 25 705 -50 6 98 706 -93 9 4 707 -48 7 47 708 -19 3 13 709 -40 5 77 710 -21 2 42 711 -42 1 23 712 -14 3 29 713 -42 4 38 714 -76 0 34 715 -85 6 0 716 -91 1 79 717 -75 8 58 718 -60 1 44 719 -29 2 4 720 -88 0 37 721 -53 8 28 722 -88 8 10 723 -54 6 24 724 -25 6 56 725 -26 8 79 726 -76 2 87 727 -36 9 84 728 -38 3 68 729 -84 7 50 730 -60 6 84 731 -60 3 24 732 -86 3 49 733 -52 7 56 734 -59 1 77 735 -26 4 19 736 -92 8 94 737 -18 3 6 738 -40 2 56 739 -38 2 49 740 -60 6 11 741 -35 9 30 742 -4 9 17 743 -24 5 51 744 -33 5 2 745 -3 7 82 746 -99 8 57 747 -61 9 28 748 -11 7 28 749 -31 6 73 750 -67 4 68 751 -43 5 56 752 -49 6 57 753 -78 2 87 754 -94 6 93 755 -85 2 47 756 -65 1 99 757 -98 1 63 758 -47 3 2 759 -50 8 4 760 -42 5 30 761 -77 0 85 762 -67 9 65 763 -26 3 65 764 -59 1 24 765 -36 0 76 766 -68 3 95 767 -34 6 96 768 -61 5 7 769 -44 0 59 770 -30 7 15 771 -81 2 14 772 -78 4 30 773 -20 3 65 774 -85 6 42 775 -41 7 43 776 -51 2 6 777 -26 7 25 778 -92 5 49 779 -90 0 61 780 -11 8 15 781 -77 2 31 782 -30 9 48 783 -88 9 93 784 -90 5 70 785 -57 5 17 786 -18 9 23 787 -56 2 82 788 -25 7 34 789 -26 1 9 790 -91 9 30 791 -49 8 99 792 -96 8 88 793 -93 2 65 794 -36 8 67 795 -40 5 76 796 -8 2 31 797 -92 4 66 798 -92 4 28 799 -13 2 73 800 -4 1 30 801 -83 4 6 802 -96 0 3 803 -12 9 45 804 -85 5 29 805 -34 0 39 806 -51 7 97 807 -3 9 85 808 -19 5 73 809 -92 2 38 810 -51 5 83 811 -71 9 79 812 -83 4 60 813 -62 8 77 814 -0 9 32 815 -70 7 95 816 -72 6 0 817 -69 4 95 818 -3 1 43 819 -62 9 20 820 -76 9 85 821 -84 4 79 822 -21 1 3 823 -20 5 83 824 -91 2 22 825 -83 3 21 826 -75 6 25 827 -56 1 74 828 -31 2 30 829 -66 8 3 830 -19 9 37 831 -19 5 11 832 -81 5 93 833 -68 4 38 834 -37 2 39 835 -56 8 97 836 -82 5 58 837 -81 2 65 838 -98 5 40 839 -78 6 53 840 -18 5 45 841 -42 9 29 842 -75 9 93 843 -99 8 14 844 -97 7 35 845 -33 4 41 846 -36 8 85 847 -42 3 54 848 -58 7 50 849 -3 7 53 850 -64 3 80 851 -0 7 23 852 -98 5 30 853 -71 8 86 854 -37 8 11 855 -90 2 12 856 -5 9 41 857 -54 9 58 858 -14 4 96 859 -16 5 97 860 -1 9 15 861 -41 4 9 862 -32 5 17 863 -96 7 71 864 -83 4 61 865 -21 3 81 866 -28 9 31 867 -96 8 39 868 -90 5 46 869 -65 6 63 870 -50 4 7 871 -43 7 21 872 -23 9 76 873 -54 0 47 874 -39 8 11 875 -71 4 90 876 -47 8 99 877 -46 5 71 878 -90 4 57 879 -81 4 89 880 -43 1 90 881 -32 1 72 882 -0 4 70 883 -47 5 34 884 -43 1 28 885 -13 1 69 886 -49 4 9 887 -36 7 38 888 -94 0 24 889 -64 4 11 890 -53 7 12 891 -17 5 12 892 -96 2 69 893 -99 7 75 894 -70 4 85 895 -93 6 64 896 -61 7 2 897 -47 2 50 898 -50 1 58 899 -3 4 18 900 -41 2 31 901 -45 2 49 902 -98 2 83 903 -88 2 40 904 -34 2 59 905 -86 2 99 906 -49 4 28 907 -20 0 24 908 -98 0 0 909 -51 4 78 910 -66 8 50 911 -37 2 77 912 -62 5 53 913 -97 1 20 914 -84 2 15 915 -48 3 95 916 -18 4 17 917 -20 5 9 918 -56 0 24 919 -90 8 64 920 -13 7 5 921 -80 5 19 922 -49 1 33 923 -20 2 12 924 -92 8 4 925 -25 7 28 926 -47 7 24 927 -84 4 61 928 -2 7 84 929 -0 0 25 930 -13 9 62 931 -17 4 4 932 -1 0 96 933 -59 6 6 934 -50 5 76 935 -69 1 60 936 -64 0 82 937 -37 0 96 938 -57 0 77 939 -60 5 89 940 -83 3 1 941 -23 5 86 942 -54 5 87 943 -83 8 76 944 -12 4 15 945 -13 6 86 946 -89 7 97 947 -12 8 2 948 -26 0 13 949 -64 4 48 950 -3 1 12 951 -86 1 68 952 -78 8 4 953 -96 3 14 954 -64 7 71 955 -51 7 72 956 -66 5 73 957 -86 4 17 958 -1 1 82 959 -91 9 71 960 -50 5 88 961 -60 6 81 962 -57 5 45 963 -30 7 6 964 -50 1 11 965 -84 7 30 966 -66 6 86 967 -39 4 47 968 -29 8 1 969 -82 7 30 970 -82 2 54 971 -35 3 74 972 -38 9 9 973 -64 8 88 974 -74 6 51 975 -58 4 30 976 -8 4 6 977 -72 3 63 978 -81 4 44 979 -90 4 1 980 -91 3 62 981 -19 4 53 982 -2 9 78 983 -70 0 84 984 -89 1 74 985 -66 3 0 986 -95 5 73 987 -44 9 94 988 -18 3 87 989 -6 5 90 990 -42 9 45 991 -17 1 41 992 -81 6 70 993 -72 0 42 994 -45 8 43 995 -16 5 31 996 -61 5 69 997 -87 3 6 998 -80 7 33 999