From 254caf91acf270558dd155c3f0e523932da98829 Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 16 Sep 2024 10:16:29 -0400 Subject: [PATCH 1/6] WIP on efficient GPU scan --- stream_compaction/cpu.cu | 67 +++++++++++++++++++++++++++---- stream_compaction/efficient.cu | 73 ++++++++++++++++++++++++++++++++++ stream_compaction/naive.cu | 61 ++++++++++++++++++++++++++++ 3 files changed, 193 insertions(+), 8 deletions(-) diff --git a/stream_compaction/cpu.cu b/stream_compaction/cpu.cu index 719fa11..db1cd7b 100644 --- a/stream_compaction/cpu.cu +++ b/stream_compaction/cpu.cu @@ -17,9 +17,15 @@ namespace StreamCompaction { * For performance analysis, this is supposed to be a simple for loop. * (Optional) For better understanding before starting moving to GPU, you can simulate your GPU scan in this function first. */ - void scan(int n, int *odata, const int *idata) { + void scan(int n, int* odata, const int* idata) { timer().startCpuTimer(); - // TODO + + int current_sum = 0; + for (int i = 0; i < n; i++) { + odata[i] = current_sum; + current_sum += idata[i]; + } + timer().endCpuTimer(); } @@ -28,11 +34,30 @@ namespace StreamCompaction { * * @returns the number of elements remaining after compaction. */ - int compactWithoutScan(int n, int *odata, const int *idata) { + int compactWithoutScan(int n, int* odata, const int* idata) { timer().startCpuTimer(); - // TODO + + int o_idx = 0; + for (int i = 0; i < n; i++) { + if (idata[i] != 0) { + odata[o_idx] = idata[i]; + o_idx++; + } + } + timer().endCpuTimer(); - return -1; + return o_idx; + } + + int scatter(const int* idata, int* odata, int* scan_result, int* to_insert, int n) { + int num_elts = 0; + for (int i = 0; i < n; i++) { + if (to_insert[i] == 1) { + odata[scan_result[i]] = idata[i]; + num_elts++; + } + } + return num_elts; } /** @@ -40,11 +65,37 @@ namespace StreamCompaction { * * @returns the number of elements remaining after compaction. */ - int compactWithScan(int n, int *odata, const int *idata) { + int compactWithScan(int n, int* odata, const int* idata) { timer().startCpuTimer(); - // TODO + + int* to_insert = new int[n]; + int* scan_result = new int[n]; + + //scan + int current_sum = 0; + for (int i = 0; i < n; i++) { + scan_result[i] = current_sum; + current_sum += idata[i]; + } + + //set to_insert to 0 if the element is going to be removed and 1 otherwise + for (int i = 0; i < n; i++) { + to_insert[i] = (idata[i] == 0) ? 0 : 1; + } + + //adjust scan result for proper indices + for (int i = 1; i < n; i++) { + scan_result[i] = to_insert[i - 1] + scan_result[i - 1]; + } + + //scatter and get number of elements to return + int num_elts = scatter(idata, odata, scan_result, to_insert, n); + + delete[] to_insert; + delete[] scan_result; + timer().endCpuTimer(); - return -1; + return num_elts; } } } diff --git a/stream_compaction/efficient.cu b/stream_compaction/efficient.cu index 2db346e..a1bafa1 100644 --- a/stream_compaction/efficient.cu +++ b/stream_compaction/efficient.cu @@ -12,12 +12,85 @@ namespace StreamCompaction { return timer; } + __global__ void kernUpsweep(int n, int d, int* data) { + int k = (blockDim.x * blockIdx.x) + threadIdx.x; + if (k > n) { + return; + } + /*int pow_res = pow(2, d - 1); + if (k >= pow_res) { + int idx = k + pow(2, d + 1) - 1; + data[idx] += data[k + d]; + }*/ + int pow_d_plus_one = powf(2, d + 1); + int pow_d = powf(2, d); + data[k + pow_d_plus_one - 1] += data[k + pow_d - 1]; + } + + __global__ void kernDownsweep(int n, int d, int* data) { + int k = (blockDim.x * blockIdx.x) + threadIdx.x; + if (k > n) { + return; + } + int curr_left_idx = k + pow(2, d) - 1; + int left_child = data[curr_left_idx]; // Save left child + int curr_node_idx = k + pow(2, d + 1) - 1; + data[curr_left_idx] = data[curr_node_idx]; // Set left child to this node’s value + data[curr_node_idx] += left_child; // Set right child to old left value + this node’s value + } + + __global__ void kernPadZeroes(int n, int d, int* data) { + int k = (blockDim.x * blockIdx.x) + threadIdx.x; + if (k > n) { + return; + } + if (k > d) { + data[k] = 0; + } + } + /** * Performs prefix-sum (aka scan) on idata, storing the result into odata. */ void scan(int n, int *odata, const int *idata) { timer().startGpuTimer(); // TODO + + int original_length = n; + int log = ilog2ceil(n); + float f_log = log2f(n); + + //size of array is not power of 2 + if (f_log != (float)log) { + int new_length = pow(2, log); + n = new_length; + } + + int* data; + cudaMalloc((void**)&data, sizeof(int) * n); + cudaMemcpy(data, idata, sizeof(int) * n, cudaMemcpyHostToDevice); + + int blockSize = 128; + dim3 blockDim((n + blockSize - 1) / blockSize); + + if (f_log != (float)log) { + kernPadZeroes<<>>(n, original_length, data); + } + + for (int d = 1; d <= log; d++) { + kernUpsweep << > > (n, d, data); + } + + //set root to 0 + cudaMemset(data + n - 1, 0, sizeof(int)); + + for (int d = log - 1; d >= 0; d--) { + kernDownsweep << > > (n, d, data); + } + + cudaMemcpy(odata, data, sizeof(int) * n, cudaMemcpyDeviceToHost); + cudaFree(data); + timer().endGpuTimer(); } diff --git a/stream_compaction/naive.cu b/stream_compaction/naive.cu index 4308876..6763e7e 100644 --- a/stream_compaction/naive.cu +++ b/stream_compaction/naive.cu @@ -13,12 +13,73 @@ namespace StreamCompaction { } // TODO: __global__ + __global__ void kernScan(int n, int d, int* odata, const int* idata) { + int k = (blockDim.x * blockIdx.x) + threadIdx.x; + if (k > n) { + return; + } + int pow_res = pow(2, d - 1); + if (k >= pow_res) { + int idx = k - pow_res; + odata[k] = idata[idx] + idata[k]; + } + else { + odata[k] = idata[k]; + } + } + + __global__ void kernMakeScanExclusive(int n, int* odata, int* idata) { + int k = (blockDim.x * blockIdx.x) + threadIdx.x; + if (k > n) { + return; + } + odata[k] = k == 0 ? 0 : idata[k - 1]; + } + /** * Performs prefix-sum (aka scan) on idata, storing the result into odata. */ void scan(int n, int *odata, const int *idata) { timer().startGpuTimer(); // TODO + + int log = ilog2ceil(n); + + int* data_a; + int* data_b; + cudaMalloc((void**)&data_a, sizeof(int) * n); + cudaMalloc((void**)&data_b, sizeof(int) * n); + + cudaMemcpy(data_b, idata, sizeof(int) * n, cudaMemcpyHostToDevice); + + int blockSize = 128; + dim3 blockDim((n + blockSize - 1) / blockSize); + bool a_has_output = true; + + for (int d = 1; d <= log; d++) { + // k = n? does not seem necessary, can prob find a log val that we can limit k to. then do [k, n] + kernScan << > > (n, d, data_a, data_b); + int* temp = data_a; + data_a = data_b; + data_b = temp; + a_has_output = !a_has_output; + } + + int *out_arr, *in_arr; + if (a_has_output) { + out_arr = data_a; + in_arr = data_b; + } + else { + out_arr = data_b; + in_arr = data_a; + } + kernMakeScanExclusive << > > (n, out_arr, in_arr); + cudaMemcpy(odata, out_arr, sizeof(int) * n, cudaMemcpyDeviceToHost); + + cudaFree(data_a); + cudaFree(data_b); + timer().endGpuTimer(); } } From 0e19b525b4216a51a947536b9bfccd85daadd38f Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 17 Sep 2024 10:08:41 -0400 Subject: [PATCH 2/6] Parts 2 and 3 complete --- stream_compaction/common.cu | 15 +++- stream_compaction/cpu.cu | 6 +- stream_compaction/efficient.cu | 159 ++++++++++++++++++++++++--------- stream_compaction/naive.cu | 13 +-- stream_compaction/thrust.cu | 15 ++++ 5 files changed, 153 insertions(+), 55 deletions(-) diff --git a/stream_compaction/common.cu b/stream_compaction/common.cu index 2ed6d63..8287bf1 100644 --- a/stream_compaction/common.cu +++ b/stream_compaction/common.cu @@ -23,7 +23,11 @@ namespace StreamCompaction { * which map to 0 will be removed, and elements which map to 1 will be kept. */ __global__ void kernMapToBoolean(int n, int *bools, const int *idata) { - // TODO + int k = (blockDim.x * blockIdx.x) + threadIdx.x; + if (k > n) { + return; + } + bools[k] = (idata[k] == 0) ? 0 : 1; } /** @@ -32,8 +36,13 @@ namespace StreamCompaction { */ __global__ void kernScatter(int n, int *odata, const int *idata, const int *bools, const int *indices) { - // TODO + int k = (blockDim.x * blockIdx.x) + threadIdx.x; + if (k >= n) { + return; + } + if (bools[k] == 1) { + odata[indices[k]] = idata[k]; + } } - } } diff --git a/stream_compaction/cpu.cu b/stream_compaction/cpu.cu index db1cd7b..9bd8659 100644 --- a/stream_compaction/cpu.cu +++ b/stream_compaction/cpu.cu @@ -66,10 +66,11 @@ namespace StreamCompaction { * @returns the number of elements remaining after compaction. */ int compactWithScan(int n, int* odata, const int* idata) { - timer().startCpuTimer(); int* to_insert = new int[n]; int* scan_result = new int[n]; + + timer().startCpuTimer(); //scan int current_sum = 0; @@ -91,10 +92,11 @@ namespace StreamCompaction { //scatter and get number of elements to return int num_elts = scatter(idata, odata, scan_result, to_insert, n); + timer().endCpuTimer(); + delete[] to_insert; delete[] scan_result; - timer().endCpuTimer(); return num_elts; } } diff --git a/stream_compaction/efficient.cu b/stream_compaction/efficient.cu index a1bafa1..d3ec1b0 100644 --- a/stream_compaction/efficient.cu +++ b/stream_compaction/efficient.cu @@ -14,37 +14,39 @@ namespace StreamCompaction { __global__ void kernUpsweep(int n, int d, int* data) { int k = (blockDim.x * blockIdx.x) + threadIdx.x; - if (k > n) { + int pow_d_plus_one = pow(2, d + 1); + + if (k > n / pow_d_plus_one) { return; } - /*int pow_res = pow(2, d - 1); - if (k >= pow_res) { - int idx = k + pow(2, d + 1) - 1; - data[idx] += data[k + d]; - }*/ - int pow_d_plus_one = powf(2, d + 1); - int pow_d = powf(2, d); + + k *= pow_d_plus_one; + + int pow_d = pow(2, d); + data[k + pow_d_plus_one - 1] += data[k + pow_d - 1]; } __global__ void kernDownsweep(int n, int d, int* data) { int k = (blockDim.x * blockIdx.x) + threadIdx.x; - if (k > n) { + int pow_d_plus_one = pow(2, d + 1); + + if (k > n / pow_d_plus_one) { return; } + + k *= pow_d_plus_one; + int curr_left_idx = k + pow(2, d) - 1; - int left_child = data[curr_left_idx]; // Save left child - int curr_node_idx = k + pow(2, d + 1) - 1; - data[curr_left_idx] = data[curr_node_idx]; // Set left child to this node’s value - data[curr_node_idx] += left_child; // Set right child to old left value + this node’s value + int left_child_val = data[curr_left_idx]; // Save left child + int curr_node_idx = k + pow_d_plus_one - 1; + data[curr_left_idx] = data[curr_node_idx]; // Set left child to this node’s value + data[curr_node_idx] += left_child_val; // Set right child to old left value + this node’s value } - __global__ void kernPadZeroes(int n, int d, int* data) { + __global__ void kernPadZeroes(int original_length, int start_point, int* data) { int k = (blockDim.x * blockIdx.x) + threadIdx.x; - if (k > n) { - return; - } - if (k > d) { + if (k >= original_length && k < start_point) { data[k] = 0; } } @@ -53,45 +55,46 @@ namespace StreamCompaction { * Performs prefix-sum (aka scan) on idata, storing the result into odata. */ void scan(int n, int *odata, const int *idata) { - timer().startGpuTimer(); - // TODO - - int original_length = n; int log = ilog2ceil(n); - float f_log = log2f(n); - - //size of array is not power of 2 - if (f_log != (float)log) { - int new_length = pow(2, log); - n = new_length; - } + int power_two_len = pow(2, log); int* data; - cudaMalloc((void**)&data, sizeof(int) * n); - cudaMemcpy(data, idata, sizeof(int) * n, cudaMemcpyHostToDevice); + cudaMalloc((void**)&data, sizeof(int) * power_two_len); + cudaMemcpy(data, idata, sizeof(int) * power_two_len, cudaMemcpyHostToDevice); + + timer().startGpuTimer(); int blockSize = 128; - dim3 blockDim((n + blockSize - 1) / blockSize); + dim3 blockDim = dim3((power_two_len + blockSize - 1) / blockSize); + kernPadZeroes << > > (n, power_two_len, data); - if (f_log != (float)log) { - kernPadZeroes<<>>(n, original_length, data); - } + int threads_to_launch; + + //upsweep + for (int d = 0; d < log; d++) { + threads_to_launch = power_two_len / pow(2, d + 1); - for (int d = 1; d <= log; d++) { - kernUpsweep << > > (n, d, data); + blockDim = dim3((threads_to_launch + blockSize - 1) / blockSize); + + kernUpsweep << > > (power_two_len, d, data); } //set root to 0 - cudaMemset(data + n - 1, 0, sizeof(int)); + cudaMemset(data + power_two_len - 1, 0, sizeof(int)); + //downsweep for (int d = log - 1; d >= 0; d--) { - kernDownsweep << > > (n, d, data); - } + threads_to_launch = power_two_len / pow(2, d + 1); - cudaMemcpy(odata, data, sizeof(int) * n, cudaMemcpyDeviceToHost); - cudaFree(data); + blockDim = dim3((threads_to_launch + blockSize - 1) / blockSize); + + kernDownsweep << > > (power_two_len, d, data); + } timer().endGpuTimer(); + + cudaMemcpy(odata, data, sizeof(int) * power_two_len, cudaMemcpyDeviceToHost); + cudaFree(data); } /** @@ -104,10 +107,78 @@ namespace StreamCompaction { * @returns The number of elements remaining after compaction. */ int compact(int n, int *odata, const int *idata) { + + int num_elts = -1; + + int log = ilog2ceil(n); + int power_two_len = pow(2, log); + + int blockSize = 128; + dim3 blockDim((n + blockSize - 1) / blockSize); + + int* in_data; + cudaMalloc((void**)&in_data, sizeof(int) * n); + cudaMemcpy(in_data, idata, sizeof(int) * n, cudaMemcpyHostToDevice); + + int* bools; + cudaMalloc((void**)&bools, sizeof(int) * power_two_len); + + int* out_data; + cudaMalloc((void**)&out_data, sizeof(int) * n); + timer().startGpuTimer(); - // TODO + + int scan_blockSize = 128; + dim3 scan_blockDim = dim3((power_two_len + blockSize - 1) / blockSize); + + kernPadZeroes << > > (n, power_two_len, bools); + + StreamCompaction::Common::kernMapToBoolean << < blockDim, blockSize >> >(power_two_len, bools, in_data); + + //START SCAN (input data is now bools) + + int* scan_data; + cudaMalloc((void**)&scan_data, sizeof(int) * power_two_len); + cudaMemcpy(scan_data, bools, sizeof(int) * power_two_len, cudaMemcpyDeviceToDevice); + + int threads_to_launch; + + //upsweep + for (int d = 0; d < log; d++) { + threads_to_launch = power_two_len / pow(2, d + 1); + + scan_blockDim = dim3((threads_to_launch + scan_blockSize - 1) / scan_blockSize); + + kernUpsweep << > > (power_two_len, d, scan_data); + } + + //set root to 0 + cudaMemset(scan_data + power_two_len - 1, 0, sizeof(int)); + + //downsweep + for (int d = log - 1; d >= 0; d--) { + threads_to_launch = power_two_len / pow(2, d + 1); + + scan_blockDim = dim3((threads_to_launch + scan_blockSize - 1) / scan_blockSize); + + kernDownsweep << > > (power_two_len, d, scan_data); + } + + //END SCAN -- scan is in place so scan_data has the output + + StreamCompaction::Common::kernScatter << < blockDim, blockSize >> >(power_two_len, out_data, in_data, bools, scan_data); + timer().endGpuTimer(); - return -1; + + cudaMemcpy(odata, out_data, sizeof(int) * n, cudaMemcpyDeviceToHost); + cudaMemcpy(&num_elts, scan_data + power_two_len - 1, sizeof(int), cudaMemcpyDeviceToHost); + + cudaFree(bools); + cudaFree(in_data); + cudaFree(out_data); + cudaFree(scan_data); + + return num_elts; } } } diff --git a/stream_compaction/naive.cu b/stream_compaction/naive.cu index 6763e7e..888b672 100644 --- a/stream_compaction/naive.cu +++ b/stream_compaction/naive.cu @@ -40,10 +40,6 @@ namespace StreamCompaction { * Performs prefix-sum (aka scan) on idata, storing the result into odata. */ void scan(int n, int *odata, const int *idata) { - timer().startGpuTimer(); - // TODO - - int log = ilog2ceil(n); int* data_a; int* data_b; @@ -52,6 +48,10 @@ namespace StreamCompaction { cudaMemcpy(data_b, idata, sizeof(int) * n, cudaMemcpyHostToDevice); + timer().startGpuTimer(); + + int log = ilog2ceil(n); + int blockSize = 128; dim3 blockDim((n + blockSize - 1) / blockSize); bool a_has_output = true; @@ -75,12 +75,13 @@ namespace StreamCompaction { in_arr = data_a; } kernMakeScanExclusive << > > (n, out_arr, in_arr); + + timer().endGpuTimer(); + cudaMemcpy(odata, out_arr, sizeof(int) * n, cudaMemcpyDeviceToHost); cudaFree(data_a); cudaFree(data_b); - - timer().endGpuTimer(); } } } diff --git a/stream_compaction/thrust.cu b/stream_compaction/thrust.cu index 1def45e..e86c19a 100644 --- a/stream_compaction/thrust.cu +++ b/stream_compaction/thrust.cu @@ -18,11 +18,26 @@ namespace StreamCompaction { * Performs prefix-sum (aka scan) on idata, storing the result into odata. */ void scan(int n, int *odata, const int *idata) { + + int* host_in_arr; + cudaMalloc((void**)&host_in_arr, sizeof(int) * n); + cudaMemcpy(host_in_arr, idata, sizeof(int) * n, cudaMemcpyHostToDevice); + + thrust::device_vector dev_in_vec = thrust::device_vector(host_in_arr, host_in_arr + n); + thrust::device_vector dev_out_vec(n); + timer().startGpuTimer(); // TODO use `thrust::exclusive_scan` // example: for device_vectors dv_in and dv_out: // thrust::exclusive_scan(dv_in.begin(), dv_in.end(), dv_out.begin()); + + thrust::exclusive_scan(dev_in_vec.begin(), dev_in_vec.end(), dev_out_vec.begin()); + timer().endGpuTimer(); + + thrust::copy(dev_out_vec.begin(), dev_out_vec.end(), odata); + + cudaFree(host_in_arr); } } } From e88dddb8b525c37303d693d60c5d580db56b6f53 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 17 Sep 2024 11:48:31 -0400 Subject: [PATCH 3/6] Fixed errors in precision, started on readme --- README.md | 37 +++++++++++++++++++++++++++------ img/compaction_graph.png | Bin 0 -> 29400 bytes img/scan_graph.png | Bin 0 -> 35965 bytes src/main.cpp | 2 +- stream_compaction/common.cu | 2 +- stream_compaction/efficient.cu | 28 ++++++++++++++----------- stream_compaction/naive.cu | 26 +++++++---------------- 7 files changed, 56 insertions(+), 39 deletions(-) create mode 100644 img/compaction_graph.png create mode 100644 img/scan_graph.png diff --git a/README.md b/README.md index 0e38ddb..95fa850 100644 --- a/README.md +++ b/README.md @@ -3,12 +3,37 @@ CUDA Stream Compaction **University of Pennsylvania, CIS 565: GPU Programming and Architecture, Project 2** -* (TODO) YOUR NAME HERE - * (TODO) [LinkedIn](), [personal website](), [twitter](), etc. -* Tested on: (TODO) Windows 22, i7-2222 @ 2.22GHz 22GB, GTX 222 222MB (Moore 2222 Lab) +* Daniel Gerhardt + * https://www.linkedin.com/in/daniel-gerhardt-bb012722b/ +* Tested on: Windows 23H2, AMD Ryzen 9 7940HS @ 4GHz 32GB, RTX 4070 8 GB (Personal Laptop) -### (TODO: Your README) +### Stream Compaction -Include analysis, etc. (Remember, this is public, so don't put -anything here that you don't want to share with the world.) +## Description +Stream compaction is the process of taking an array and removing unwanted elements from it. In this project, that means removing 0s from an array. There are five different implementations being compared here. + +1. Compaction without scan on the CPU. This runs a simple O(n) for loop that checks if the input element is 0, and if it is not, adds it to the output. +2. Compaction with scan on the CPU. Scan is a "prefix sum" algorithm that outputs an array that contains at location i the sum of all elements up to element i. Scan can be used for compaction by creating an array of 1s and 0s that is parallel to the original input data, where a 1 represents the element at the same index is going to be in the output, and 0 represents the element is not going to be in the output. You can then accumulate the number of 1s to get an array that increases on the elements that should be contained in the output, and the value of the array at the element in the output is the final index of that element in the output. +3. Naive compaction on the GPU. The following figure shows what the approach looks like: +![](img/figure-39-2.jpg) + By adding in parallel and only having a logarithmic number of iterations, this algorithm reduces the overall complexity to O(logn). But, there are O(nlogn) adds since in the worst case there are O(n) adds per iteration. The work efficient solutions seeks to reduce this factor. +4. Work efficient compaction on the GPU. The following figure shows what the approach looks like: ![](img/figure-39-4.jpg) +This is a much less intuitive approach. The algorithm involves 2 phases, the upsweep and the downsweep. The upsweep is the same as the parallel reduction from method 3, except the algorithm occurs "in place" on the input data. Then, by treating the array as a tree and doing some clever summation, the amount of work can be reduced by filtering the sums down the "tree". This is done by setting the "root" -- the last element -- to zero, and then at each pass, giving each left child the parent's value, and setting the right child to the sum of the previous left child’s value and the parent's value. The upsweep has O(n) adds and the downsweep has O(n) adds and O(n) swaps, which reduces the complexity from method 3. +5. A wrapper for thrust's implementation of stream compaction for the sake of performance comparison. + +## Performance Analysis + +# Charts + +The following is a chart displaying how running time of the numerous methods changes with input size in the scan algorithm. + +![](img/scan_graph.jpg) + +The following is a chart displaying how running time of the numerous methods changes with input size in the compaction algorithm. + +![](img/compaction_graph.jpg) + +# Observations + +Observations on power-of-two length. In scan the non-power of two work efficient algorithm had a larger difference in performance over the power of two input. This is likely because the overhead of padding zeroes increases as size increases. The same is not true of the compaction algorithms, likely because the main bottleneck of that algorithm is the global memory reads, which are present even if the input is a power of 2. diff --git a/img/compaction_graph.png b/img/compaction_graph.png new file mode 100644 index 0000000000000000000000000000000000000000..4e070b8f9891fd473b107d153473c1476ed905e1 GIT binary patch literal 29400 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 bqZfL#88vTeI|3(G-jSD9mMVR16!gCU*p$m* literal 0 HcmV?d00001 diff --git a/img/scan_graph.png b/img/scan_graph.png new file mode 100644 index 0000000000000000000000000000000000000000..be04f8adb48c4a89f59e2fcc9080d69455d439d3 GIT binary patch literal 35965 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 Mq!eEkNErJ5f5Uor<^TWy literal 0 HcmV?d00001 diff --git a/src/main.cpp b/src/main.cpp index 896ac2b..969eb72 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -13,7 +13,7 @@ #include #include "testing_helpers.hpp" -const int SIZE = 1 << 8; // feel free to change the size of array +const int SIZE = 1 << 26; // feel free to change the size of array const int NPOT = SIZE - 3; // Non-Power-Of-Two int *a = new int[SIZE]; int *b = new int[SIZE]; diff --git a/stream_compaction/common.cu b/stream_compaction/common.cu index 8287bf1..35ea7d5 100644 --- a/stream_compaction/common.cu +++ b/stream_compaction/common.cu @@ -24,7 +24,7 @@ namespace StreamCompaction { */ __global__ void kernMapToBoolean(int n, int *bools, const int *idata) { int k = (blockDim.x * blockIdx.x) + threadIdx.x; - if (k > n) { + if (k >= n) { return; } bools[k] = (idata[k] == 0) ? 0 : 1; diff --git a/stream_compaction/efficient.cu b/stream_compaction/efficient.cu index d3ec1b0..972c08f 100644 --- a/stream_compaction/efficient.cu +++ b/stream_compaction/efficient.cu @@ -14,30 +14,30 @@ namespace StreamCompaction { __global__ void kernUpsweep(int n, int d, int* data) { int k = (blockDim.x * blockIdx.x) + threadIdx.x; - int pow_d_plus_one = pow(2, d + 1); + int pow_d_plus_one = (1 << d + 1); - if (k > n / pow_d_plus_one) { + if (k >= n / pow_d_plus_one) { return; } k *= pow_d_plus_one; - int pow_d = pow(2, d); + int pow_d = (1 << d); data[k + pow_d_plus_one - 1] += data[k + pow_d - 1]; } __global__ void kernDownsweep(int n, int d, int* data) { int k = (blockDim.x * blockIdx.x) + threadIdx.x; - int pow_d_plus_one = pow(2, d + 1); + int pow_d_plus_one = (1 << d + 1); - if (k > n / pow_d_plus_one) { + if (k >= n / pow_d_plus_one) { return; } k *= pow_d_plus_one; - int curr_left_idx = k + pow(2, d) - 1; + int curr_left_idx = k + (1 << d) - 1; int left_child_val = data[curr_left_idx]; // Save left child int curr_node_idx = k + pow_d_plus_one - 1; data[curr_left_idx] = data[curr_node_idx]; // Set left child to this node’s value @@ -56,7 +56,7 @@ namespace StreamCompaction { */ void scan(int n, int *odata, const int *idata) { int log = ilog2ceil(n); - int power_two_len = pow(2, log); + int power_two_len = (1 << log); int* data; cudaMalloc((void**)&data, sizeof(int) * power_two_len); @@ -72,7 +72,7 @@ namespace StreamCompaction { //upsweep for (int d = 0; d < log; d++) { - threads_to_launch = power_two_len / pow(2, d + 1); + threads_to_launch = power_two_len / (1 << d + 1); blockDim = dim3((threads_to_launch + blockSize - 1) / blockSize); @@ -84,7 +84,7 @@ namespace StreamCompaction { //downsweep for (int d = log - 1; d >= 0; d--) { - threads_to_launch = power_two_len / pow(2, d + 1); + threads_to_launch = power_two_len / (1 << d + 1); blockDim = dim3((threads_to_launch + blockSize - 1) / blockSize); @@ -111,7 +111,7 @@ namespace StreamCompaction { int num_elts = -1; int log = ilog2ceil(n); - int power_two_len = pow(2, log); + int power_two_len = (1 << log); int blockSize = 128; dim3 blockDim((n + blockSize - 1) / blockSize); @@ -145,7 +145,7 @@ namespace StreamCompaction { //upsweep for (int d = 0; d < log; d++) { - threads_to_launch = power_two_len / pow(2, d + 1); + threads_to_launch = power_two_len / (1 << d + 1); scan_blockDim = dim3((threads_to_launch + scan_blockSize - 1) / scan_blockSize); @@ -157,7 +157,7 @@ namespace StreamCompaction { //downsweep for (int d = log - 1; d >= 0; d--) { - threads_to_launch = power_two_len / pow(2, d + 1); + threads_to_launch = power_two_len / (1 << d + 1); scan_blockDim = dim3((threads_to_launch + scan_blockSize - 1) / scan_blockSize); @@ -173,6 +173,10 @@ namespace StreamCompaction { cudaMemcpy(odata, out_data, sizeof(int) * n, cudaMemcpyDeviceToHost); cudaMemcpy(&num_elts, scan_data + power_two_len - 1, sizeof(int), cudaMemcpyDeviceToHost); + int last_bool; + cudaMemcpy(&last_bool, bools + power_two_len - 1, sizeof(int), cudaMemcpyDeviceToHost); + if (last_bool == 1) num_elts++; + cudaFree(bools); cudaFree(in_data); cudaFree(out_data); diff --git a/stream_compaction/naive.cu b/stream_compaction/naive.cu index 888b672..884e083 100644 --- a/stream_compaction/naive.cu +++ b/stream_compaction/naive.cu @@ -11,14 +11,13 @@ namespace StreamCompaction { static PerformanceTimer timer; return timer; } - // TODO: __global__ __global__ void kernScan(int n, int d, int* odata, const int* idata) { int k = (blockDim.x * blockIdx.x) + threadIdx.x; - if (k > n) { + if (k >= n) { return; } - int pow_res = pow(2, d - 1); + int pow_res = (1 << d - 1); if (k >= pow_res) { int idx = k - pow_res; odata[k] = idata[idx] + idata[k]; @@ -30,7 +29,7 @@ namespace StreamCompaction { __global__ void kernMakeScanExclusive(int n, int* odata, int* idata) { int k = (blockDim.x * blockIdx.x) + threadIdx.x; - if (k > n) { + if (k >= n) { return; } odata[k] = k == 0 ? 0 : idata[k - 1]; @@ -46,7 +45,7 @@ namespace StreamCompaction { cudaMalloc((void**)&data_a, sizeof(int) * n); cudaMalloc((void**)&data_b, sizeof(int) * n); - cudaMemcpy(data_b, idata, sizeof(int) * n, cudaMemcpyHostToDevice); + cudaMemcpy(data_a, idata, sizeof(int) * n, cudaMemcpyHostToDevice); timer().startGpuTimer(); @@ -54,31 +53,20 @@ namespace StreamCompaction { int blockSize = 128; dim3 blockDim((n + blockSize - 1) / blockSize); - bool a_has_output = true; for (int d = 1; d <= log; d++) { // k = n? does not seem necessary, can prob find a log val that we can limit k to. then do [k, n] - kernScan << > > (n, d, data_a, data_b); + kernScan << > > (n, d, data_b, data_a); int* temp = data_a; data_a = data_b; data_b = temp; - a_has_output = !a_has_output; } - int *out_arr, *in_arr; - if (a_has_output) { - out_arr = data_a; - in_arr = data_b; - } - else { - out_arr = data_b; - in_arr = data_a; - } - kernMakeScanExclusive << > > (n, out_arr, in_arr); + kernMakeScanExclusive << > > (n, data_b, data_a); timer().endGpuTimer(); - cudaMemcpy(odata, out_arr, sizeof(int) * n, cudaMemcpyDeviceToHost); + cudaMemcpy(odata, data_b, sizeof(int) * n, cudaMemcpyDeviceToHost); cudaFree(data_a); cudaFree(data_b); From af98f562688700847e2b3a6e50b1e41c7f618461 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 17 Sep 2024 11:53:58 -0400 Subject: [PATCH 4/6] More ReADME updates --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 95fa850..22d7724 100644 --- a/README.md +++ b/README.md @@ -22,18 +22,22 @@ Stream compaction is the process of taking an array and removing unwanted elemen This is a much less intuitive approach. The algorithm involves 2 phases, the upsweep and the downsweep. The upsweep is the same as the parallel reduction from method 3, except the algorithm occurs "in place" on the input data. Then, by treating the array as a tree and doing some clever summation, the amount of work can be reduced by filtering the sums down the "tree". This is done by setting the "root" -- the last element -- to zero, and then at each pass, giving each left child the parent's value, and setting the right child to the sum of the previous left child’s value and the parent's value. The upsweep has O(n) adds and the downsweep has O(n) adds and O(n) swaps, which reduces the complexity from method 3. 5. A wrapper for thrust's implementation of stream compaction for the sake of performance comparison. +# Sample Output + ## Performance Analysis # Charts The following is a chart displaying how running time of the numerous methods changes with input size in the scan algorithm. -![](img/scan_graph.jpg) +![](img/scan_graph.png) The following is a chart displaying how running time of the numerous methods changes with input size in the compaction algorithm. -![](img/compaction_graph.jpg) +![](img/compaction_graph.png) # Observations Observations on power-of-two length. In scan the non-power of two work efficient algorithm had a larger difference in performance over the power of two input. This is likely because the overhead of padding zeroes increases as size increases. The same is not true of the compaction algorithms, likely because the main bottleneck of that algorithm is the global memory reads, which are present even if the input is a power of 2. + +# Investigation of Thrust using NSight Compute \ No newline at end of file From b477e5d7bfeec84ba2d67f9c7806bb37251de1c7 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 17 Sep 2024 22:33:34 -0400 Subject: [PATCH 5/6] Updated graph and readme --- README.md | 75 +++++++++++++++++++++++++++++++++++++++--- img/nsight_thrust.png | Bin 0 -> 55703 bytes img/scan_graph.png | Bin 35965 -> 35725 bytes src/main.cpp | 2 +- 4 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 img/nsight_thrust.png diff --git a/README.md b/README.md index 22d7724..a524d88 100644 --- a/README.md +++ b/README.md @@ -18,14 +18,73 @@ Stream compaction is the process of taking an array and removing unwanted elemen 3. Naive compaction on the GPU. The following figure shows what the approach looks like: ![](img/figure-39-2.jpg) By adding in parallel and only having a logarithmic number of iterations, this algorithm reduces the overall complexity to O(logn). But, there are O(nlogn) adds since in the worst case there are O(n) adds per iteration. The work efficient solutions seeks to reduce this factor. -4. Work efficient compaction on the GPU. The following figure shows what the approach looks like: ![](img/figure-39-4.jpg) -This is a much less intuitive approach. The algorithm involves 2 phases, the upsweep and the downsweep. The upsweep is the same as the parallel reduction from method 3, except the algorithm occurs "in place" on the input data. Then, by treating the array as a tree and doing some clever summation, the amount of work can be reduced by filtering the sums down the "tree". This is done by setting the "root" -- the last element -- to zero, and then at each pass, giving each left child the parent's value, and setting the right child to the sum of the previous left child’s value and the parent's value. The upsweep has O(n) adds and the downsweep has O(n) adds and O(n) swaps, which reduces the complexity from method 3. +4. Work efficient compaction on the GPU. The following figure shows what the latter stage of the approach looks like: ![](img/figure-39-4.jpg) +This is a much less intuitive approach. The algorithm involves 2 phases, the upsweep and the downsweep, pictured above. The upsweep is the same as the parallel reduction from method 3, except the algorithm occurs "in place" on the input data. Then, by treating the array as a tree and doing some clever summation, the amount of work can be reduced by filtering the sums down the "tree". This is done by setting the "root" -- the last element -- to zero, and then at each pass, giving each left child the parent's value, and setting the right child to the sum of the previous left child’s value and the parent's value. The upsweep has O(n) adds and the downsweep has O(n) adds and O(n) swaps, which reduces the complexity from method 3. 5. A wrapper for thrust's implementation of stream compaction for the sake of performance comparison. # Sample Output +Run with 2^18 elements, this is what a sample program output looks like: + +``` +**************** +** SCAN TESTS ** +**************** + [ 46 5 33 20 5 42 38 23 28 29 9 43 18 ... 43 0 ] +==== cpu scan, power-of-two ==== + elapsed time: 0.0677ms (std::chrono Measured) + [ 0 46 51 84 104 109 151 189 212 240 269 278 321 ... 6416721 6416764 ] +==== cpu scan, non-power-of-two ==== + elapsed time: 0.063ms (std::chrono Measured) + [ 0 46 51 84 104 109 151 189 212 240 269 278 321 ... 6416683 6416688 ] + passed +==== naive scan, power-of-two ==== + elapsed time: 7.26304ms (CUDA Measured) + passed +==== naive scan, non-power-of-two ==== + elapsed time: 0.243776ms (CUDA Measured) + passed +==== work-efficient scan, power-of-two ==== + elapsed time: 0.407616ms (CUDA Measured) + passed +==== work-efficient scan, non-power-of-two ==== + elapsed time: 0.318944ms (CUDA Measured) + passed +==== thrust scan, power-of-two ==== + elapsed time: 0.083872ms (CUDA Measured) + passed +==== thrust scan, non-power-of-two ==== + elapsed time: 0.03472ms (CUDA Measured) + passed + +***************************** +** STREAM COMPACTION TESTS ** +***************************** + [ 0 1 1 2 1 2 0 1 0 3 3 1 2 ... 1 0 ] +==== cpu compact without scan, power-of-two ==== + elapsed time: 0.349ms (std::chrono Measured) + [ 1 1 2 1 2 1 3 3 1 2 3 2 3 ... 2 1 ] + passed +==== cpu compact without scan, non-power-of-two ==== + elapsed time: 0.3535ms (std::chrono Measured) + [ 1 1 2 1 2 1 3 3 1 2 3 2 3 ... 3 1 ] + passed +==== cpu compact with scan ==== + elapsed time: 0.7794ms (std::chrono Measured) + [ 1 1 2 1 2 1 3 3 1 2 3 2 3 ... 2 1 ] + passed +==== work-efficient compact, power-of-two ==== + elapsed time: 7.19795ms (CUDA Measured) + passed +==== work-efficient compact, non-power-of-two ==== + elapsed time: 0.545376ms (CUDA Measured) + passed +``` + ## Performance Analysis +The following data was collected using a block size of 128 running in release mode and utilizing cudaTimers and std::chrono to gather timing information. Memory swapping between the CPU and GPU was excluded where possible to focus the running time analysis on the algorithm. The size of 128 blocks was chosen from many tested as on my GPU it saw the best performance. + # Charts The following is a chart displaying how running time of the numerous methods changes with input size in the scan algorithm. @@ -38,6 +97,14 @@ The following is a chart displaying how running time of the numerous methods cha # Observations -Observations on power-of-two length. In scan the non-power of two work efficient algorithm had a larger difference in performance over the power of two input. This is likely because the overhead of padding zeroes increases as size increases. The same is not true of the compaction algorithms, likely because the main bottleneck of that algorithm is the global memory reads, which are present even if the input is a power of 2. +In scan, the CPU dominated in performance over my implementations, but thrust proved to be the fastest at large array sizes, increasing much slower than other approaches. The CPU is marginally faster than thrust at small array sizes, because the parallelism is not fast enough to offset the heavier cost of transferring memory to and from the GPU. The thrust algorithm's supremacy shows that true harnessing of the GPU takes more than simply implementing an algorithm, but also smart usage of shared memory, data prefetching, and other strategies to utilize the parallel hardware. See more about the thrust algorithm at the bottom of the readme. + +In scan, there is interesting behavior between the power of two and non power of two naive GPU algorithms. The non-power of two naive algorithm had an increasing difference in performance over the power of two input the larger the input became. This is likely because the overhead of padding zeroes increases as size increases. The same is not true of the compaction algorithms, likely because the main bottleneck of that algorithm is the global memory reads, which are present even if the input is a power of two. This was not present in the work efficient algorithm, which is so tight between the power of two and non power of two that the power of two line is not visible. + +# Investigation of Thrust using NSight + +The following is an image of the report from NSight. + +![](img/nsight_thrust.png) -# Investigation of Thrust using NSight Compute \ No newline at end of file +The green and red blocks are read and write from memory respectively. It appears they only happen once at the beginning and end of each test, since this image was taken from two consecutive thrust tests. That leads me to believe that the memory is loaded in to shared memory, and clever caching is used to avoid large amounts of usage from global memory, which is a large bottleneck in GPU programming. \ No newline at end of file diff --git a/img/nsight_thrust.png b/img/nsight_thrust.png new file mode 100644 index 0000000000000000000000000000000000000000..7fab80cda03d69424b865ca985a87070d4617c4d GIT binary patch literal 55703 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
mkcwWAhR)nD)UAZNpUY^ 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%0DMu>WZm z{*(LsPuBSVzr1EFgSvC~bP}#(e(G>h*!3{IYWBGT7!v{)CBeLIO_p=#Og({~ z5N8jP6^Tn4%HB2)JD%r*cN z4}1Y;@19}KJbW!YyJ#op>wSAqTNcfP1Vj5(;&ZmjgXYMyWieNl2AZQI3r4JOieNWG zaczEXkTRIEk(hmhWiU&6H>cTAm&+#Is>U5=18ue!<%#F7q?S+qPH@em)W7s>pjT-&2)qA7HGg@a1KuvJGHk? z6}J)h#1<&lj@>R~#9Mxxr zKgm%f@8Z_uK3th}I^M9Vfwi>-oLh$52j4Ma_vLQNW4lxdzP$$z7aUn;w;z=^p4$E? z_bGPl4egWUPKSSG@igTaaCpMOBfqsbRa(3~ltKC|wo(cGb4^LMs4(CF&u-4roeZ;> ze(HeB3*&xnF75xQITcYTvFE52KAJDt%XxpS8ewSpSV?BEeY8{70>1m`jv_b7b=W_wp0YYe zHbq25qQ*!NM&JzAjE7^f!^VY59MR+vv60-TcNejXy*O?MHAK;77^Te!;!&oOz+LY< zt<(ap{+57eoUTCttf;U7LcR_$usA%tAScuj*& zi~4I8FP_uJL3{@}dUhM9AuH^jhF$`6s~4`zij{;v(ppv`6PWb)i%SY1WtpPTn}}#$ zvHo}&3)%<^CmDEu@zznHYdvALUkdZnU|I4!Y6K0*IUh{3EP^W~YrZX}f@$jdrSUYM zvRFh0yV{BctV*OM|3L6tU>{HzEYQyuzlw%d>Na&c)Qpe{&9Z0tklR{H_hGi~?glr~$&tA(U27A%*J3nLjB zMia=Aiznd9do6=};Aw1mxq99*89U+gAYP|8eQ?mcO3b?FvQJ(4Fg8IQyOZrW-xTLG zwKEYBUFV4%gIYOR_;%e>M&h7yLtyXud9rjtJZr1g(#!d4vr%V-E4RNO5QVMNzfZ+f znpllfK#M80n>1{$CVJkwUOZG%@YS6bS6-U|d*9A6{60f!cP4+GMdX#~sSv70;i3>XC?-P85E`&3_^LasFN&5hej3n z#`n`0X8U4AP2qOVCiX2v5gH5vPlPIRmMv8CG))A5W^Y?j*?QGuhMF2;SLH>*vaS+LU{|OF z->X)_$Nrz&4;Nwt-B?b0NWo6T8u%qj1bl`3kSi&y;xK4-C7+5m4X;vt?Opp!6?A)R;OYUIk}5h7x6PyM+Y2R22oCt6|eXK$gYIP_za&1~OpaNKGL z3^914imm1oWT;S=n1@jcCCCWyfwd}4`!lRdt~Ln$aJU-0oI0dc?Brmg0E0UPdQg8T zF#VR|ZKO>Q-6L8J9J|DP77gX=jmN#sAT^#1`+>)zAw1vaqIB6*bzMtX)O%Cd09;e3 z{%ot4lbo9py6S=M<5IsbX}3Zbb(p=RGxRKYM?hGMF|0_pNxVr*mgt3lQO4t*LVG0x z3wY%N3Fyw7**;*BngO*JykAbL*FFCH8OH;6)(i(8QO7 zZmN$LsGSoSb$uR?B*;9BZ-NBZ{~07A|x< za@uh6-q^dWXc@!w%Z{x-do_~bvtRRxZ}Qc_fdVF+m&}4;ksNtob>xTqPTIS6LvS~q zjh5X6YpV^6Z_HLYpb^+ubWiJV$KaB~VxzOarjv9Rj~J{v z;FIUs>pz69uno2<=7}>-2mB9Sz<)E|X3k?j}9WeasKB`*#o?2j?9Yx&DV# zXAib}*h3V>x0dLPE!xJ(%lp|~Me(GXw`8I9Z#pGt^*@rGuPv?)qZF~ZYTQ~9r2D&XHyoEYHZW@2R^z+yPRb$zQ-y4yD@$pAQW zBtl2FST+doFG}z+P6<`K!`?^0&j#8_K>i#^O2yj_C>vS6a{8I2%Wa#hQs>5#cvq~` zEzxdt>*ECZ!B!eFi5;{-hzHvEd-UM{UNEPxh?4%(d-_+-EqMEXE9cUq-&L`kiG?6V zjj_~?zsJ8$VD**33a4S8vVY&j!IpW!K9_zSe@bPUnA7RFDIk8mSS;}8gsrLZn)XxN zy8eq;NU5@cL`qfFm?}OHE7c*4`0xQFyIHp1sG0w63H)O9qK6W;1lURMO{MI&hDCgzu)N?eHqVHkQsw*-&3#9Zsm2;N!H*ce z+h#I&i2goS;Ps6udbvM>Bc^kKAt?zqAMXUa(C@@(s2bqay)v;>O#JuaJ&EUgeab;@ zkfEhz*I~aNfQO7e<%laX{alJ1DJa(A;Wxq4PB@5@RT|LMC6L`=3ge{Ys(M)D+D`;e ztEta&7X((`>X@8m8QPAC1WFSbt`ibEog*$+l2ABCm#R$Fzl|UFOJRhyYMZE5D@eQWAVxVynX}k2ZE+RAnwm0B;Fs=R4 zd8fbB55)%~oF(-Qmexvdcc}i;T^#6pdMI9nmYm2jD6xx;!xg1W5VyG{kXOm6c;j)a z=2{m$-J^LoeoN&8U12WcNR3_mc_^n@KW%aX&?>POo>4IeS{wtA`xsYS6yd*2?!ChaDZ->iOKZwWNXQ@x_$)0P`FXun zd(D}AZTHBCWnf-H%#crS5}3k@hGMA0)RD?Ia*RBJ7?p;;%vqmIA|~T?CvD-+ywH&T zh9i}i0})i#LDF>(?kIX&!?(P1liLG_vMS?tm*=mAzPAZcDRkWbStPYeG&e6i z+a@`GTKmxHOaLezyR;rY8ix$=g=e%>zXE zq7m`vi45_cLRfi+PPL3C4T8vMdpB5>(%9ZaDh+oG9c9g4m|03jSybi_;5p@JR7HJ5 z<%~wvu>;3*G@b4+*F$brhR^+V--UI|19aHSY42XfK2Qc;^<%iRTgf^*c~R3SR0IbB>H&$yX9@K zASt6K1R}7ZDkjk}L8h6&6#+p;z}Ztq@Nicv+wa8DAT28yyWRzTAAC3ur7kS=tKo2D z#>@QI+Bg7fBj07;#&M`>f`LNE;iI~OdqehcHSKL~$CtT$P0*NO^9)x4eR!RDd&|3^ z9=Ros*GR}tAVu8u$Q&P;AO9716>Fc|e^qQ0I43rG-ZY+=@__pMvV8hz#T=#nG7x~(trf&M(VFHo1wQC~)bFrT%jQHDb zP^EgY;;bhko}#)VXxC48+rlVii0DTuucVStQFKmh#P?3p+IoF}gW$vF%|<*B7w9p; zvc{oCd(z|QCY~Q@$_#ZTGxAj^SKmPv%IxO0)zhG93(l4-SI5I?)|1R>9Gl}n1lyc$ z*{O1N`hYWVcC%85XYnuUj)OS*50~R+mLGKwDH3WWIaGZ#%Q@F%YG{*RE@xd+9I!%3 zY+xSQUJGK4SjDbh&EcR6+nFojR5(0Eu1bZ2Kl3e{7E&y>c0Yi~YS+e{&Ks|4yd?>Vkh8p5k|yqAd~_Wl93|=hV!GiAV&Jj90av& z0-Qt+r)H+MvXQHK8XMIY4nAvIa$qa>nJ_FMZG*FQ>vZNjCRNRrllIbfg<^_DncD-( zkqph(jZXtBq4Hwt?x#ENA<#@h;LS1Ok6R{pdX$Q5=B%dvYfF{_JCRi`FjaHMq4dur z;F$0OWSBf0TSP)6kMPW?A8kTh>5h#+^_&(r0e__T{_DB*P3#mN{C$D{r6iySx!s?; zFT(bpG9~}bAT{CoH;WNb^Uo9hU-e)}X}y{SRG| ze;Kscb7JrHAPa_4Z-J3!Eo0TSod10xoSd02zO`VXMBL4N^|4*hl_SFAbY0-oT02!36(R2d+kNKYcx;*&#jyMrVJfB|j*h}*vp7PWJxni3$_>uzg4I*JuyD$HBKd}}HS zq|TYe0yO`Xd=Diymxw!MK7Mwbwzh8kTj>`!qtCt!sZlDCR8)3@*b*!u2aFGL^vg@p zCV6)D!OvrETjPG7W|qn;>a^kL9slN0qz#kdS*UhSfDT>6|>et0)jEkD{XKrer$w9ccN81`mdTst0Ae_Z(pldR4JKMuc z?SNVQL&7xGg%c_!VG^dvRLhQ05!6y?U6DN`B}MpYVjSs^!< zYF5pIKHhJQGMLL0ExOQe^o${7IBvue$WU|65k7EkGd^c*P<5dP%So%WYkZ905v;7y ze<>6iB^w7=-=J>VpRTa*fu1~dl1a1MYn0?{Stk6*uV>41_3gVc#Md;lLb!!W8#AtSbsE6Xf-fx=__QBW zbh#$|gsVp!2MS0r3;t(|Ep5{|(<2`vwyo@j?)S|VP!!)7y1h$mymW4`wq*J3TCz!-OVt4qQ}oIlv8zUqM(5#B>u*0)$Dlg`0J6T1K!rw zPmQCTp7t@=@po0c$XX4ye{S8$l%thA_Mpm^SDW@UE{FZ%EDyk!ma15N%e+L95Kc8Z zR}l3<;0`t9*$c>XqIP0-RGEDbQ7N%(tHT@DYi~Z8t1O$=1NCv$=2vINFK2|Sq7Z0% z)o|qv6&8yVMAfIFb~WZqW%DqNxf`jst0wu){tPY-%N@{=>`6Hl*T7K1>vLr&tq2+O zfxSXyU!JD!*Maxv43EqrDjA5QSniF!S80nCfF=Bif#Z1Wf?yHePVkEuwg3VKmH1Mb zsAlinAXKcxFP~lDyZVTQ$^H_^9K*igad7kbSZFBRSqr`CF!nYoas-hZ6xi`@XQIC!D{5lut>SekhX(@2?=60;8NQI>UoGYLf8#kQh zl@6Ynu(f41&fA>nw~I}w;<(l8M&w6s%<_?r*dyBNt#-7}ubFF1e&x6Jos*Rw&j01P zJsbl8q{n}+{^g?Q(DzQxD-qC`QTn*?dpYQ?IfFep?s;>t;?wt{^Y~+i=jVIUn&B<4 zGo!IKC+%$%FMb}z$d%1WG9B!9J9~R+`;RY7*pvB~1)1~i;hNQ~>PHsx=H^lSAYO>a zcxdDa>hSiTj(zb5EX;}h6AKfoL|%`ife36eC3_`zoiIzb;`4$fS!PASD^Vr6Op}at zROD+`I7T=ucvjmFXacBev??TM%quzu^z&hM&J`;FUKRw`K_JR3Gw}6EkH>|Vd$qWsK(>$`90^WC)8QJj+38~x&7fBaSPK3CvM?E z*^sbauzeiBjky>ton%UX;-&#h(OI@lZ_i^`_<^xRrN1^efoeEw+Q+*DRfY(=r%Q0v z>=zWh6}U6I@M?+06|C{lx&4Nsn!XrE^xuK~cIno2V$%G88JJ`CKvmW(h%oJPzWi)3 z9;85C=%yS}G#vO^U1#2`!rC}tMYcP3t1CzlP8MrUwA9WrrN%W#Uo8K30Vx=d{E}GTlI;tbjj8sJoe?WO*s7aq=$LQ8uJQEO) z{r99(rPF&`!#tJWzpT+vYFKw)mh3;S=cX41>?0S`kdc?3qtz5Qh=EfJYFf>y$lNQE#&f0SFnR!5eW|V%8P9}s z8E8piiIt*9|DgJMFt*CJh_0m@_@*tBA6k&4RT+^zU~4^xKid4?3ZtYCg-=9t(RBTY-o>*?P1SzJT3rFPE#GS3iJQWjny#kJV+5wkG-$?}m|Y z-Q{M{ROVUvQ5sqR5md)AeKI@7X-+k$dt6?r+hl^1!R`iGR{o9yk3<;6&4h+lJ|qvr zeSn`s+bQK_@vJqv{PaWEA8M56d-W4{+JE+kwERHW1=~3w22m6I!i<9Neu>6wbQC}U z#E!k@!EInc3_W7oAK{REfwds|uogt~q~R(5p(A+~1c}IT96)m9zdk=00w}D9<=b&| zg7Sd5xH+5P;sdT_LI4mfBG!K!)L+P?2i^}*QWC_Pztq-$#Ihi;jba0lg{3~dTAi~f6Rq6G z8voSIjk}N1UcTSc{E-Ox<`}^R5>oEf1pDtfAjwvn-?=*MRI{u;#(XoG45^$rqWFJ` z`_8B)yJl@Hz@rG*04V{Hrc~)jRS`j|BE2gDQUX##FJgJ<2nM8s^cre_Bs3|ZNEZSG z$OEBB36b96y94^Z=e*zfew<%l)^aVE-fizad-lvV*UUH!MoVl!Lodus%HP7GYNCv; z4XEK13&egI{jp60p8}~VKXJDef!e6QTOY*e4g%fEK=kgbW^7}x$@!bDlzp-b0!=-1 zypfjYDY`(pTophmZmw8H#?OB`^;sp-Xl{1qIbLG(1Jb>hDDu74^rQPHf35#$x(#gt zI#d0Wpr#7tlFxY)vc2?+vPZR7ICWRre4ckHy&<%f5@<43fhwyrk=a)%4<>~JagF7o z(`_W27(Uyl$4E1d>QJW{X8$X3)T~A`7FjS6od&%oxT_hin!Gs{(s}%0R-1+=Z-9p@*Z8ebeUq*iE62G`Y3J}!#+X;K$ z-f4R$AI&RS1~2~EGmV2+9*kj~8cZEgtB>yix&DR&x9^OWc2K`wma+KgDe~3w4gj-< zTWw=&;Q&ieOJfiSW+wkYeZHjS(^RtaK$J^dR>12T7az3+)0|Z1TY0m`FUIoI-Z7t7 z?;4?(X}21CLcW=E$OvEb)p*(^%`K!NE+!88Yo}n{O>6LCqK!xGnS6jLO;d7nFvs*Q zV@OBT9i8bzL}-w%kV+ycm5%*O{@H-0m7;xgcWuk};gZ%Fi??L2*_rFVInR28F=v8e zMuf+n9*UUN@K|+n`rr3zyrR7Ut7Kx@ieC@O3&etgY zQR#+j7Wz7v5@vW!Q)c-CHlcG`?uMvN)9Yaj=S`|RvC zc(mQ%6!!xtDl*2?${JPI7@0&^AP+h)y~Ti_reTbdP#t2{14R6+V{5w3tm$=_`Lv}7V<{qR+F2+I>f6vUWYf^m zTOA&}KM_9ow}tOPpbMRLb9wWtwn)dwgcn8&^{_7>lj6@hbTGkt^z(a8y5=aAwfEFQ z!41*?m(Ceq(NyM8xAN(aV!7`wEvQnMCm5x$nXk1V7`+4=iLe*mdUclF?51#)s*ZYF zT0W%jk?Jtl!qUiXY^%$4R~G4;g$yI157GvNox&_%aBJKynl%Z^(r%XdzEho9eos#t zyj${x$~tBNyi%~I)o0MeDN=&c?_z`^;Hs_52gO0cVRbfLd7ph@x7eM0Eq#hczgbfmE>Bs~{5k0Y z7u_AA;Tb5$cNz>x$Lhu=V8QO$w59XA88h`;IWamTa|Nyx7FsxcH$L`ED863wP`N8y zhvs@4v=WPd7>};Euu()vdvNs#3WZaeN`I)59Cn*hyH%#s-wns4R1H3^;IW+ zvY~~Mn*_isnq4e}#dQfajPvJbHhziYRvW&!?3v sTkxXvjL-`%G#J>ZaPeBLPSH z=^2S@<7;nq6^+lCCJ!s>V7j@Qit+@L)JXYC#~To3!hA%(;qsCAs_=W&dfeU@*t)xc zxn8O6;p|)9U8G!OkH{usPmn@J6sx>hCsye`GOo5cZ8dp?$+!U<+^^K}K#(SN-%_Aw$nqB3! zXVADGC8y;rv7v~5yS5L-w+e@-HXc!YJomuHytLqxpJ@DrWoW$YwYwcVX-3nQ7vnt} z+<{zEV~Idk<>MNmr$3>qG0Xj)zCoC#8>2NrCG~aNhUXBR+w~ileXx^dk5+9O;_-5Y zKWra=bUTN-dC;fRF5bCxV!V;QE?pYLkR^u?7oDji`oWR|j&`k|SbCa9cKS=kR*0qB zzU2TaJa%iS74z-@hx!l8X6_!l?(n~p-q=LhGIDb+G+wIQ_Vbr=&!D((qNEx=O6poLlmxYC7z*n38o*m;ieD z?#*yp^>s-JbYX_JRWeJofG`@;+*>6I98yjACQd~gxj3ErN_fBStkCnxd=`7u%^8)Sb+NO%4SMKk)7d$H&85dS0f`$QZTnL+V zXZUsGqX_03sz9JI2)X<-kLGeK&F%Mj<0+29Kbcr$!~h%1?7lRResrE)S(5UtQf)}k z!<*85NAGXWy+9Vh(9GU$xeIka5Ub1PVcCv0ly?@b^-p5QseG8k ztM97U;$um9jA+e<&9e~Ih|#D?ulNPc>dTM1B2}HHYU(WXRPH09K?@WKsP$!c{l6~U z-tMaD5CbA2^ox*f1Y<ApIK8(q;E7fiNC0nje!hlG05dWOZ51-r1to`bk&TLFqUA@_M=f4Ia|KCCt_d$6jX1d%N z7mvOhXVKi}_`kXlY+V0+XPt;jzvLDsV!qB+yw zy)%oWzxvSetbNx7k#C$y#mwePyqB@jDu<@H>l{sVqjAyR&tivp^{$2~tSMKq*Tg8f z3~kQlGjFKzf)mqr*||8))^F~bX+sFyC9kgNZ9Q~R`a9$9=Z6>AUl5Z;=fC&#qO{sBxk`ViXrVy??0Wh3QQYRPgw62_Ovia3=8QFoJ0 z4lRpp&t6*p%Rs%mh=hcM4QG+!l-}IUb=QYupF-vbdCsImqZ;;;-S)Bre7I7|#n$k? z^IGOd)66u z^4MRCIY>(~`d1wY8UHE1)qe=vk1LLq5HoWyw6YV5-$!Q#Xdw=CptFv;C4u%K`rIz5 zmGY6&x|-#Gw;lp6>`f`$_^CV{M*F>lt8BOAdD&sX@&jI69Br!x9-kaky|{7vs52bz0K5p4kJ5LcVw|#w~26j*1SDL{;jwfXTtU4 za9GE5C+Q5*2i6fka4W7J$R!0 z7{5a`TCQobIX_DX_dM!wT4FjWwPHbiZQyLFwCv{W&ah6)ToX54!O+d^L#X5XLcuUe zuJ`%M^;ZU=<%C47)l9asg+)cC zg)&o=qd{JR{&BC6%=?Pywvz?4j|apBN__8x-p;utSi2R)z-Xq~+Dkt`y?S=Tbi8K- z?y8G;7CGWOh<x?R&+%BU zo94ds8MJ$G@)kWAVA}bxROTT(QIAYq*3&Q%qDb}0F}C^QcsNSfBJIa6>I+3lg88*l_x(TfQWdBw z@CRs0njD~=mApW`3cCcarJo<_)nZQ5_bdcRi{~P@8KLrZs5=;=%UbPbSk&O*+VaEA zG;q)4V7Yc}W^Wsk(KX`>+HRYyJQ zJHSw~X!^7)xUD z#D&;Xy^=5tRn1NSc%7|4$I_RtZsi}I2^^L`T5%m%h(97g-8u)_qt;Ut{QP`ZCW@!+ zPDbuM^%LQ~umNZs(0?j3UfYbt*DOaH`ipI4B;F~2>aAQIcsTtY))I{LKzHP$@!zRN zf7c>5IE#=m3+Eg`9!};d*d-CA>9DX))*s%BDq8#PP*_YLdv>#S5<@f_7h#^ z?QaitVZjox_=6k#Yx3ROt1(Fp@;2%}thb#G?dRJuWvh`jvrhAo)P+d=WZwjdl1|px znTf<(#hho|U%y}4)8W(EE0BjB2NVrfvNbqLK3;C6JWPQeW0v+kIh>gCx;}Cs1YJ?; zT0@xgiI%fi(berALRy8DKZ8!A=Vkre$jF7LX?_@n^#r5cBkHg zRbgRoZ_3L_qzR4SIMWMh`L8K^#K+@6gQLxcDNfHbA~D8s^|>gvCwwDlI6vkn=fOb^ zB2c2NW!t0xRjf2$|B0(!D@^vdk+KVY%;9W8N6H=~Bim?6{L8js|5!G$rDrrVJ6@+? zHshIg5FB#w!vRT*tl{)}xj4D=GSh-P|4X5t*05u(m+PL})i0H7^6ohSzZ4fXc6k~m zIMw|Gdt?nSR7lYFz#P>Jc;>;!rqEuEt^G3YAk4-qjT*=dbL$I>pxCI&i*-?LGbpkW z(CEIzuLpl$>d*=s{%PT)qSK9o>+7I@( zmsTeuIz*pX2%Op}fo2BR*a@_nM-8j6D23}V)B)C^LpzcBTx_YO8AAp`0Ka@9WfkaM zbVxljTfv9N1pNe$p9S0cXUnWDVfDWVJ7&Y(zdm>%%j*_bMjH!Xl)8y&^03df$xP>L zR1tLA9V69Z$nu8_%C!74ug-z_8{|#<~CDQE+l=dBoI(z@{9qH8u>5X2yrwCpkHNW%_2iALKR$jFA7Y+Jc~I%9n>I z$5%pOo9l2}iKnQS7DpqgyJh**?1dSQyPn^ftwb6=*eN0+tM6RMP|#jTt;s1s;y2?q zaoz>N!v4t0N%CcTlmscJ3YiH=GZf>@JV{SEJP+X%Yhg_ImxYuxV0~3_x;+ zi;Hs;dd)orQxDjVAqR^J{)qw$^#kj+3r5a;I=cDlYP>Y_Iyxnnm4c><5*J$)Y!yD+ z3lJA2sDzo{1u0Fs;omT^iZ91V5Ur&y^icAKjcHS#*-uLDdg*8DjeeAF3575DTwZDwebK$%|Gpalz~HWUXh z{d4+}2I1m#1KdYT^T({m2klKeyQ9ZK#sj89zidNv3h{zI%IKyS*hKOyjY5W`LPwux zKkpG;g~IF|Re5h1lRtdETEVdPE3ZbxOY{9)R1P1uFY=&D35^(a6;C~$su&%wSgjCi zz};}N^BA`)2w%5f=#CdtFUQE&v~5|% z1k?wVmKoMp9VwB9twu0s{W1+?7Wickyq6hQ)iiI7ccj<9*aOwS)k9?Uf_F{ZFQF+N zGmPjC;a!7w__OPo6=EYYeVk;sUduoWCK|MiI|^fsDR3uC+W57oBU)k=86UuWytkvc z8XSx3h~qEIT`37~GQ`j@L_G0%1(~v6j}~QYcF9LR5nNHN+N~+5jolWT+){Hq@@|4l zUevC*IGXQcSw1vU7g2CAZO_G*ufqr_Cdk8|(lwpfP;@Zz&o1SP1As!cj_01fwzJAw zaV&c)c0T^)_qOiU$$ib%N#pqPP>JW%KtOXq$vtB)qsI0?$G0*svFb_mn8Ft~FBWH) zwb#<%qMCv?-Xe_i9{GGxUPF8bSK208Ejc9zZL86y4O&UhO-~8tb!EUCFvR6ENHTRv#Rv%PU=CeQ{^Spo+C?%Thu{gdE5VfO=Ksar3w4KZM}kpN()6x=Q%&A(l@7~}0)v7YgHxnrow#XfAeeV} z)f@S$c1!X^_!EZ1DP@(DEO8!c;A*r0Ups?ynqZ4|R4w(%wCMngwdFo_3yh=0u{8mpzk01u!+4fP$Z;<)!JvKHKI9S4H{+nL1$3 z!?r7*MPRe{E2|DF+%r#k5^7*TRAB*lwidRDN|{N|{$pT<%L|WC+T@rlmrCrKV9SU|C5B$@-mzy_@T`Qb!B4dTqX@ zDs&F4-mHcuPoWT{WH(#i8m2sGHQ|$ld^I8<3Z0+_jr3CSpP6(>#wwjx)j$pwUoc%N z0OcyAfryBkt`hHxJu-q})(hr1TOlfmUY1i`A+;_L&u z3KZP(3bzCSyKLFaG_>=_+@6!1LG22*uXw-GV0VW&_8IgM*gFcg^A$ep=T3MIWCn%9 z>MBWY;AA)FWH)!zOiYPZ#bR#`zQ`=#E*!$OQ!5C^=`UzYQQOTI3DLfm1YAqw``d+H z_Y;lOpXyGw?S+n@q|0aLC17sJ_7XK}{Jce-ip>-g3wmf8jfbs?mZ_A#*4xe(>s{x` zc-eigz>Ib?XwAyG+uVBIy~q8tu2@_Ywo0<6_$t9IDMul#&RX;K*sizCQ1PY*qT$I; z>3}+`q0S+a)n=oRdo@*=D^&RP$+P?3ytSJ5O;G0Al3}0@QPKJNKm@Vaw8#UwW4YSDW~28uN7`2Z8~6j? z`pg;I(U-`l-GwHxH+R>SE%)r9i|ror5DycqP%rUfwPuwa1P>Cf$-68|>l=m`)G#5P z>HWg6WZYM>dScs0>vIQ8NkqFha#{0L>0d?Ua+NZCPR#_5j;lncg^$phvOHnX*=1Ei=LUJIN8JWj;8rKiT6B~4IDesR5eP8WXQUF_T!o~?YBp>*!LpvmJ@!u~9xN>3U5Q)z7fH{s;F2O? z41W8ATIk_oV@qpmZog!8`}uX-!-GTsT#|;EUg92tKHqM8^+No2c-k#KI!?dNcYJWs z06`|F18Tl!Pb)uW=iqqqQ6w*u6Q6oC3vzxU61S2|UUeTPdjeUo-iwK_Os(8s`P=iK z;I~Gks{_R~Rj5LMV~h=?a3d*~HA+CPbfi~3W!cz5sr9X>MEv3%_>Z@zq`=7zr*BaM z*a}_g8_lt!CMnfhXs%KIlW(<;1z;+@^fXx~lheW95^mIZabr$R zuv4^4RtLSUrZmv!xq41!wL7S9ZKBBO|kq zQZ*u@f5ZiL%FB8`)WL9A7$wxO@F6?TZGAgy`#{b@+#s|;639w>3=Dv*=;m2E&&@>- zscGVczQ6C%lUZy&e?ryxHZO}1F{V1EsL)3(Qp8;^OOBu`-}5BVs{n0@I!xwBLoHBYHv;0uTe zp)+8_wO@%L`(#^1nS0wxpWvYuvj#uER07gN|40Qu^w?s6p! zjh56k`&f+rSn68LmPV8#%*!de+nkv2C6Ql?JGav{Aw+I{GQN5XeqsOz4ygmv*C{5) zgdP0H<>nR_yNwL@iqmnG?R_L)+lRJH9o}rP?`wXKD!Lzf-~I{myTZZ4OVq&bJPjxC zI;|&Xxf`>nq$xa2O|pNDnyV8hItfLeXfBH?U`v&*aYA#>eSB%d6c~wq3a_aR8L6=6 zr=X;)KzC~_kJ4GrYOyNZWlnLFi7v7S-f`O|g>?e7&rNAL(=v5qrI(%?4*L5V$LwYl zA&Pvq2Ty#w8$nk2Ud#=|5)$kqX{DB!5ILCJ8Joep zSYTY;O8w-P?3O{S-B?JC!W|4~%(%wyP{yOpLcJ}6XYETB0Q&7)Dwgk7nR1)}!>3@@ zVUDupu|Z4{jj~UzqlBhI&?d97&a`G)Bqt6uUQ@qTV|M(8MG!juPvo+*a``XMHm7Yr2HjhmubDRV7h$N#TKAYy7^~sy` zNN`jkX5;npq$Fc72c-;CgG3nt{^>?|*+`X*L{7?xXtZAWV~0@c2zjT&wzd65KsZPc zpm-Wq z_Fv=2Fbn+zTe_9LovAoHc8iux6RD(G;J$?9DsgK{-uQwF{4CCFDfwZ`L$-~SVh?P! zj{xYZAJLI7I%;C=Ee5xl;G|_4W8_iImg=)!Ai&Q7K9Op5X9XBD@-#eNVg3#C9s5I{ zeTprm@Z`U>k<2G6+E`FoqQl$GBICgicNmQkI2#z+n+!3Nki@0Q?K?;xe(Vy8k}>xc zPRZTxNtH{|BqH?@b{_DppJZyO|ZRM)a|JD%pSokjxIxh1ZJ=kKW|8i z?AIsiH8_i72i=fe%9dJNh&@6{YQq@ZuhRE35WqFJ#uy(byk8P{U9ms3Q^91^xLa@= zW{)vw`9~%BHt6qK4mWxe1p&CtQ9WGBpB&?{P9XXwU35oH8bbY+mziLl!>2(`emQo+ z+3W{~+EejzCE{@Vpegm;!7XYxrdRG?6+D(%)aNx*1dY&c$@01h%sxf8!Qa!^!c%1S z2D!R{wl|!w>{3nWRij=EMpu)B3d}Me;_1Mj1lFfF;9{JTwM5QQyui}5gna6B24QhK zD6QpDUHMy9ig;&FDFuIMpR0v=6I85Lh@!JsT;4a<`Dchk2{Z)FyF`F@DE3b-GQhVw zSDC^;1vk&~RX_H2qL?7razt$8+l+qN;22mLrMcAp}YNQkV?H$X256jG;A z!7?Spj7VwXz=BFq?F4o)$9QW8R4t8Ch_k?BL=E6R%?kJMywlLLEq21 zbi+5CMm}p&HFq!YOg~K>xb7}w?C1a7A+PuKpdA|F$HZ138~-km8uI$?W6d9RFfmpr zgqz(dEFJEfOmuQC%2D2i+|brU|6JiOO{_NO`RbAw6X@iD-TSz$2e0klQjcmoa^vXS z_rW@7ycVw!Xz=mv@m3Y~*auR6aD7aO7FLxd+6-B$<&5Wn(F+gxl7>d z@({Zf?~@%8n9Y+#7;#7!7Befz|NHv}EqY2;XWXpw0t;RC;Va;WIS zTf;#u7S-UKrlwcSnysjpSkdRun|41xAWCeQM?5SfESRvk2Mk5n>HFgUFohjbPa2H& z=%MYTQ&nPTo7R^2)Qk!~^eYPc*OY`-9K7E7wG8hr@irchOGCc38?*aclE>{kpKt81 z(s~)(%&*x8;AgE4^$Jzkr#Er&Yhl=lL-iBku z0C)0veQcxcy#P#Cv5W6g`UHt?iag2djI^WjJ`66%vX0y_+wvgFhBLnC$_H)46W)PCe0{&>PoScIiCVws#rM zeS^8={KHMtTl$LQ@V3kpUFuY9K6lZO$nxYTU6@1(yqnM9;}#A2L+97wVW%Por&wYA zSl;h52R+p7@YW#IbXiWK1nxuAr(jp)3IP{Qo~!Y;CyVJ`ehfb%+GAWVKiR<`J6Ye4 zwsmp}zFiNNaV&iIlNvqMjbzj;_$XuO$Lj4k);Gh-2d`hFdbc$@j{xsRv5ZLuBw3^V z1ux>l-0LTI>B~>g7K=N7*~;i#;EmTb+pUQXEHE8%wzUsVhR}QNpKrn*h1g`BXFU`;0z-PoG#g5|EeiHmpTLH167>i53SY;j zR~|JEy+a^lE~4r2#2#VB=Qd2_D+yy4d+mlC<2f;pS-(pDRbkI3w$3J5nQ7SSfgBni zx;XFKz^tcaQvhAsbr-qOtuJgGGPx=Ng)JQ@vs6s^%r6nfU;b99Zn4oGK@#rCI&cX& zgdD}%s$+clQa@_xN1`BfJ^c<2rV6yQeQ$$&p`X!a%3mF$&pzzIC#!t?W?AFhEJEZ>j?sF!-S|Qw_sknoXjEKF$(Nc8Am5Cdx$P( zkiln6#bI4AE)4OmIN>y(a|+#B|kS@RQE?39LmcN`G#Jhw~B9yk3v<;UQ{ zyUGcXvfRT!dk1|0NDP$t&=y~lG{Y}etapFT@?%dVHbFm6ueskLd3bI@Rw(MLvr?=d zlZKjs3^BEqmuM$NYyaHP9b8d>NwgdDvlX^|MhA{KnvzN`%4HhX(kn^ofJ9dZ&J3qts>vU_988|*1Beydct-T#A?D7@PH;^3z;YfB%FiurhxB?B| z`Y>wOTNE~pVxB@RjlI{EObt5(RjsRQc>Vg^{*Q=g5nB8C^Ki?u!WWY5hr+&Z zB;J6S6#C4#oLGl@E;z(Kt?`m#)q=TKq z>-Ff3dAw@EXTW75m*F)60;Zs_L&H&9R&5#rXvLAs#yeH(I|u?-ac7w%kK9ZkheMZM zdo)~}g(5BYD+;iqoj-HvP^RSsxN3T`8_@*VB6~!_-lmCEs!N0yz+q;c3x}C-Ah)`l z+Dl>)Y;ZcT=9{VfhJG~QiK*4*sg=!3g)l=i}O&!1G;J*#dsjFy211Q=aFrmrgHDqBJl zZ_u>0gHzsl3<@KVSGTAm$A_gIil{Ftv+<>+l#{>z>}B;Lrdcv_YJIW2HBZkZEZ}g-b0ItaBGxHjAA64gl#HSu z@F-FEux*{uRv+|}kGDE`Th*NNpv)|zX&_Px=^m&N#~IC#)6iw-8g zk-?dKHFI9r=HmMSdoij$NVRY58K!zLv#id^BW-M{Tv9=g<(CZgdz;yb?Y5DU zZ|h0R`m+auj^Brlrs_0$>iulLjOdk4 z-d|q{wo%0RA?>3KUD%d+FNqYg&(u#CLi*?`=F3*<^J{S)y?%-gy^hPZ^O@^l-X8!8 zp7rN2jT5Z-=WWeeC!ZxyQ)smZQeQ#f&NBV`mC1l_-zaDMQlXo%G1%*&j2J5=A|~G< z>>N+|KX)%|%mIL=D9OPgw7$m-t&gPd{{yCME6kW)7A~x%T^w9kJ2bkN;tH!8T{mF69p9_waWu~o ze}Lfst5F7yc-d}$`RDHWm6KP(>x8hM4g)B4*8hmk2QwOQ)2vxHb|2EB2B$5-3#ZaHUa1 z4Y8xatCFPmVvs8B9uei>Sg+u-HR`rU8*k1Eso!}it+ky3(6mxm8#V@N9Id%iP5^id zFAxbIGuxPn1zf&{-EOC8pv8q&e3c@XKuWT+nMJOb)hPvwEh8R< zI9w>wxaL#7`mtiz`_k)^T|z=GOCN&6&UK_WS|YzXMWx48y_SAlz1><;=5Vl*m2x9w zMDpfoDB1x3uClSSig2IFh&ob^{-x1yGGK-Gy=v*(3CfE^jRO{#GKHlJ?y%&9`4uP* zASp!-ht1A4I@ew{F$o{GWPAzFsL5EFUcr^-AK=P7)m2Z7qEc(XwY6YOPDuPdw^)R` z5&Ykw%ICQeYNyxf0oR>;Hkr4|e*-NIf+WB{d;cJn0DMq-Y1oMcz(aMuGkXITqq=p) z$$do{fHQ7D@f+>K#adT%3tE#Twy2k?L8%^1)eHkUzezjVN)ercy~{R1dezdx-~ zZ9yQxqavdo>DTd!z_|t!+KZ7W6?!@Ih=o;x^#oCCGy<@gK&#K^s{nWA+Gzq?kst8( zlV2dKkv=cfIuay9Zwz(L!}% z@_PzG>c6o(f7+vJ^EM?dc}Ak|ybNBlVON7hPaYL5&i_MD{K*c$Wnx(|9=k(&17`o} zOfwig;maaVXJ;p@6;hv0s)6Bu0)%T9dx0j0w*j)B&Tj&kiRr?M)bXtwWCn(jCY~=O zP9(BX)wvbYU=PsRyp>Nd&=Yw#s3oSx;nFSpH37)=pBl-_HGyUUlIvE+69Ou6$3xG*Ze)nnr zUov*`-zUKM|Nloe-a1)s6QBRZSg`p31~rLc@GBlm4Vh^bM%4XN%PruCZAtCK0~o5- z?Pw>(!ukEJM{CZ%r(*kXQNJP7Ce@3(et&}K@#9@3Uq77r!1n`meruZ4Ex?-^kir2KdjXxe%}hYMFvhhbrx z?Amj0)MS5H9fH0mBLw}m7jTnr8JDRLYi6%~eV zxufn#w4an<1)@!coN{L*?Un#ogOtBIur@Zd7@KzRN`hfEt{TM!M4sYXHeNfh0f5yL z2>Rp4%ykwwKmpUX)OV;t(9o5LF!h$ydQ)L~MPW1PryyewZ#SPypK-~kZTMit`cQ92 zwbN_aB^O5EV@ZdFnOnco!sqNyZ1ebdv&28_TtV-(4o{%Ok#0Bl`elhU60g@jCq`l$ z$cd6VS|J_@)&s@8Y}E7$eND!m3uEylwDtC#SWqZ4TnTW(6Fj_3uv}{!*FN6zdcXQ- zU{*%1?BH7qYdfxK`z8R{A|_#+;hdjezy6P{?}R|l7i-S8JeF`YzK9Rs6!GbC=^^v2 zh3j4b2K5PDX~XLWLUa3_rt_0EhE{Sbj)m=B=`NlAvggdZ?zuN3TXM=qBsr-0Y z!^+lPy_t_JN}2^bH$U|fxkm?Ofk{G zk~tHM==?$3?By0q+egeYknegOC0hHBSi{87DgL(xCZpF?jZfD)J@;sp?O2#psZAd% zP(7{{fAbINOR+Vs~>~&-(+j!6XS^nYC3Y)j^;^#>Pf zbG32@<0Tzba(D66X?r@-ro6?&$96s@0jT)>gUW#=g7Na6iBp&lY6Op6TACU<^2|Q; z`?JK`lQ*6?s|x8655-w?OMDrah=P%3~J-ubLSJ#qQH zQaRS~@1jYGmxC1e{!_Kmcrp4C;}@MD^;=c2?zl(EK)R$oM;58qI|E4`=9b6D$^_O} zqbMaM3O<>#F~_=K%XcT(PhC{9E-S#|cJ30WZb7&&4a9wig+y;@9dBq2f)+ynpWB32 zDPLDcc0B!SmBI&FeKXheZdrG1Q0EdYtz^L`!hz^-NuIoMQ(l*0M`2AnMcRran2eoa*iIE3vo;ZM(O{NzDq}7u<_X+A~6V}U08Z3VU1~n)C9v9&8d|+smw3N%w zY)IytDr#psY}8~sS=t?V9PpvQMr80XKgz&Ct+3C%vBNa6%*i(vN6K z=?Ty;2?-0{T|+(Rx`%Meuq{%&uXKRUFSoxK{*+{Ja)ln9=_}&Gv&-)M6a2n+RzP2d zR!l#Dt!|7Ib8J-A-$;2p$?E+xV`qZsufJm=1I{2#0tFXd@#qkD?B|PT# zRS6a#`5lmgI>3Ah)Xn-CZ?q}En0Hi>cIa>bYy|tM^(Te;m6u+Z9MyYQi32YP9Lo7A z6PcAF<$P<4h)eUYHrnv@13ni*iu~KR0|mM-b8v77%gLn(oJe3gRMe)YMQ(fi8en{O z$MFjQ#!=DL&4%Fur(CTx&2wXH$2(}C;C!f=@sGga&=pWOj+DG%G0VFrm?$5TC>R;A+htBKkIS32n-7{>BxdUSkfhCEA+&z*^^c=< zg=0~|p47tG+Mm07r;|6!&CNXxv|nFc>k_h21Fi+G&I2mu-+8R8j0YwIAaMa~`9|Jn z8+^rCRoWY=sQ=;7?Z%=?Fqjh+z~>Lt{rZ!Q?1|6uK8`J5l_B8De5#M*R%dPK?kGb-_51y)Diy9yu$kOe|Ze#%6A-I|kZxVKV+kMu;# zOg`K3{XKQ;PF`Kc(b(c&^}2U_*6Y;`g)^knGSA#1{cPew%y4G%UVw% zd0@Ps4lKW7HIt=2X~qgO9N`s?I8rD>{fIs|wE%wMyLY1n*gqYBb_q@a%p_d~C-G=3 ztPB>3t})Rb8BN4{kV&ukiBVay(zmk>J&QSPhd-4UHj176>`CfpLH6k~sm?6P2y|X; zWe`$hkmA!_gK+LDa5Nn6H>92H76Zn(z5V3YaJ51bS0p6+FI)S=gL#GCxxib`pFdv^ z5{m6~wU*ob@!Xb+&=$dbs!;gQ%($I42S;1}$`}c1Tdh>t1i90E1Tu>|0^lcqiu}3) o>V-6?WdG^#p8Q*2YRJy<8Gtnu@D=d}P5P%NN}7*K9$LKpKTgtsAOHXW literal 0 HcmV?d00001 diff --git a/img/scan_graph.png b/img/scan_graph.png index be04f8adb48c4a89f59e2fcc9080d69455d439d3..6aa3701c2ccd958b341687f6f1b580209c99563c 100644 GIT binary patch literal 35725 zcmdRW^;?u(+ciDp&>H(jYLjbcfWp z2fW|se%|jN_`c)t2M-voYsb0IbFFo*JyGhaN<{dy_-JToMECD0XriHE=%b;byW--2 zpUf_JRG^^+qTN@J)%G-9dk^uY7#hFWEC|>(-S@k-4Bj; zlGWUM#e^jKdR-Q)`*u@Z{V}m*Nx;8Q`Qw-RcToSslD!2b)4%#DG#rcS>enGGL5i2Z zMVj9;C%ycwD9!&DAM3b*VfW+1{pg8+ixV^bvPXFIQr_B4A+}+4q74K^tS4BT$Wnlz|gcx|Dx$^hh1uFTIJ?_3OGsI&e$mog0N_@|nTtcy#TB3*Bs%=y>PANd8S z!pXPaHJ)rpltu?l<2}2rnSQ8ewK>(WmTJRO_PCp>DsF-GRH&7N-v854ZLv{xuQh|^ z>XZvIM1(uakK%!T-1K9k!9$6zVv|X|3DMZ2CS{V)Rj1_U7F9y|(8>3WwnN-8-XE>v zyN(+*d*vTJdK5Adby5}E3Za&+X%~@PW0A>e7!_A7TslEVN7o$*^5Rn-skR&8|Ls}N zNs~r8F;nHTpxh3L!*&1Dog`2#&R9*!qkE6ovozMRs<|IuCP~Um@u&o`1wWEL%HZSW zjUPvbDBHK*K9yY9axt2Ys;Ic78$PS4;Qwr!{$R48txci8yK#N0!RSC$I5Z-nybheS zNFAyS^A`8z{Wq@Lvx>U0toV7GCj~)EtyZ4U#os@3#?Jd>E_f>n&w94LL6h$pUl(#NPvO-03_YoIZ`$<;*VY~~19$m5$%6u}6;JsGFjDE6GIuay2BLFO%@dt0^cedpyvPCoLL;cvM@#7GN36~n8qgU+^Zttvq>vIxGr}mRc1O zHoRdy!X#OZmrQ5fKa1UQx1AA`RC^iF^v{Zcqx{TaO_blbhM6&I{5M!L88$X~Zuvee znSiU+nq$b|Vm=ZuV>hz5xH@GeNOO2_k`=2MBrMzp^L)1BrgH@yaomi6uMw|N)r(5X z9GvDp?Ct>}Hl+##V?RMSvHNL{*Bi-aN6eJ++LJs%#J8d25s#}{q$KNOrbxt2&+Pp; zVcKDjm1{*$>4_TjxLQhjrXV+(B9xKJVq8?)e)AS`d*NGK+#Ggns99%aXOD@s<%v}} zOmuXWn#TTkVy*U`O!<(iNpCr!?Pl#g`R(AU2_E{_e|(j^-ji_+*W4zTDurtXiOybd z%aVL<&%=lbAtqdFE`57fAdYNS&=!P>6dL{7B<+OiWVIXpV&9B(xYWY@(vneSCACp! z)V?p1j2Tp#-mBL4oWV;h!UsAiGVnGV>yRok9doh6T+DlKK5|6eYzrB|!mziqRU6+= zjzEfxr4WZO;!{L;O7F4WFkuoXKa^nU^$Fdo0+U=OMLs?v>FesU9Qm9W5VF)-wd_^a z4wAir5hF)WPtT(hn%W`eAWB!>cI|c!gh2YeUbJ2%cxsyxErp>R?#o4TAa=6h@ zEY`QhZyS9s_PU4Qg`9nkZm)y-M9CCYl{BQ58i%wvQ*aAXKKY=vSc(1>b1);9m%h^E zJXgYvgxy13W!@zRI`87G%$MJ`;pY5Jsw!2~t?Rhdfd`ZF=K*gc@Vp{5)0%Xq52+DO ziKn8K57S!Py4(7CbWQv=_^R6ba076+usj)8+SQG%H2%bLn?TN)5lor-u^769eByui z=`k2Ql8%rkYRhV#nDd;+*q*gKCGA;c_&N&@H+6K(Q5w)UeXL6xl~EQ@p&u>?#y5hV$@8^rj(@)^4%I(8PuMu!$og8Rc;VQjs&`8K{W8vAYsIwrxy`fc=Dmjv+Yxd z)JQRtDv{ced+S1XR`Lt_8WO5I)ftB^Z2G6R%;g)iXDh8niIv1GuR-5v{BfR%yePnu zt)WW7FLYh%z3(==%(3^}y!I3k>2+ha_TQV5{@S?bKH^pA=&-3h1Ltte$v)pwEhB`O zF}^aN>6G3QN~IP^~rKAeB?E+qJ|~^|kLKmPMSM zRjqfHatgdl+0@$>{H#?DHnsH93wYjPiZvM}N~g?|c44O6r!mX22v2#4Rgps^ zBezNz`v%BlFvZ-4hL)yW`lV0Pwwb(@F`eUWzItf;uTKg+w)^CvbZW+q+frF$Y;FMw zeNQ^vt)z+!^*R-8+=gVI{(Jt$4vf5wQEUTivcANmrKXd`j$-2(A`z6~(p#ou7_HZA zkNG{H2{PTU$1%#7q3YwA-eUYJMRqiUtmWMyVybi5%$0m<^t3gCEg~r@a>0{uV=hEj z!QN=v#raJ7m_sdNaZ8f*qgdMDOgdfqiL$ESv>EiG(4k1|YYyv7H{td!kA@!V_(c%V zOu~$F7Vm3jHBM`o@&}lVg#VK-7BC19r$mKG7g_BP;d9zn2+LwwM$N3(^&Qu!6WayU zW)_{*b#3c$hwJvov_Gj@#A_uoz`yrfYCdv*)?dC$Pzfu*WKO{0bU(Ir*m)0b$fblw zAuP(mCJo=BUw+v(U|`9GqfrNDsDxRJ*B6K6Ivt8j7nY__M32aL)v`%*KHhmi(?QB~ z$8)paE^zv`@14wh3YjF-)SaKzq)9)I3&$*Y@_D{g7Rruspwo;+@>I|jQ@eU^RsKjd z!ZpS8c35GfIJ$*DJII#$r(OoqggMH%8TR8)7V1x3%J-}aCuUGbFWsm6wOVqJ#g9Ll z0I#2pAFtMl{EcMsRMwLEYiW}&Ss*PZ%?eNJFK7~7sD0mI?}?KhAY6<4ckTP^*8mf$ zVh$R*8sdS&yEA3w@YR5>6wzHEjApe%p)Zn(AwKs}zP+nt&B-*WV4DH4c!Ze^_93ueY` zF%orOqamb$p)vZb3BqqZB?B1zTh{sc$!1a&gwYetdv6($Ca~kpKG@ZlE<=n7freUt ze}~XglWLzT|L{S<{;nsDDSL^j|M6p7BBHRJ9T!}D{9rvZKb?F!@#kDU=`u{urt0yu zKB-t-)Z&6Sf^GQW+9w6Eu&_`!G{iSBFzBy#G#f2@95Z;AKb{Z=6O;~g?}N2GeF3GS z)1vCB;DzoaA&rET6ap0G>SJjs-{ub5pO`*RJd2RsiaGr;cb4^ z3GbFEDk$7@3$@$g4jTGwB5_cFVooist;hsD)7L8-wM&c#53mq_zHHPz$Y%p1tLU74 zpU}UZLiVM4rd0B$rUS+}GDP!)td@lc8~B@AuEKeWWX~A{EjQL;-`SQ{aOB z+2ZY{Ac>8dR@T0ig9*nZ)0FSlHS1LqAN*dgt=WqLknT`1aF@o!=1;4LzL)gU%vVA_pX(qRBOT5Nx#REe z`#t-nZ@Lp7DiXYZvoF@pis`!$5BnYd;ylY~F~eLQ_#rWh{Ec2FZ}f^`T#mmn^khVja>7+>40+Q zg#K5kgRHv^0pF;zzAUl$iV;C4?lz$3GI} z>H>oZJ?!aGi7DILd%pZLCr_iFL0*zQg&T3 za`LeX0(fdH-s+RSv@k>nr1kvlr2P{iA@MAi`>AsrV<8BN(mAngrMPgn)nP=V-wCfv ziIdat_FQLXNeKyu3j7Yn11ryj=Gk3y3k-?#gwCF~Z{H@LP`Q?GJ&4)0{LSFuULPB} z)=vcn=#<0&aaFz3*B=Kjv0cB7miT^jc8eslJo4qsu-ntV718>B4R znVAC_PG&-gZ)#AGk+F)rZe}_l=Tv>f2HBQ!9?!5F`Fww$YY_G*vW2)ohhD`=X*mKI-1N%Kgtr$6o81qG=uY3wRZEwDpEQXxD4E#zI!UYTmI-9onv=y^8#n zYwn@xYJsun^2sGDC4MCK-J{sn%*B+lUs-|{+C{VH+#r7=f^EG<*Bi5AGmXcqNc#Q} z?dQZ{{!Td(1-|Pg^)yQE^&9_ePCP?Uvc}fR0YXLJjgSU|WofpJ155TRGwONyb8fe< zo~LNFUZd$kB>f_V&#Q=o!yj_H%Wh&cPr|h)U;t2PkQ-Ntx^z zK2-Zd`b?K9>ib%YuNxbU`vo20zynw(eO8 z1%C+k&7vC`@(q_q^^crg6FOKu;$xBnGbs*{ast;_VwwX>>vt5 zGMRUo>X{(N%IlaU+zD|AY0%=N4ro-~-NNHHDKoD5^Y229{`Bcns(t0$gmjqzMjR+T z?)P`XAvtN@(G5@T-;WyY`8~7mFkW$=SGVEWYfwQV6$y>flT1;O$K_U^hI_RtEaT3F zhWGaIPUaIw@@06XtI)Y$Bv3i5AyVfc;ZhGDBb!Un!hK7VJA;VNm(qNoEiEk>6%`a^ zWn~$T(~TuSV9R@H?36KL-5O5RU;ad`-CN9d!LebVir1_$H7b8{(ikr8#;uZkQ_+6$ z`PQF0_jUY{&nD&E)sRZ}DrtcR)GCuon5u;4?165!vuP46_@<${o|$d2Pavt zxOjL%K!VpEr(OjkB9_{F71o(wR`$lLO!VlyxZ!|S@@(%X2?GOP0+W~vR-MNtG){5{ zmpttJ{2WzZyApUZK`!mFqaY<^8OjUlyw1*!SRTkO>Jr1o#)dumN`eAd7R&vaPP>Z_ z^N6Mu+HP*|YDzo-SS;CtSj>4AOQH|iDm*RB+v)uwHy8KrOWO8WRG9}l??@_*?Uc_z zmSTUN7H3|M4k}Le4$!urgD}nHlz`6DKl!%GRR~KyOL}W$;NsH&OANeWB~D|xSw{&y zm4NdX<9LK)#!v?kj9l!#`DHW~>+ly_e2l20bwLE0^6yFSZ~QU>N{*pebg)3<5k}Rs zU-;LqU9%J>Cq80yc6RRn^pGx(Ufv}$GgDnd16^8Ly1(AbH4i#%_h;|-+Mj;92-a?@ z(?2LIfJ7p77rs_J{b|0xGNeM16)5kRqA4K;wy)B)7cPh?@@(>}>6{>qoJqZ>;DlMZ zHIW1~S3PWeJn5-2@vG9TrG3GHuqOYP?+3@{Cs8JsyiD+PyYp3 z(xYhi%1%$FFRWXB&wqQXDTSXycl+7b*b*Fh$DQ3dJHp#thYpB|45i!$N&IWY_4H4N z@)Ljr*7uV@pq_asuOXtS@4yJJ5=Wb(NQh+|9(=IPeuM!pI{&OEI9`bv>)sT`VJnF|KnHK&miY zk+P-96HejH-si_lES#L3Sv~e5ER>gd+v^oGiH1DfC_1{MhFm`d7oU)OeMGLRoPTc5i$-2B+kUQnTHA0S;^X#o&r0t02&t$v!oVa!7NRv&1?qGHITFzSo#4<&zjz zaj-cpAo4gP2e;J>G)cl1qpu^H`cqs_kDL?DZdtToMG)}PKa9-A zUs&)gYHV!eO~McBt8t$DAigJQ(&TS4z7)Ac2_^+k31iW$V3LhvShVCbsnfO%>CE}? zp`?%2wF-vyt#p5?Hx$&@xhP^1_Dg(GlSa3I4ZE=|@y%}EV$!}wQ&VVg%2cA~v4Oed za5hMSGm5b3NluYnd`l}U-|1L z&a(<4E+o_BN%ohAG2SWe@GeCBJ|#$Hd8B&Vhe5x8{IG3* z{C-z{88gjDQIr}5-oD3<$OD*+J%*%pQFcZC3@v6a9;yj-)K9)=;tqFhZLT@gxIu5D zat&Smso1ycnKFyL?|G<5RRh5)YUy>Z-oHdCPSVRCQJ{-lcew#yf?7c2wR%~ru|MOB zPVbR$%tIOC#b5;hElFOY{w#ZN+ne>W(5H4T%+en*yC=?9zDun^+v&2)Ay#i`foieC z%NlXy*ESu)FfTAZ#XQKTOxnTa4Q8f=f^&5@hWJ(ZC8lcKhWA*Hx^RTPBvh~%x?yu& z!AylLv`W2>wzH zcVVH4-FGTZXn63p!iAwl<>oaQ^%_+Qse52|=S=RMV@+OMf4wQsIU*5^5~J#8(cQmD zrXZ-n@DRW1xJ19Lf-{Ayc503hRsNeWiy^nplaeK6sn2+=K}(DBk9&%o%qP>EpCgs< zAtD&5OL&S@>29gJT|C7lkBywBcvHg|IMLW~QCsqbi8&Sp{2nRIi5WRTan|2m_bO_X zu1PK8u@P9Tw}Ej;>8w_Yi{WNurIpwE+z`$A@rp%$^m>{o6Qvm&@sif8kx6_)!dT^X zXl4NF2ygfXijrN12~kehqre4D-;By>G>$^=P+wd?KO(;m=G97iA5#N2$ksMpe9p4LZkqgnh~mj!$yu4LxRXL<&TVqQISPTN$RFp{P(R0qYd z&R&~k_NcRnXmuE4f7&HzCOPahLN?2k`SE&GGNh>%=oVcsrt~g%dM_C(g<-cn+m6Bo zROF_(sKpdu5I{kt*gqN;g`tX_!+J6K=PJhgL?>9W3!kFDYYQ%Q3aTZ{SBh^#cON+$ zKaMc98L!BTw|abw)?kXVGqJe^I|=YM)bsHF^*rc_n9JF%Jt#wWs1DCG`qt0wm+DUo zL8NFohb`#dZ{hxZKhcMM7GGiy%exRJ83{Tk<@*<+Zg{+eME;G&eEaT1(9F?eH*{NCN) z5Bu>$GciQ?*`#Qm>O*tnlNT|RR>2aoPXB)F;P>-_&J3Tg5J0rHedu)4cCbUfHHIZP zpL5ThKLPmg9BqNR&6-NI8`|(DDXFuKEEbDi)QNdwDHpF$#9>_j#Z7HHB~NM;k!g5d ze|g5@Z{%|a6+?LwKAF;xiDCb69OjF?&RtxVJi=~KdFb4nJhqM)a3{gCVEXr872dD$ zC8@)Tvu?>Rx{xT57A8@#?*7J2DM&YF7*u1;Os-ej^u!J?KMXU$=>r3n>?rZSmOIuE zpF7&z`$ycH5!*+5&ui2lO^2p01~-^bUicP`tmr$!lG3SD#@a~1Yc(z-)cfzc4w87W zkWS&!_lD}6IBX(@%Ps5&tW&g2F|E2HZ8h9Fi=1Y%&3lQ+jm92Ytuy0hSzMyIAKPyj z##<)Vzw&iQMENu()ax>Jd=FoHV`nL32c!3VdW~jw^9v=k9-@+Lh5_$tPu$PS1g{AJ4y)-%}SUM!fHf0nY(8c;2_ zfpqcbXZktTwC^s_DUvuKklM_bw5-h5Wb1I!l^FOj4(fmqw^6sspQl>9{Be#Qh%D8k z&Ur`N^-Q~Fpp3RpZL$>CTfd&EgHbbL%^`Fvky8Gol)(fpS)4Jh z(|(7tIy&E33ziXbafwq1s2VX!FY9xEL}?m~)X)NDukh?aMoF2qg}GagdEE{V4cWOr z54|Tf{N^W28V80Ynt0UMkHOfzXQMc0X4_-d+`PQRPPgL%;#c0?c7!Ggm{}K>5>*XJ zT*Y&ylEe#Zw$pcIFN+u=TULq~tjrw`NDb^B_b5gnJWCuLM7Qp7!jjTRQ^Y76CW(W$ zZlMBlxw+PL=_YXkFn`qV_DX2}0-bP+-c&JlO-&4x)5oGU{9EiG=igV{miVz#J_FR7 zqUYxyi8!<}cuXShQq0!tdn;Xq{GMg!`8;OHUYoVe`t87|g0xH~ z*`3O_mO|)4@UoF0i$fW^P@SI5=6GrBW_@0f=hwVznXr&g!78!x4m{|50JIOOQRmr? zYs-wVaJ+)V#xo1#>q_-!g(N8k=KSI~9rNxWK3a=IYOm|qFS_hGfgzHkz|G&#;+zO# zUFpnTh3CpS4+)%Vaa66esiS=ontOz7hBT+nu~oUyrTNNCBF+w{iGhMk7GqE=H9FDD zh?0tfAdKcq_Mk+xudv}J?h;MxFAre;`0;~xB|)8slO82`{H-~XL$R$RS{ZuF`W%IZ z$I!rQU#R3h=2<@~rCnSjG9NuF21RT-7)T#zRon86$K3(3{ z-}=2fJVq^eTRmdjX(n?dzq=y2+8~L6QB8*t-rYCRFvjMu;hPb8P0G7MM{McqYqtId zACJW9lS$XUQZLGOcZZ3p#|6R6N7Vp#ueoVxkiMW5j$Zf^OCuQky*n4n`vWU0D{mLD zAX)tW@$p9^S3IomXh4Z6;h^0c5Ll%Ce+m-vzWa3(Dg0mVgY$++3c>=_;}FE7M{d#X zH28?;))>3Gg3gsE)8>tJ8ulM=P^|akeX59Ke{I)iUAGtGiO*AW1ef$Go0oc%#Ks{0 zJg~oC{i%Yu>MmPV>%cNFhdn7CC=bmZ^zyQ`<(3eE!PL2_OO>#`P0Y}K0p^{Ef7JT_ z-X*|Z>7O42rGLbekGQKE)RQ9YI`6C?(W7@e#G>zFI2^O@MKP6eRZ@rZ?JNfGmShY9 zsfQ+Y&n*HL7FcQCy&c&e!NbGrkq^u0Txkx%TyyJA#Cz<*WE4(I$WeaZo@2~{|33O0GWLi3xM!{u zJSL8ys4`}FQ_0HdQ?ne9aNwK|c>DVLB0w<_L=M)u+3^g7%ycoMlzAgztQ>4P!LSUH zHw4)bCSP@N-Pm`yn%)A!u+VSq^pL~SR43_w4I!W5m@*6|{2TJkPFUO;$C$T~TjZ^% zx6N&Mud21HK`CT!;{*|JLcX(oy~10DKIn!k6%BdHSVMBLVH}i#RFPoOa($w@FRNa! z*tEn6DHjWE_!NT{?KXi?td%8U*#~e5alh?alYx~&}-@Iv&Gy%Mq^=NmB2W{Sp}zg zu3uNMmlMT9q4>W8X^+k5vGH^`A>k<8a&*#tG5UeZ3J?AxCz$2nGp%#N7V%f*cSJRN zFLSaJPGm`@aQ>5#CLJK&x&2!04Z5IWsU^}b+D$aSI_d{Jf*khI|LdZjOEp8RoPaw? zXwD_GxyrR3V?km%aHB9WU7%?#;ky$_xtq5gLd_hlDeYl zl=wWU)A&oZnytQ4B!p4lZCitKrXjg?EFxAlKcG*ts3kz{L22iI6MMm0bMlBYj{8Ps zOY)d=xI25#<7?)U<3)gTXRyNwhQerOxg}Cxnu4OMhSJ2dlVXzqE9$Mn9KmlB#&ll4 zL!n!f$o%<6Ze$*zN^&`Z#K+@hP4op1oS&~6AHt2amoN_dzy7*{O<0C}>esOtxvqf2 zI%Jo)C{$BEdGv)vFA@6Ol+rV=q75{yu6u#X`(h;usZS$#24WaMIr|sRyoTzq%`DBO zWF~B)aeVd;iwy&nqs^MobxaJ#xO#&C(ulU0a^F%YMYI*_k#RX~r+3ZV0s;|31$yPl zwika!n&beyoJqep<*eTyHY#ynHxzM@L7MJeA=v@<)EZ};KVbn~C`xs{H8uUUP+DB^pVgfIAO)7iorLYA;59 zUkS@zbGq$a8p13|l!IFcI$m<_?p6Bsh>s7FMx*CLPx`MyPigeE@A~yU!m~)cf?IGxmG~y{dkbx{>?0-{S4PjgB$N1-oye&dkPl)Ll)zH+zaeW(L zfwu;D)r2r905@&cXrGi}?^6iEYkW|80O2Qs7_=UI*217$9Zb(Qk|`ee~s@PJ{J|bm6hEZwThF~)Lc(}wqqx^)DC*L8GyS- z@4F0kE!;YARkwSx`ffi|3!91<(zxA0=XB=%ov;f~9140-^+Q_oP`keaGICc)ohG`# zqv=4g#*k(iKTdeTg@HO>mb%JNIOYX$&v9v@L+T4Y2}$gR(M$!4$AXWNjLUtrQufWD z_-GV@pqE?4y+nW2n&@?Tk?yl0mWa<*Wj9g9mnsvG*3i+kK3-{691|UFKA5Yqbu<^( z8cE8QQB$KYt_$_{_+Nm^va73Wl;S>pDbQK@JJb3yflWS~@LG%gHQ?F+o_#Ib*4w0| zD)rWtu3a*Hpn+SmOE2vUU$+t)W^?mv^z6w}jL86o49#RA=lo{YikDZVBzMfYftOf% zLP~GP(2q<80@$LVNQ=`bv;JpD$drlc-w(g#^-lg(*#@tZ>>1$)^JrltM zfxv(JV2aI4EErh~fLLyBuDM3?;`bDz$`sH%C^TzIYq%@$Jyp#0!_MHKwmUEMXm)`$ zi$p_i3di+5;5E<&pF`ckq^k*8j8{D6t*-m<0SnYhJTOund(O^b;ez+B9WSnxIM3ZZ zppBE=oB{-C>>TX&sPjFObb-d(Q*T>Z+C9p430B51IU?Lo+`{Gm6jv}N~#_wR;cPKerWTCBbs>b*uz&gS(Khlmzy zcd0J|H2TZWK*t{#&#(KKj4Z`$Mvt}} zf2!X2Uw+dM)pFyk+P9~vm_A_iDQO@TrDqkmZYXk#Zgf6F^uEnQ(JfOEFD_NqeC)mF zGJ9PDoPI!vig0&CE;*>Jvf!iby<0;;M|wRLgBmB6-F$OV<%fG2kktvtrZC`rc<}hL zZy=@2wP3!j5k|jls0j0t6cYNG#VaNCo=CDh%=6jDKJxPp$Jl-tCA_E$M8^Hz5&_orez@-PUfJ#-(;uuaBY9fZ)$n9$b) zKiP{BdmorGGqO19n-L54P6l+}?A+=Fj1KNTSYGf4iB^wAI@FnhA@gL^$5+f5?pjCQL@ffMqlUPXaO97 zg@-4mVH(`xFc5XPI6t%0;%Rf`@q^mL6c-D0f0RQCp%gu67&Fr(hmvIRJ(H!jN!}h0 zAQ3Z6C<(CobL_NT)JdCxZi)@a_wE~$c;!#}!h!H#8r_d}Rh9yG^@`MpLWdhM;Uz0% zlC)&}OcnOp$*okDiJ?PNoz1?jJ9>4xTYD!6fJHvb{bqSVZ0jY)Q8Sl&XD=}WSDjoR z+*jG!Y9$sbZAR2*AzLHLU%P_4AmKnQxaY>oRdyt)f27C%ndBn?^V$rAR+hPhyRYTs z$poxWUzVp*@=%B;#9&0uo)E5!HmfUU_=Z<{-|kvn}hCymdoYLZ@D zbm)Ey6baD}6jq-s&nXxFDOV@=o4n9*lvESzbMU3%OsL7FaTG4!LF$=An|GM=`}Zaudi`YHbPP}WK;;Py(*sdm@W z`fsMW%MA8kLOxL)a|=1z4mm-w-UN9zyepJblL%Y|r_X)aD(VvKh9uUkL|x7*v;(+~ znE~pA$e)@4gtCdFwP=r~RlCMJ-l??_!3Rbs>q!e%&2kF0U<8*FTop}B!S`#Gu3e~H zA&!YHiomy8ufShy!BnR>3_uBHznYD$#Z)G>wn9%Vh_9fMruY@DXg!X<#yxYw)>Nj> z99@7;I)~IY^>zr!r!yCqq9qi3XxpZ9sTSrJ9p0(%m01Zf1!zk&npkNrs(WJQ$qT!U z*+|5*Uv;v;zo;mMd@rg9WKgrQu`$b1Y>?}#^aCQDq%LD~$pyBAwTFBB>Jrh7&d2I} zGQ!mB;Q*WfJ3O@M7d~VPJL&KR25cDm;7}WI&XpL{yL|Jpq<@Mo0i&M9gUT8EIp8w0 zAb(93s)aQSK*bn66+D2Ffr04uvq^I{JZDvsR2i&pXK^1H8JTVMmaxkNn=0?DbHmrq zsrJ@>ONPnY8GD3S-jp$%up^`hm_L;20&8!XxVqn>C~K8Kc*Ud2D+f7H8FDN58GAF^ zs_TFyq1^5Ut=t8e982!J;I{@)r?y6#&J*}jb`P5_-t*Dcg6l@QYJUT6Zp?LowhMv#FrUoa&GP`@+1!E=;YJh%%=cdGp4qhvK>q+;8E4S0;-%(E7L|UHC+!mjB%y z@#!TE{fU*B7!?y!u3RDGwnA~z4sP+0i%4uDLRtt1#V?UJQWT#j#-gK95$NLpFN*4U z9_toeQ_&j^WI-}%iuT8wo^1(saZq48j3RNrLN`C?6zGC3Rf9o|2xBK>P^IU#B~>j8 zZZU;Em~jc2{xW_VxEFR3C;YgJf(B+DsMx@GiA+Vqmt*etgSHsC?s^qbDBlyg(X8*0 zwad6PZ_PdvK^Xlpdp>qO@U5AED#^Nga>5&1Tnk^^wQ8W!>j+DC_7V-g15%a~OAm0i zmcFK3z9#3y_u*%b-BORU@N$DUxZzWTMde+5^dYyVcL2CnA8QmVT{4)LY{m6x9Gv{G zfDqr-8{FM4CY%tC0sH8O5e}EIYa2>~0LP1+7Y4e=7}5sJ4@*jyhEZW>cNaPKBt2ne zg-oA@_VjeOZ;Z7SD+nAz#UliW4VpET91mhf_T4<*u?JCtTK( z=!d2(S2E z&2q%UQRJNPC%D)Tb#y4fEl>*J;JqQ@hBxUG770q@r;b(m{*VQJ(q-k6)}NrEaCS$4 z(z`%iKl6}#&-nWV9&8fpXY#graFh_RGXa|Mi&87SQ zxsh^w&?~VS8gRC12D9#=i7~_atYG|EiN6eJ+r1nziu|VaxN4Hyq1rimm)m?0xznleodq#9dQV z{>&+n;d3~U1+oNRHP!=~oc23g5^Srj$DgKE;yfDp&Pz<`^Rwz_21uuO)a2GUBK>gKop8_j0*0!pqc z%5$>8BfNBb=_t^m4-@19(ZqlSF8Zet5-bw9!8U}TesO)qz{G5~lw-ThUA&-e%ZRgy zYTG(V$r|hR8^6KtXuZfIf^bx0x(*0#Z{3~al9(hK1O9j`u*H9tWG?X9+uJP#Gf6L3 zR+vWR?$N>r;)(;h=1`ruSHwv3UOY4_L7*Fz)E3&d1YKZh9f&u7bWD}CTJOhy1Oc6O zL>`76xE*UhhUW2-_WH^t>_dO`CJE}OrsFBlAiFV_?tIBW={b+=E(F(E)vOn>~207LQZ2~v@UAM_W?NZdM>-L zCG(?qa|?OVv^t){+NN~aK9ik8Kk+mLm$w8d4~{^KX~!7%ktJDXkhjLH?g7=oXt20SiS0aLAVKpIwb6 zWosPm)y0=I4SKpT$|PVlx}-XvVg-4o-V#eLB8C5xW-aw2qV zT%e~a21&ZFB|sRPO8EQu3F5!qJQ(nYvq=7r{1TFQmxt_*a%T)k$psz~?q>JH`4QR4 zB`s0%Bk!SDbCt|64v{Ylm35dZIZEi-Pub{;ts`<|FNgkDpWCtfemVa zhOtOXPi2`tBmOVJVFT~gk8Mj3`XbfBw9pLdO5pbNSbo+b7+KKZnx+X5-b=KB2)yB3vr!U*ReoF(aSl*8gmY z|8Iri&EQ>sUhftW`%yG0p95_ajorWlxZrg}7fN|5pqB8DHX>la42N0l1Gg{9D_y?A z*nLnTHyqJH+j`dGoxH$d$l4Z~@-Es=?^u%##V>L7WN@{(8Few*G~3Aw+(wuIcC0l4 z>YMsa-~z)z-4*A@03Q$~WDuu#HdSbHiy;j0m)if3e)8=NyL|%r>$%yLYe&_JDWz|3Y+qp401X2TUVnwUFjTyMqmmC=r8TqPfVe^L4RBQg483I9J}H20mxQ9mAK!{(iy^R5X?-0r7|$W@4Q64G0El z{xYJEA|Nxjsb=0@lm<+ct4M}m9~orM%oLv-ZuXfTu8t7Dd29Dc`kI)_b$V&za_$z; zE*X8Uz|PLD60h=JymC=NosAInRRm#SVLznHe2-m@fSrjVhrf)SV}9SZSVI)~&kYNT zi5_6o2X_8U&_xDW(*Uk9^$ge`fx6Zum(7(n?*?49-LI<=u5-d!9_o3(Rawh9L&2_q z(T&=y)jW3~?i}ZAhC(MGL-U5m4G?6GKhE4#r(J_?PB^-@DJAjHtu${Lg|ATJW&}n- zSsB@Ql|#2_AK;Z&=E-Tt#^dmYXCt2(>>?^`hm>~=GjBggO9^YaBRwFpQEXU=FYdm^ z#UK#u5HI4@P&D#A<#q($)QJZe&Y z%FR$-1gYpF?;)03-=dU6ls_lrcS{_absqzC{r+J#KNuOaJx6n4#M(4;*z?1R<#3?^ z%xmWnji^(G;_;WwMgjmB@)S2HqS*XU5!tf(-Bqx2x!GMvpcWc=i-Mi*i>8(++}(*=f<`l}K!fGDuiSiCQ)i1)gA zhY;il?`Q^tuq1PUkwF_r$bx&GQzWTgcZ9qSL!0ZOZ2!9Cg8yjn+LkKdvT&NwI=2GF zTF^D;>CB@O(<%NkCK8;&B17s)pS45=oSJYgpZCBhvCNe!YKqlYygf3ZD`C%Uhg5;DZx} zxca9qu9r}Q78OdMKz*k~XsE9Ob1=AlzfVud0HwVZ8CI%Jzx9fh6(9fDUrr8VH!{kc z?&CvK$5ml`3JRy?hcQu68ulTXs>Yl&O51K5lh=SZAbV7GvUA>-LREPy)YHB%=hZ8= zG`%QbP89Jbl~3e?YOHzR{1AF+3Noyk1NS^U9Y+*63Qfnyi5p{2aG!Nd>9KvDJ;w!x zEwmn;!lK0WTw>rJx+21V^*Y;uSnjvz;D!oD(HRcRdC0ZXNtEPJ6R75o_KQcNA5eAL z48&gg@-Bt*zn!e&;Wf}!;N2r;>bwFW%qtFD(SICX0+9^A$E)(~#kYZX3`8hP`W4Cj z+dC^7y|jQSjr_HM5invYv8GG`w=BBK(jq22eyK^e!cxf!SW~Z>Jgs>c4^mI?t1phz zFHpV)YSVx-HxaD2PE3FfRGN3bUcJ#T@tl`jw;7Eq*~jxHSUE{(A!*CdjEZVwfjCEGxu5OAqTI395-&trfg5nbRB zjMMz>z3~0Djt`v8zE(+|k=z>yTcY*p+C0$lvb$|pP8Y3}>6B1ff_1s^e1ftWWm1VT!rqbQ!IG-%@CwIAx`T3~(6iDh&UxUyuqWatO zS0K;Y*J7^Fy!$fuObcF5m_@jLIY$d0^~q}`a!;#ng zO1xFjcN;d~D7F{*qLfUlA#2v$_Blc@U=+PG3H)_4-WO<1hgElCn-+Ox}}(;&VkXldO?DQw0=lg z1u4Sn!s(k%f}WYz$x=|GElDoxDGWBO<}*n+PJ14$O_7{~`ev+NwrDr1b-i_*cKl{! zB|GrI>FLNO0zOLEQ!CN7__D*my#{sRX|y7{5G`6Q91#@BUgE!M44*v|+MA?wVE^QO zx4rd4uDZStGxWfumarWs#FHbK`4LcqGivY&2`OUmUYeKB?USThC^_j8)>rxAlIs>9 zAA|<>M*v888-DW%Iy_ZqaPpda4a(oCKjtiq-Mje<7a2q_6Hzpc_&>$HWmH|y(moj6 z-Q6vCa0n2b1PSg=g1cLACs+gsP9V4(AhZ#|ct@a@;Gt|1A#3mDeKVtZ-=kVKMJtqA6nc>utjR3Fk*~*E?2JBTf zM&4k}zTF(b(YU=2yGPEq+92EE*FKOyaplWJ`3?=By=JZvEAk>xl$jiwrwU8bTd0EM z4e0z=LlN7p3fUvW@~qqwqEBHMrNi2b^Q@+QkIC^hCfQynV@r2|=UfAHerYvcJRBT2 zQJSHMzk1-{$;~4guCoHJm95(LMS*#{*hMroRq6;_ZnuRob1hgx7Ww{UW?9zZO~*Gl ze{7OlIJSjrc0X(gj@whkM(YR4B31J@%MCp%ft+m>*sVtzQfKe)1nioWG2G*nQMi_ zKh$vzcyj-lZy0-}*h0`kCN@t1+eUv7EV?;LUH8==Z^;MmF?;TW92y?p3F?@P@61a) zPzg%|mcxkh-uZT%PQ%VI+ovBLIe8s*AUzg?5mxMrdYW(l$_de-51I;5=U%?ywV%ab zSzTq{SwA;vq7?Ocp{JKB(}HWW?gAMC=wG*4Q=H6BRSEZ_|IPdGr1E3+32hfBHb7)KUv zUq5I2SZd?@kx;;|e<#Yn#4vny|-Yk{4|MNcw^J#bMCZZfyTE=_c z({nZ+(N|;l=fXbo)t4IpH&^@OojC2}C&tVHzrUD<%5stnc znt6#lAAhCjUPP#4?itozHNTAQc}~CfNjuWgrGi2^zwl?fU9Bf8&!i~lR5StWv|a-; zYVso!OF2ty=-!1U@K=r$ds28;#QFbv_DEAJ8KSByy3#eWuIWzFm9+a_ z`GGBLqSfzPeU^|sRnj869D0aDM1%zBbE*ot*R8#MCSlxGr(C z&Yf>N`)S!k*;~KJOgLT=q%|V=?*9^g6Jd|8tt_Fp!ibD~jk9ri2M;F|Qri7uGe!E+ z$rAY%p9uDM0an-Ns_-(xB}EZvY%YS<+qVqg?dOtOG6ftd9|g+*EL>mCF$%cplbC-w zPAC#sQO^a?sAlUiEBpc`iZy>#n#*l_;n?MV|FLV|0?7Ie-^nxni6Wxr|Bq2blawn2 z`_G{J_GsAM=VZFtgU>ww)XdbpmHSqN>MwT9`h9jb9u#8U8!o;0^AIG|Cug^#WjC|T zl0X4V(36lw3Kx~w)*fvy-g&v-rpF%qUO%g!IHi&moBuFAm~Mv1KD>Ib$JE0LTMmsa z4**pOppsnD_mZfi4HSo2Vp%8-Z)B@1A`?0AO03d8RF>E~wx6G{M`9av zK(toPTrtw(f)BEQ|9rcWH*yV?u>OMe*?Jli^pzK5Mf4=kc z(-BghZdY)QTpNIpUZ` z0yH`7jk>x*=9~hzjnL`aFxp62ui8E zraSjb9U)b8XHg)B`a4c)1}R5-Nd!mp1pz-xbfgOsD};lb~_^ivN0uZq-2$FJpV zi4YxPv>q5N7TOglfw6uMp>E!*K6gUsmi z;1{0g{qA>)!*a`c@UJ8L&iznPgjT#iw-*wLrE$NBTEXrq2e>-(=Uk^x$y4qXkB232 zaINhbJ=2rTK>%*&wFPZ({g?iP)AR<=X`2c7`rn28&_`B%N-|d>10=WJ$8(O%>3U1& zNyuBdBF#S@;?Fa>ejsIE-qHwS*I`Z~v4ykDX+H(~ngr>i2V&=JH`jD>;@1Y5gfmd5 z9lWXKjrtcf{G8+h`K9CqcC*6GR?7+<)9^o~{{KqEf2D}hl{lKL6$3LpGfSo=(}EKI z)!a;7DYxKeIq}m**Hv!LL|bz}5LGQ_kZOn6U++z%%fx@&16d3oiNt$~w+*?fZviV9 z`$b`z+ho9&Ww85R{QyllpB#5s2 zV}~vr=>>(kruKg%0EMR>+kBX1Eq}E$aNc*A7s#af)|GL8%=u{S37oi@S+pdXKM{04 zDz)~la`(6H=M#t{W)FMdYt}X?3HdxtSGL9J2 zBDbspRlNyoQss0(7(7Nr2s21tJceHzQ!GA^U%B5rAzi1^4r>&_EIFcpco7*`w*%uA2l2~Lwh-O9097M+Asd1BXjq}fW^g7W+aU@1S{BZj>;R|x z2j$fi)=STakqW6Fhlyqu61>?55-Z>MA7K-K${p9oP3fR7BlUI$_}O-A`YswRd0O$) zQ;qgTzK(CAdRh;SD}L55R*ht4KG``EB;F+_k@ks5qMT6I_~1{3{Y#PMKkICTRh9DP z1N%<6j|E@-a)--Sg6TRMVk-tQOOc}F-b}_Ph#kHUy=0E4=!EHh64M%FPO4-Nuq{VTGww(+q!Ft4cta>nA zUvj6!)ChD`MEY5YZ>)m?_#ma=qPLgdk^S;rFylVOzkeSJc(k?cZWTr?Y&$5MkJ^Vd z)}$&uC1FpUXO21L){&d+l}__z>3ixkpTa`b^>Lv+$))e1!JTJ1~8zMew;u zmV9KN(RVupt_LYBuV%;ojG;b^4%Nl+UrHlJW#Y)2twFA0C%1_pbN)uL5$(eDCOs^A zo?B(78Z(-3Fev!7TxV=+#?p0wQSgV)3f)q?5rPG{%DW+_GR{tzMKn_3kWF~y!>-MN zPCj&Jc;R4cW-rQCX5OSzK1}C~=LQKR@qJ<6Vq$D9kNeCYwNsL|aa4Vc8~VyPeqs71 zWzdjEfSG5u_!NqeH_m<@@JZmi|rz;Z?DBKro%nuwKeXg$@|m<=i&R(&Vy138|D3u-g}xM*y%K|H~) zGlV~X9!cSr(jzC0?}%arG~B`SsZ!mpI4Lg452>j?M>V*@WGN@RE{xjzMezysd<`ZR zh$$V}slToE2sW>}W9RR}ELB$%e81QSk{)Dp*Aj1%)`hiQzT3#XJC+qW z;Uo{~o)?3d^>K2ES%sX?_BVYsm96Krdx;!ON76@L3zlfdJR-?Dfx?1^nA0%u=UtQv zA%q}0K<|k_+a>-9;#n20GNJxvt&@58T!QG8t9-@{+@9_Vk{IiGM{)^ghp&QyslDX4 zOXXCl1DsBTU}q8%Z%nO6y5S*?&u6Dt5qL|bzPC2m>D=T@3Sh>UIQjT6+Iwy1Py^0G(6M!ZgWdmGC zHJKvcRy*h9mp?PwdBn6 z{Pt$;D+-J>_<*DrTRxS_Fov0D&X;|DZVx7PeIs~ zOzRqGZFww2;=*3xq`=mH`jte4G-_dwc~ChdFV7w#>_(u7u7@>GXI|E=Q2`uF(hW4S zm0AgxSsLb|@wf;8m8@DBuxU_;!>*eKsZ^Pv;18$5U(qcFK{+_}W0+<<_V*8*j>jsU zPTEeXEf!>Tnz#t_?-CG2TUl#yl~2kB>KM4p-jWO+u|~XA{fwPrfPnPuy%Wm_Jf?iC zt8i^Ms!v?K&d-q%OWS+r1>Zwa!q(N0yzBFQG*HzQ0^*UE_D*H`2OYRYyDhsui;Zzz zzm|Y7)o>^kQ28r%bE??^$Wc~L0m?;g7*gbw4|aO2BW6h5ogApDY&i5~F0KmrQ$)Du z1fOXa(NK*3>^0L1`9Fx4vyLq2SThz3`A%dcgz$@pP*_tWT58tKU@uao<(C&-8eVwC z%2}Z&{anmf?j-pBX9#QYB=8OMB04BcXgCuWO7%w_R)Xg}Q`kb5?4_wx2p`*&g31@y z^ii0uCQl>OE}fJ}{0MYlN>-oJ+@`=N8}N3_4G&8^$o(U@4WdvELU)~u z+9i($jseiD%f<)|6rrNtSiw{A*}~8vz2(&x0eJhx(lX@G=57kht$-q~`{N$-uqYN1 zCVW>TWP*#qs_Z9ieffLE{Yvmh-QEGka%aD()9vX)=df`JpEPJ*H zgd75hw7VybSwNtv?tISlwq{ZKR<TuB*dnG9|$FFP49art33*>ed^n)8uQ|msb_@8WBZ#vpljygd0bQWq6Y}5 zrkL4R{lwA_NjE+8MAt^+czMs*Z@(QqA{CGVC-<8RsaJ1#X(Um=n|3rn2WH~rP7pGQ zbvl)AR_LC?ENHF&z&?@U2O(rN*ntS-!BGB)m9H#Fp6|4`kT$>>)+d z-Xj#w+tqbL`f44xajm=-E*{a4nYE*gq=&#MZLuBFwnP~&v%4j&R+M}0fTK22?DVXk zvc!*^ikc6*HoNT8s{rV4_T0fLpC-Rn=XOLP-hAg@keZn}T#B+sedo zO*d9b*ufccBQ2Ww}wEG4a_7i`&{0X6wOq zAD=IIA?w4e945FTXYBhP6%!|{NW%1Y%I0Bs2#s>25}J(lw`FJV_m$EVNxw3Md3(ab zBZRgd0=^#Q*}n6oIV?$(&$x%X-L&hhcU{H&yz*Q|p?cOh=G(CQG{yLn zx;)wLjY8)#`H)80Wf5H4*A$`Hr@Nm5dl286XY6Krt)TdU`u)Z1rjo!Hxz%hk!^n_KhcGgho7EG9$W~lb)c+ zMoln@kREFJiHyVOrA+SZ5yRU41c|#Ff;~lQl^U-_ejTQ()7Cu~5>IcP(4fS9WQTml zGqQUg0n>{;bDd^tbUbZC>BU%285*0V*AprJ^@O(2U5I!yjF=@^qKi^&@UtPhi?`}O zHzgvWZm-&R0Lm{=D&EwG+obq;-Xbt|uET-%s)xvU2}lfgD#;UZ-4Hpt((z8&tGHj2 zOkcLfKDgS8Qe1{jz40B|#-J!t6_wJA{?(hQ}NTw%0 zPl+KC&j&k>4Ea*_Rbpbr&LHtNFXS!oh8Op4b1>E}y|KT-XW&9I{Z3xaGvwKoVtLT- z0-428GPF=PQCI(C{$%(U8Armfu*U5#>Le~+BgJ(j@pu&4cscQm4Vw%LH>%0)GPiz= z*`gOGSE1-K2q5w!A*4gqFb@tn&Rs;Qm#wGf5y3gbaPKVOZi<^UWf|g|DC;6m$K3zL zg(QGyI3LaknDCDqx=WPu7aZCwJCSjtGs82UkbE(7F6 zymAz3CdG02y*_V@Uj=KgvDh7XcEf81GAlX@NSu52Ewry9zy8xzCZZko+8if;XUh(l zg{g8kFYpcqWzm@rP9a0|;^4+E%=WQbFD+(tfoZ#|(=v}XWY=n(G&Qz@d#+BJ=p_@o z%RtKe(#Hw$y;2xpezIs1uW0EHUly(f})}#dd!Nio~r>1T} zvG%sXU#x*1eiw4T-jqP*?l*&pkspzIcULGRci7d4XL|?IAE%o$@WFn61+Wu~A4im3tZ#b|GX- znd6c53N~wmwknHpIT$H%<1}wy6@_3oS1gY|hls7ZkBO%Pw=p^v>J6~jx~4i~!gm?3dU2??+->D6e`D|IR9 z8ZpH<5*v%mE3ttxPrR_ttoF{3M9qp2V*VC)@U>|B_d(u^ybxF|f!>D|`|{x+;dj`i zom3%~O9Pjk_VovD+4jB85SxD;(H31*y@S1s<+^mxjp3@&;Kl!HmUtsOd$B-}$B+EBFDgQaxV9Q`ac0V_ z#Z#0&vk_BM7H`;4J6Aeiij0f!=DF|}wH-((NIg$ljd2{>0d5`6FzquLu+>&uy>!J( z6i$EPA7=>?-7cnV%@}(MA2p3l_Ln?+DAO1mA{R+$O!}4Re8r}m;n6qyg6Taf3PBjl z0b_rwvfx$#d?gAcGkZUw*bp7J9EI?#DdvaOvv48i%4ed39s8|RboN_Tg}p;W7_LVX znWTdvMiKikXHLh~VB%(Vps%=1zO=zUXjo@={Yi6Q2-!v65#gWK*=dUCMm(Mb`p_{6!XkovyxjD3a!@LIZ2AcJ<_V(EjnlweOqMESW$?MsDw;3b1n$rFF!IG$wAODyS4-$*Ny+CKCRU zdw)S*C_-`hZX6L>@2g)Q#fI!j-J`i4IULy;Jl; zmR^u2^@a=e|8bEsOhKKHyU2z5ARH)WMRrP1P;D&TU~Fh8?D?4PmY#OlQ(7`x@z^$otJ4YdtI3LvGROR-^Mp7ISBQ<#lO+3}?N9rj zO~X%g@fG1z3fUO2k2)17Hm0h1Y-vRNahGX-#y>q0-( zpB_VEj@oZuV4-8i5F!*OO3>)6x)TovMI>ad#LQOhb{1^&Hkx9Z(E)3ZDp1xpaMregBe27+JQh&fQ7oZoLEq|g$)h{ECGuF*nFYt>g2NsQ=<;TvC2b!L^1K*f}B z9F=%^-E%%Zf_FFP>q)jDDWLkX`Ut2k?dC`Mfk}_fN44T$U%S?=91H4$Ta=)>sHitN z!@4*Y^y|RDNR@3-YCMTaZbET6X1^>5HPeq2$w$13`Rl4cAzilOuu^f<0zBk}ZLEI9 za>Y{W29L+e-bNg>tjXyr0->JYgBSIt#xW%XPrY{O*UCr1?{uhr2CmCrMkBjfZ45Yn zXII`?(h0_^MSN1B82$Rsk?b;68ose1!7K9+C1UfL{FbfPs}7NMlCaOAYk!A!S&Ll3 z|5!_4oQ~lJo&2@0S;J3)E=f9>zi-==D$r?tpGRy7ZJKG#!JRD*0R!^nps0g3J9($E zR|V+2XI<@GJ`a4{#=`D+;5D`MQ8Fu>bZrl{P1^FziUPq{Ktr%O&Snl zy00wOo4AYoX@k%@MRMrGBB#fM&RKUV{c+nMIy@7(LVk%Etdzjhit&f=(O0?gH7l8d zxh&pu;$z1int0n;U`?cjM7EK=W59SK3hV5ABbJ_3hc2{QrgBvAI2=BA3T5`nz9Pe% zqw_)8H$E5~3!~YilHlacxboJ)ouFa=mx~$5AT`9NojpuEj8M`D=`*GJgZ0OQY5<|+ zwJ2k|*Z^K^YHb7?{}hpUVP$s~o3B|nZSy*WHU{_8i|?rmnRx`Jb<7PaBLC?_%*s7Nb$+2Ni=0|K0HUsh{Bp{= zQO@OHIl7L48!#KNB!h?Jd0DRrMYZ0A1AQUqe0t9nUJFL-D;FR2bIR&lQIitk zI0(EkKEA<9ZJFb*B_9j1(U#Q&lilFyb&&+YcQDW7;(CVeTOK!*!`TBok!+lV+Q7B* zKpowWNs=$E&h?4zEevd^3vWc2-y%u6%cD&kJMj{%Lq9j&PJZ&lP-@W5VPPdGSB^AO zZU2y(|H_JkbKr?-FkEp8p`;>sW7Y0A!m^gVtwZlT8Hs$PXjra4Qswjwad^0F zBSBFQ|Aw4?QRA+S{`8n7A7g2>IoR`Q+`_S6}vZBBu`P5I+Fw-oTGipk}G?k z_I0o3x#3307I!DxGrK&u|*^$TAwJn~4xfTDsPykWe4YYB15nyU&7%*oOtw*JWbvty&`#kOvf|&3Ow$8u1&fgOHJ{ zx-dtwxQ9lR@bh)j2$y1G56&T;(^!i`O*jI!2x@Jq@1aS7^yo^R9@bmf=^1}0a0wlx zM?H|<)Q8fFU(wpI9-u5L6?|BWJEBnm5%%vbNd;LqjosBMHPt}tMjsN*mt`=rb5B=3 zs%%wInH*deNyBV}cfC{%Y-sSUF!EZS?LGS%NE_i{KJQ~-TqjXsINgl2S+^%stPpy{ z^mmDNY|iTRgC|T4#aSo6njxB`ETV&*RP)kTMNgXsdIF<_XLF+N%)djd>@{chErP;R zfy6Y0l$11z3QAsSduZXs@g;<{OEID__&#f;v#?T-$D9UN`=EU$%P@fgJ7Q(e&q0o! zplTuK)GbDM+~)UhBBhs=g6#%BB;MIX`v*oTyl8lZZQ=*3;-x0ujxU(rzTa{UlW%fC ziElrN#U(>lDzp4zr_Ah(R@KWiHjK!BV78IS((bhj`;QI53&&X_CVFzs?V9R1_6Hw& z+Ky8Rg;NFTpW6yP`;xbB-&hdt)-Y=hgWZqbLGFmE*ZOf`>p+7<8%q2#y&Ez#%$JCwYzIV{cE9~omBP2ZDj@Q)Y^ zs(PvJ)s@L=PS(=Ns$F`9Ab!|8-zZ6qg?4{I0f%QFHp`_?dhhz3{zy3}k`^C+52%kQ zw{VHzpxY?SZKzZwH;D#?BpWXLq@!vot{W1OMUhcbGAdlJV7*~_=csy=hwI;^6PfJA z=Q=HlL1(+LxN4afMsW@FBnQhdcHfYh{M6xrb5u`a zYk;$MC?rB4cK=P`9QdQ5AAxwX_(Kg0V-gxyDZ#w>XN|4(K5)&&zt$FmOOB%9NmnX= zJ9PGK7XmRyH&h%}z1g9RnOeT(bD0q>Dp$jfl+l> zvUv)@;6E3yBoyW2i~?WAH3omuxC7lUOVDTP{=lKz?h(qf)k`yFj)kSfEoiH~V!L_( zcJ&ED=?&=X7ua@xR`DqRehjca8U_ZL`d5A5LvuHxbsS7o+@S*oDP{tut;8otUPTMt zuT59EHTgc0c^mq6?;LXER`xFYf(BE_BUu}rlMVzMUcx3OUZu<`u^7nRvvmAURri$K zV@ylX`U+={4cffY`7m@50Ryy`FD52-8RZm`S3r*WU4~#gw1FL!D|Uv+4QAs*vc7F# zRNQYcGxbkaw{y|BX4PNT#R+b~zCYI(-OmtlhmrMtTJ&a~RP{xI536CdBECtv{WO@N zZG9}-a)x&L*(133XtY>}v>U%dp5Sd_M+1tzbdxADm$Q*2cF|7>NkQ>;0~tFP?opoT z9JOyX;VGpqdFw^a-&DxWrt9C{=5i4bHZ!RDzC3>D>r#0|5!#OdrV41szc16T`wHkz zK+~=ZbO~ZGkTJIZ=7gDDBuEEB7~ z)^aLhx?wYGy3SH?&z`As$bvAA92!XVnxfC|wQ)=BuP&sfy^Aj28{zbYH?e=%MH1^C zxKQUsRmoiShjBG#WEU5wLUjk7x|3xhD@GkSg;Cjyz&p zXkzl2cyw@(f!>eQbwt=fe$~L2^A?Z$?0dln-1A0fnDCm*n}QE!YWO`Zn(Y@f+sOY!Av__`D5rIT38N4}(ejkVdf)R?R#rUdDvLV#t3cIW%5^P1@YIQS{~!u?H#wnUnM$zQ z8To5KYAl380o&%3F4*HxI%S9>eW3=eQp7H?^^9rFZZ`Dx>|{5~EJ~}{;u~|j!OZ2y zpeL?6L?$}sFpT~cO&sm%V$(iPSvGX)IohSuZA3rg?|#fjJbcW7_KA_$cRy}uj z|GovWZ2_R!lt8mdMp-$|iSMOqkp`%^Mgru)=s! zE=149)f+Vch8)k7=_LsX7mMgBhd854w706W=U8(_PnP3{g`I!@z{gsTomk^t$1F`O z{B2AtW_}xfBJ+hIn)okLL3F-DDb*v_%$e zSDsy-&fFgXc@|=RJ7PzSZBvPaFt*sGpXWeWA0Bi}C@d-I0?Wqbcj?r!p7a7{w>9A5 zB4A3?!NH-o?QX8^IBBQ4x*89GVN$Q+g>zfH7@X|t#{f+JnfrxZy5@)b8zAwN%NWz!Dl$~m zP%ArbIi_LjaJAadf*yv=KQcE*=Gc6USZ9v)n0l)9y>R$*xM(ae)R$!u6lnjj62oZ* zdK$>TdNo>>Yo8BU2Xd2_8)=Txr!_#JfXjN6{$LM%7q+Xh&1#DKoV3%srl!UVC@Hv) z^=6&|Hp9m7E!USXU!bR;pM%SootXYGw8fW*$6|1)HVbG@9L)Q2S$sX(?6cf+SDNVT z+wofetQ}e{LIEs5rvJ4yFF(Ia{0t78hja|KWTe}~wRiOWFTM%V4|4(Q-*Ynf)9QTA zY#bseh>82d=~_Oef})s!x18%#7Adin*h4p%^dcVT&X zZ;n(1#H=swnOh5O5!kCoEyv|OWjU~_kNu87yAS9p;94%#Oc~*o zN+8onziOm4v5wEQD!7WTx$_De2pwDPja`jf>+bD!F^zp)pFuP0K8-^|NIu8O z`3rq3_K>kff(zg7@lE^L`vMBZV+WBIF`eE_9$H#SPu`)QKckyW>;_Y~p?|ug@EX+J z6+so6o1ybGOG~`ib)@eg^8b#J3e6XE{^q+l-;E-yt^>u<>g(<@LX7ir4q^LyMK3gHq~%f?BQ!4XdXLJ!Ek$ZOyX;p zUv@DVm!hk$k7lV44^|s+K)UX}il0xLLpc%2i2k+QVMxmdak2XjvD^EHM~+r~?CDJC zI)1m?pkMZHm+*|It}ZSsl2J)HXQ83HkX$*yW%N0nQKhtpuyAtr0U@U{eMYF!z_cH` z`pDJUl(B2U;ddk^&`c!^$ZweZ+4|k+K27|wH$0N-Y&PF$YTRRQdX)Vnm`!jb zk!fJVJ)oW5`LIdnJNzD~2^6L)oDYB)y0p337lvUU;d$=?R1O-gr9vxu${F8i6P#>T zPr13fuV1TGF7Y@nJfDANUP0q$M58|P<66G5oFCNOuIB4TxK9%80;4xs)>R7{&aS{> z?N;|FOW1tzu~)CKwG;6;V-qoCd5&QF5+8yL)&xdM#9{flI*h^`N@fPFc^Ab|ay9E7 zs1O=ppF-p=1C$fzj!+!2f~1@)HptOtb*=@Q3516SREI9**IZU~SZ;Y=DT-SDPZ|m zWE7$S0P@|u53|KtItA4AyC&mR4_K`S|HsoF0SL1?zDv;WFC0kV?F?BK;7*HHt^MEc z;Tr#a22l6Q0pt5ljKG2(SpthwP#|2G#>DW~w*SpQsiLClpjND&S3Y@yCjU}eLc_8+ zm$hke1@t5A%Xnon{VvTPFa#AqUhLl^cm)pU<=LGrpPO_0gCqpN&F`kVKSC;x564%f z7zNR6jM@&h^h;(F76V_A#_)&;Ix(@#x+HL%{MRqj)c|n*-Hj&LJdv;9X8W_Q1O++m ze=nh%96sbtamyW7-oo$C|DKU~90WEJ91oAr=Hlq480Ztf-Tzr~Y*d{p)6(ja^lMY% zlAs)6ws`PIAVq_0Ed!&#sOawTSwS3Koe$JAz6DeFm=dHZV>bCAt)F2?QgqQ}^%{Jb zDak*3L!K3k^!LJWxmtcGDe>PyNk-y>1OYRHn}?<(xD{+8BpPWfT(gZP*c z0@)5)B76wFJW7V)XB9YrWS~t*ASa@s>fq*u4wt_w1mnsJ+o2BaM?hdhQIoXPW*Be( zyH?neYr(Kd@XX(;OCXqkFB(QX-Us$ENB*bb^4=Yl$ETWlKR$Js*~Fduo0|upW(2N{ zNg?LISMX(AWMN8TSiV);`u=k($$#FeDMUyr2pLqB(r|EK0_EwcG^RdbAn91& z`sy}U(4~})ojn#!8OX$4hbZtr?aKAmkgJ0j%00mgn~-b;Lo24 z9wi*c$H$!p)->d_vR(gjRHr8;f(Pn5+?aC zrD}?%jEoEiJr4IrO$B~_{>E+4TT|nrq5m6Verqdb+r!=AF=$R1Bbj8d1GxLtTBSN2 zqUFWKE6N284Gqo(Q^XD9%X@pJzK*~uO}7Pz8yFb8(MFonu1pz?>!TI?))VLvB zl929fxZF74j_>yN)@{r#LePCjV}Z0R&!`WGMlLNccZg0}@j{gk!-$NQIC9&(PZ9-PpTI{L-}|dG-dmE;pHs zFt7$l0~9o+Dq&7rOHP`m-a%(r3KwrT1fZ(aLZ+t48Ts=Kt_2IXs=2bxaxd3|V;y_M z(EQuYfYHwtdG-ofRSZ?fP?3cu#!$7tlR$*P3?P37Y^;08^9r0Tc|_ssCP1YSdSfA1 z1%yQF>2v`XuycYwHcZc7&@u}_q^!IpQj$X_;v4|VNoX-_f>nugzMz%t9TiQe8y0v! z1H;%FJU!k9WK^@#ualSS6zl*2uSeF(ayjfrG7nAq-P2sHk_KxJ4TbV)%VW^f$Z0t` zfF?K{QUV`=K^6|s)sUMEGl~Tint3DyHZ#J#r(8l2tl@@dJsx{(g$d<7aqX3?C(n3z z!eZV;P`ooYH^Px@Btq5cW_zWe5LOLNx&((9SVC~%Nk)EAZKnl4k-2&P9*M{_7P2tF zSwW`h9{iWj5Sl{r@6++|1jRP9_}4iuIr#qns}GS@BPAny9GSESvq_@ECQ;iZ0%+4m zpFT7sP&e$Qtlr$*{7C0C2dXT}DE9c&CPuOpLNpd{T3djGhM6p21%@H?D+n}3vCch)+q z@2fvjZ9B!$44`nIITTwH(?s@%i36z-k;PiX#3ha?s@~U z#(_J7(7EG9w6qa_Oq-fi-xh5nZ<)IH*phjJf9g1BQ1j-4w6(NWLa@Y^?$<~DH8jw# z6}p(|s>cz+)Yrvx!`ya*~GC1qS{D(SqRByyr~*J5ud zGjRaYa9k#YPPg-_Gn>|65(>2gI5%+i<(!BKpG_BWls#O=KP)BLlI^CKGx%YM)n?Sj z6Nprq?`>gaRbJ`cu2Xm$cW&n*yL{r9GFP#rnf z$$+S{j#SXm!Qo5g{`;Y+70$!{n`eA?kdZF`bD;YJT?J8k=fuQkk%_|nBV}-An_TNB zV0Th9z#xajM=dq$R)s+eHXz)-_PzdjL3PE! z0{^nK;!%!*5{PnNK~~4pbn^qYFU8pO)lPoEuIZt>b6%HT>Y{I_%F0-KlBTBC z`fTn^iLLc-N=o#-TevsmI(SM+f+36iqrReVfqMNnjBf%eP}1vv6}?Gj@b|yNF{rNp zH}ox2kmB_{@F)LwT$YSeaQ`ja*XLIkI|1gqOC3%JKecvA;#-Ob<{~p<8yZ`o}2*nNEuGS+rw8O*r3tQYioc4TCvy-hMW zM_gieA6CT~ziaJ(d1@nE7aS7O!DdZCLD8Hh=E`%AxN#u$E^%~pG`P4oky{`7`{0+; z#c#Kg-W8KN_gJaLU7GS%0%w$o%Yk)^0tXwgq&wSoKteL7C;8+FxK-SD!zB-sIo5tf^XZSkMY)oDJ#17%wm^>+dauuq5sK5i~9G zn-fIzr%Tbcwzj4ye`?%n_w(suqNJoGp`qz*MNe@JGQ~gWj$C^|;nNj$=*u8QIaB3m zlfmi!qokyyfZkR5{QP{f!tZn?xgYDBWvGaGdiVM1KD=z`UI++7YaB#^XL>3tFE1Jr z(zPTeaI4gHO})$&VMlq_2N9wFxHa(U-T52kH>Io}B=H12Nal+gSZt3X?|&PeL2P=g zZ|2t#NA4PYQZap|zUbHN3f+#46y6?d^gByQ#!$o!XAC&sRaUuwU(l}Y6du7aSuwe1 zVJ=Eq{43S5ku;zBEjB!iRnW5 z%{gN}-(jUYCGi%x8@qM(@wNWSrxh`0<05gwm&Ifl@O!gtFc^6o36n=ou}RHHf$0`? zg-c^`(mn|#rS6XVQe(q1q9u&@c?lu05693ij-xp8jZ=S3%~u_6P}7*{!>#Fx2lwcA zaKmldMXC!8O5_e(Sb{%XmRj}k#C18G?yc;hn-(mmN(q#=4y~w|lHRiykYsBlzV{R# zAAiOD2t6wSIQqgIP-ILt=t^d9pZ{CLsN@DLH{Q7Qxm6PF5W;E_^ee$@y=`FiP z(oSrlxbhC~)qLJc$o5oO#F(OjLZmL$=%GY!vEpo1CDY(ZlPXE5kMq~&(#lMIIGE(T zuE@w0Uj|oNKC{MtIsB78iatd0W51cGv!ghP7e7h3JRe^RhXss=RUz#YOB0Gmfio&yj`2^PG{?kilMvx#Z`xK^j z>a=2tUGIPHi|`vxZFkUWU6`5oKqEgY*#!GGI@@k>EqABk_fibM!OdvFa@v{QA$n=@ z*B}t3;yxib)lOuJOid#GS0HM(KUP+HGWd_r;bxbQTfAA%h1-TMz;-2?5c777he&kx z4s&w`OQV#i5A1V3n%LoRv>}uXU;Dbdll*7xn9g#+h6`gMU19h)+T{z}#Vy1ZhWh&x z`i6yDhRhbO7mp`42OiF4pZ)-q&!mKU!P*&zy(smU#g!D5LD@{E>A*rTU-wMIY=FxFb;y@ArNWT^jq*ls4IMj_-mE2RoFkg`AGhN0lt1w;Xqo0&T zP|)D{qQm%~g|f7WjxOP}`RQ9y^A}2KU5%35m$iW_>CSjPo z1ui1?o;ZXak0QeJ-U0L1#|-?g2NFz!KB0)p!v_7Iq;RVflA*yt>xt*QS6D+44&U~l z#NV+ShgC|dr6eYH90{fkecd?AZ;>|ptf}b4&{tv#LREp`Y3xR)yv-Z#SwbN7hK|0n z-K%gtq+us_+KrLpi+~5whUODz=NQrDD=t}*?G9cvd^i*Sxf}bc52I~YuGG_ZKf9Hs z#tIjov+-W%ALQFH#MBzMYGO`rSV-8d%wpNmj?c8suYEjdWn8**8{-nH=l$&DFcO_i zVHo{0!A4{%S%pxA%jLXn)JnYrn5%o`f@1XK{fQG%Jx3PR5IEZKYoG2b$2|ciVlA%y zDzHkKsRtj?+c;>i3hWB)3YY2YC;P-W>pM|cZTOlXcaX4_5#Nvj}~Ig+vi zDdl7SnW)reInNWUHdW?x>Xo*rD?I)52eVareA~v{RaK6KX+FCAW)og#{NP?h}@vrqqMYoI5g0lPQJ*rJ!_NnqDi0LOa) zgQTv0gf!bnQ=chLJTv=f6k4 zq>zyIo&HqxO^Jzg*f1^%)$j^7H7Dicpd*#WIX22n#=BbLQ1F@b4q%nc!JjcoW!PLF z%P%nH+_d+@s$5@paU|WgYTe=DTMjGMN)eOuYs~Jo>++^3ua2*Insu`L&q^x3q9xhi8x#OxKO$!o-=GD!n)eWP7>Tv%jj@u5*@f-Z1Y&8$B{3 zU4Nrk)UZ#GIrD)!bcDy76gK<%X5}fzZOMpf4moFkmR%bA7FTltT(MiXLZw1?;oS@9 znB?Q!49}gNoeKzDpCioU(&^F|aQhNi)=&Iet&9PR#NA--l`310wW{XvlV@pONVDv-Z z$fVI(uOlJ$l)-=KgjlK~NYr+8O(L(}efwSM-S2h(9H)FR7<%g<&PF0jj#I0oKi$Gf zh?Wxf+=NMBho25=b-WUBDdT zU1f=yfD%*8E_o%=&ZB=;Mq`kaOjfLc%j^Gw=(0KFJDfQEKnRhR(8ag-`3^^eX*J?2 zTF9AAz#XMaSND-C-d_A8djW8LukV{ z3cTKo=5BZ-By*e1Oq1B0n*n^+Q2iLnl+qM**lSjP^0Cv*@`SP7go;96GG5`|UsC9D zo*11;d0?^ouF$L1$u9}*kq1&YC`(#xy)8 zvl=8AaGYDP^{DChF23?N8eQb>w^qqy#-f=xG~U%;?m0eEO1N^=qRxN#T80EeivjtX z{`_VW%Koy&ntLfep>1`E!UE)txN$PSTe~ctYI}S3Ik4;T)27u7;qJ8^!)V zuZ;6mg?`S-kq4C)eBNg#>}YF7-rD+$iO2dVr|0=@SEg3B5@ObMsHG(Yn^Kt!6rqi+ zC6-;#=0H@$q-A`|r~7XgM?OEWJ|vbz1lCKPEQSncD-$32YK`Zc=ld>q##)q&9aV}3 zTuKtqiITj({R~Y*>X4%D^35BvlACZW@b-p-kq0F7^hBVTBOxP0E3V&*Ho5!ar)G+D zz`fa8H~cSZ?^-Wik#%q*Cf;XI&B!Y#U?e0Z$+^3W9Bj?p04SZON(+x6qy=STqBtU5 z$|rA}yF_=s!cM>1ee1oV*JH2!fxG5YrB-S>bJfo1U(`SJrauck+vN;8+%UU(e-R;z z=sQkbI9Do?-=XxsNqUYM*qgzK6FkhPXhmkyuyUej#2J+XgZ8Hg!k&F+D-)tH%<%vH zwVod@qqJ1$>2x{x>$t0ZB0D>K+s|*=yuD(Wn3w`jx=D@->i0xbij%n4-Y1jz)?Z*@M6>Y7+Jx*i?B0n-ApBbI z-D8EB`tB+oZ3M1CIi(Da7Xq5jGw>)Sy~_`X+&#SmH;1X7L{tt(LlVDmza=;QI&qBq)FcQpV1hMgTFIM`Jr#514@VAm{ zNHR_QqAYw-PZ;)h7{QP($4~MLk@4`gx5n*xSS4&FWLTFv>j)~pk;djTL>n=$3rs*- zRg9xIy}3E`xS)Witn}qef}h`W;tg*qOERolY|T^+70^lPNmk)?kc113dG7VF54gaF zX~Vq?(`?ec!Xf-4`TG0@Feqw!XQ!Nz5e+U6`=T})KKa?v=2ROQ*|)c0+9FP!aS(jh z)qZm`P#fB`!pz$!l-J35U(^r&jTqt+#3~%`WV_q;>8}N1)5(z=Sla~;DJHn6)#Z1| zAdrD9h^Q6%>W+mvc~^R~imIxGHY-$4jO|^9ln)gaF+IWA@y?A@q4s_FQ#m@_Tps1( zq^2h6zK~YB0R@EM%Sj=1uEtRZ41@+3mC&4|Y6Dm)+RF3^PiUhvjUFrud+F zhX-_r>TU$0!VcQ4b0TmaE1HS^6dL`#Ruk@71C#2mi`ob5w(a)lH>@(;gJHR@S7KX-?8kRpvdl{9pl zDQKmwx^CHx^6#Y*TPnR`1dh)c+Cp__0;|m3)<&9rK zrduKI6na!`{TDIsV66_G2Rhw+x6Mq$8GQ-K4DP*@5I6OZaes;ruC1Pqn|yHgQM+4( zt-zFs4kvY_t@+kehTsRr10q}=hR!iaaUBR5=2RxHiIuXc7pmIS*@w*v8uGj3e3WLC zV3b30XnhgRx?LO3yNMiR!Bh1oNxkloienL4wdS=|%EIor-cXS-q) zZH(5zj+loy!J0D27wdIxJp1#!nDA-m&p&8BwpJ{He=UkWwu^npwLUI{A|E1wM%T z7d}XF64Rf!(^V|nw|G(0-7!2e8W5|dh|X8-us#x`3i`FFAkcpKMag9Al3hh?qg@Xp z(+3&4I56gjKVyd3M6^5!U17h-bZbUoE2xd|Lpdv^Cr=d%P1wK=mm(g=$)BuiNw~a! zNUJF)2~R~XqfNK^d9*)~H}8x4?)46F6n7|_$_>5AEM#X4k{l&;}5n@CxF z3ANfyZQHh>r~qv3!Rd9po%FGb$r4KeXfulEW=R)x1&DU?! zI|V#SheiIDgY)IN7qzGpX z8X4hDO-&6~Ihsw@dzH;9agq&xFZI9h{y9~aW7|Mxyz;otJ4HDxs>mppw(h5%EPwXa@Md&@hV+Hb z{0)XnD=Vwv@@Lv!W(8}LTpH@?;oq{AjT2n)@bIABub2=g%kgc)ney=QLgVP93dwUs zn>BrYZ?EcV&(cTU;>O=xk{1WxL9xn`%pm51QR}fo6o2nG2YCwMoLwNMUD1@>AKf;_ z`z@<1yNGHAX$VVjXAlFa$OG!<7V6R#ICA7P-08Zd2H#9*8JG*54Y60jejJIL^Pp<4 zz7S}ibCsYwxhwG46f>Own~MK8P0`hvVnkKxmT`x+0b;Xks8k@8H-Xsyz$LRQ*JEcs z?@)C!Q6pXQCIC3Ry|15r|I(7Do1fw-R}zxWc}M9bHEM?6(M|iQQcNLX;SO8s|H3A5 zOf?9EQ*Lf9inO%!)A53LCJ_^Ye!pK>b9*0YKAFnS6frz2sK-T~gz5B**QwtdhMr?c z%^;?n?rn}Jx^FKYUd#L#A5DIQrK&9`wmCrr>m!$j{i?eO6HHT5M^`th!AYip-#8Oa+7Ki1ZSwZ4DVW%9Xvbh@8<^Ngz3G#`~I1NPZ*J@hMqnxSwD ziO0^C)1q0+3ooyVkz6lo+psrxq~+)9r0C{*v+d+{$4~wOmgJv_`lhdsx1`Pm;Zoe( zeFZ!$Ea*T?vDE7%9g6UJaCWpM%&ojbG*l=j7@DbeC*61NeiBRVWgMRNy%JZUh)v*?I(i6C`UAl%KmP^ zrEj(8F7rMV2uAUb@v*}Orz`B-xp zZX?fSbOplev2U+ggEXu9TM1-E5^36^gi(Tck5QtpJhU&nyhp>)iR)2D3jHjEGZ^{! zh~_<)2|a(jRyL@%KU^QPKFspeWZ~e5gq#h_6ALntQ&F*ryw;Lf2q&cN@7>?qgARX` z<>`+M#yuXBi5~`X$yB#&y+7TDoHQ;}MTT$!ErqPA=n&j(j$0W%+hT0)bd&}b5aq&p zK9Pp2%QJgEe#dZRoS$~(yIr4P)yW7~++o3|9OQb%_Ot{uLfQT6Thr!T*xE-oppkXO zN+ztc#9tmf$fHcQN+*(yM9gxvk|8(VT-?NiYg_@RcX{C0%pPS1R+V#;B-p-(Y!)Pz)v29WkSxtxpB_QWN1Sd}Lrjyjq&+9M;5^}wt4bh^> zjNn_#jbZhB z)4$M11R-0Q+&~t{C7jSGm>}grCSd_uWMv%xvoO6?8nIf5EhN1_(fFQ@j z#T7lU7A9P~{3I*%4Egb%zfqTXu0Q^ES{ddVbhzk#>BM?pNZ({_a2)eWN1)*8SEJ&w z9$6Ghx3qydWzscAE^h7+AZ+%YRX-Vg#Uwx3o+jEwVfLWdVWx7A`5U`>8gxy}_e5Z( z%cVfs$=b~%4lBMZ>|IQZUBhcn0zUna4V-8LAG6P015{5VDn5JTOd#>z?ho|#ch_^D zE3M0h&LaWGE=0!y=!9hx9e{c{d+QI;51^8}mCSUL1S7}%H;hR|H1R0Y%zZ)4KV0YG zSYtn3{tRY2#wC);uHG%?wyvXh&$5$19Rj{vgsTV6$NEiKfR zmKJMsDc>EC086Gu6$={pEi_D+^ovZ)WBACok$`783OkbfdO2%JtFKr!2SS$L!E8Z2 z)F`ospKz0_-FjU`7bI$?1nK$S&^>HV@ z%RA}4FbT(Mnd)(_d4G9vR_15IhAr==(wD@$682H>Q;tay*1~=#VP8!@iQP_&C^JlR zv!lH|vLh7#IwOBxW<^3rt-D+=6JdzST3fBLjHvuZQiiq?+GiHR`6{Qo{o1TPh3fSK zl7@61Q<*n5qbMmJOHTAWyjt!QIgy#@?RT+i z{`+t0i`%Eqn2(Bp_*!N&L=}U3Lmte{w+CGhu9u*5oQX7HLtB@S`B-lN%DJa6x(-b~ zh=GoYd5vxSM<>UBbMmQ-d~3$@2=ssv; zH1PgT2oQBk{nQM)ObS>ZBy~F=PDV#{*gOSn@a1388Sgl3_!UATj_KPHQx?^$8Ib3g zskrI&p~udGKUEf&NscenAwa zx~VBWIj<`{W zdkLIiCxU+uIO&$@J)FmK%HWI;K{yyBQxUNB_&!q6y~Se8O)^37WQl9L%AQx&4lZ*i z?HRT#N!-6@I6EmgnmHx?JOosNH-#a56k;Oq939w=muJSK-i2|8SYPYe4s>p$nS&eM zBESa8PL4}P0vcsPts8F^4;SHT1{Djx`Rv7LTc{i=AFSLF_!5^(rRyYGx%W;bPbD0^<-%~=EL2#mI%w zqR%$soAKv$tQ7V5JVI=?JE*_Bb0_m;M>~i>(umN&El4)??ykG1N(5}-t3*iU1$W!?EvE`S{93#+oFtx|k zP~PsdhrVb>J~kdaR{C-`9sy{_mYskrA5VDLjmb|=X=mGY8m5gX`eIFM={`Ti8?ye) zSEEJO=cRmv>1Kdc@tBQIQ%L>Z`wmYBCQ5pYc%M1P}0M{udi&Wpvya z6G3tsRBM-KI}v$#?-ljFg@n=bHiSR`qzB8=q(F}0$)CK^9Cv6Ouj1zFQ56S#y*2N`+ zm17d#zdU=095R(9UcMpqzdzSIPNZOdxOyZAySo;dRUr;4H352iV_G7~5!_EB(-mv8 zL8jZ-vYxbH&`vKFXKP&FMf4605zqUdIn+GgoGcLl37vzJGw5H;+Mm@joC^7MI)&IS zic&LZsQ%2*|M2vtYTo9pY}&n+gnLv3B_0!z`BJg6y@VvjHJA;v#K8y=5PLu>w}4E$ z=+Sfrq1EzSQQdk&$;ruSKOJ7TT^ke2(e71p5clWA`q>e8!HEs+iF!CJ4n-l?muiy^ zO|WC{utpZiPHwTJi$3JXk0&*;d+(j-yAC%d){` zmgi25*Yd&|ZC_8&x#G->@$npE; z4cL1bPtR&eW=PH{=?who0TLih{4{LUTCbPn<&A~V($VoG19%dg;NTQHXVsS^`$u#5 z-|=c8N~3#m6qNA;S3W}NVNikb9oHYu3KF04Q=4IH0RYL{bn4^tojq9gr1?f91y>CU zOaH?6xE9vb>q1H}z`1d<(cZ4GnkhGI>9*L6dQ=PEv{!1+_7)dFJ#E*IfhYdeLw75L z`oGB))2u+B0pabR#Qk(G?xYWUF?LuBY&41!B6}5l%(qX-QhVH0SieFgXSMuQXo)MZ zzn)YN8`V9%@V||rkH>S1nK{_2w0#et7K3UhCUSLPbg3kf!YLvc$x_6xw8c@!54FIP zW%@*+L@agi%C~^bj#*`^p&*D!jc--7I({W|<6lcuZ>zhQBlK&}LZ4~=w-Vt+i(TE4 zcm3bw>sns83#Il&OMUc^M){KV{#E?l%&{{#D7ed-Q%2k24{L43#5ENtcvE6392f4D z?U^=s1IHjfqlidS*jYgo{Q=bP;&4L1|J<`?vt}*5j6}*dcLlnu6-Kvfq$u#e>TjiL ztbax2Tik~mN6mIEZ7DF@CN~m{v^msAhthT`HO3!#wu5NQDShsyj7VF57xZK?s%J1# zqTm&MPohl8)h8%>ak9ItX<&du&ZY+Af{8dxw;v_enEWJt@bIBkdLhyX2}`H>Db=PG zYVrhbwvsESP_Os;)2CZV4)2MLP1&)8&k+v+y(IO~&H}#(s|m_~_Eq_luESEv6qrpT zfE}p_%pVCRH&T04Sbsq!&%GT)1y)#JMaM-C)Z_8a5j)B}EdNOID9JKdA`VZ%aTE|( z1$YIsvnJQYGMaeK$B!uC#0-ND++Nc}Hkmgha6py^ zW!KMZC=UdS<}|MU!d5zN3cVE9up0gGSE|CzoNI7m=m$T_4;$0HLSbxp% z|2gD6TZ!lhBeT(JCh(Mz;8*wMXJ~I)CJy!`rCPGS9yj0qR~kw42=3t+2sqo3HS)p8 z?i-*Ud~jbp*Awx-mdolw*7yt|gJ5wTj69_P<{^=DuhYRBg>z z1c_|Ln;>hygQ+W+7{qBOLcO$INUDz;fcpKj6&1juCJqsG|F7XDx_?@+X_1fsWx;v} z?*;TSlTy=`gFIF66RkOP_Uxxa@z`UiDg;;anI91kss1!v{lEg5m;ZyJox+g1-^s5N zwx=u7fl>LUa7#GiP^aXkJeLG^r==7nym?KwHjzi9EQWg%f$=BM$+!goCm2-NQl@@A z;tx2*zim5;1JG4KGw_h&+Km^Oe?KBmSNxL{(j2;?Qf)q({a^>s_h5%un(i_FN+({) z&A_i{YEx!`Oxsm}YCHz4gT`2NA4la29Ge+9=bv%%ks65Jk>*1W>_b&hR&E2d<7Dqr zwLOaZ_xP1+-)6w+cF5!2{fpTKOVJfagIVlSa^;-Iq+RIJ>b>;rJ6}Cl3U=PHtT4?V zg`*_aSd@taRYfw^bdwRsv5gfi-*KVw)!Vl$RH@FtMp!GE#o%Ipm%>f=PbLz$03JMP z%>x>Ofr|yX&N~8&GFwV_`j=g2<9PWO1F~GOdo@oVJB34xWcb}lLaX3pL5iN(e^UK7 z5((A3Ug-1QA)X*e$5>q*o1C|QWTS%_zkZeoPuU0vf`--7sZ^I`uS^s`E zr2#H3F5+i)eCY&$F^J=)E68^31|JR)5tR{Hy3C)zuG@9Zr?DUa3mw$%)xO{a?p^HZD#xK- zV7&ea+~#r*TFL(&Ff8sr5*LDpj{Mnu3g=@k_)WMPxkS)8`Kdq%$3O^)FmkJTL|k#> zCgFr2gdRb}mqm~3T0yzY(>sS7ozM30J*-JZMFmIlXwvdknu$bC>fZZduaf_WBz7yR zG{40R>}+=4ABH}_q$0*{1T>b@h4%nKFVY1xTOhn5qUj9P zJu3`h6tHAh8N2GwrPAW~0z{)L>_`4-UbHtXhlm_y`Q3B13=9dxSSRS_3kH4{V_>30 zr~HvW;^@TC=IT6b#5w^XYx7m$8c4OC?ypVR{TGzNjF-L?eMv2d79A6_Vww2S!v<*h z)>fIBnXo54WL{UWFjS&f)c$%X6PZ5HoAX&g0zRaqbW3vJch z8yU9u9~Kh0mJjEz_S5mSkFO2q>2goCg{HI9O?H+X(H|8}O^aDtT3R_yf0PY@UY?&0 zHw6S#N_!%pk#SVUrC+VWQHFZv3n_F+r2`ZfAn_cu;u>7;>IkuW%{n)!@E7-H` zQf6&{Zcwy?YV%NQ5EfDD^=OoSrIw7P--(!a`rItX%*>pEt;{ntG-Q*>M)5xw&@}k8 zvzll20e?d~{Si(y-sf)5pP3OqEE6ZmIBbi@nn}Khz9&9DJ-A=#^utxgxcaf^N5Z!E zbaoTgg=v;sX`(7|0qN99iY*c5GUsPM-f9TN-;kc4UW++vwkaE^(Rb77$gSrj!KAhU8K|TYmrEC^kPo*>#z69g?zP z@*dUfYgx+16I-f?hVFUl=_MH&Dk)*ndRi0j&e~?6dnZ@JWWSvP8L!uEX_wA!h0b`* z_ju03aMEcKW^T`*AN%gEBmKd~gvN8rjs1$_`N7W5X!tigDwCR(J?a0HypgjvFj*|W z^qGeI>XDX_Reb0f6w)`fSSkV*ji*`VW^B@M-v!A0+j71*%N*i#4|8~whkAgdV#qfX zic1c_-NRIo52fv0S4C6uw}2#|jKZ#_*iy)9FS=PH??RNWehHCJNo$ zv_J9(JvdhI@{6E-FoKA!KfO;l$}cV zEu+eKQ-yQ2gs7{^duBd6TlOH8xNpzm0va^DzFx8K7NUw0$V2& zry=8Kxb3L(u8+zhDQs-MOQ!bOCHG@)&$Ej~#W1*{Xi4LfZU*_ zrUvOm5h!VHsm}u4MP;vDKS+3l3)>8KyD@W=o=6&;=yMj4RM=6r=s*Z8EpiF=UxQYh z{`JBS@`Wbnbcm_AQ%!0Y1*RO|@g|_&sGUdVe$bC9bj{LiUp{>*cm90&9v)X*;n2jq zj|6Qp9uM84XhChkt7sQkc@T0dx9vZftwjmRW&@Q8;1`3k@@Vc#%L@eqhyqoqZc;Mo zxS&#-a?R5B+Y&8|VO%R5NNeXt;wYPa(&GaUJ>Hb9zmFt^?ZIqc$e zD8PN=l}gt0>%}kG_N!ja)2Ax{lqg7|{a!tpD&b0nyN)Tg_IkIimfHl7B(oXk1c)`B z-gK;E82^JB!Gp}@XgcKt#Rfmfv*30OBRT8pWK~N_Bu!mj`@wEZVu?l6<)YjqfMbO* zg^w3qzSRuy$4Dy89!0xmiD$aYcsoMse;|s*JSC_p@vm3$nW#Gp;cq2h-x<3x1}b`E zY|75*XOy2>(KRWq0+4jsoD7#R1KT#QXWNAnM#H2m$vhS(NTr~qCL^DXVQz~+40K zWr~J|@8lnRBl+FMiiR)C8h?NLgScC8)A4m_`C@ppiIgjxU^XxKo1&AW+4q{Q?Lb3VC6 zuD4Z56gptjI+-;Psq+HkB_}_!%4#Bd^z}CxLwaSK;VVcZ?w4W&9e4IOgPe{;XSj_C zeH}_15w79SlvH9w!yz`Ni=?aq}!q4OIwgv{O!C1#y{hnys4RQ)WZfhSrdW)UMPbIdi<+bdH)MbONGM{D-7+3wga2Bxl*;?wC zuhOuvGVoXrWSCX;R42lwx>b+EPK;rc79ujeUOScAsEiMKzXVG{Sx~Ww=(>-@#xbar ztP`>c3M*KA@xcTfKtG5&2YZEU4g)hu3&5(GAQxF^S2Z{2M{>ZN%x&xMVMrOIlLc*K zNJvV_xQ`MZJj$%X3#0TdZXFss&p>J875H$IIDFDSC|&$+fM-X|Oo&hqd>-TwI7ib0WPrjK8UI~JU;DH>u~Jx$~x3poF8Bp?Bnzx>%k zBjL_te2Maw)@Cpbw=JAdIDg{Lo}XD%k!cc!|D%;N0%J!0+h~oT-QoO-Y;@v=M~~ef ziOSD8B|^5tK{cAi^s2e`p{gogOwDp=u4op?TF1yA;(cS0PLIXn3$XvDE#s}#%Izfl z+H41W#CAY%LYb*#y=iqTk%r7aV*>n53Y4_XC99fAGUR%LlBK!%4g6w!N_!$gt|!WU zw#|KKE!pJ)P>iyQqE2*uO)gY})LHKjaQU7#N#3G3{^ zBb{*&GLDKw1f)l(bp2AOP#!GpP70A^-G`zG257G#e)T~t_tRVmuqq-$0kYNBY|UF< z+QqM0A)yY}13~%fbrUiEKaM<~lN%g&5<(JaQNpESk&+LV_U}ns)+B!VZ5Dn0?sulQuYxp}=%T z6cbSw`g<}HI2nT(X@Val5~xsc zMJOkPX*-?9IT304I>j`hB+|()a(_x$8p0SEz6kc+n)H>Ssm!}!dgMR`hzKtHfVJ@2 z1qV|4;tNwYm5ItAreCkYvQvVp`Y?R#y?}cuZw-q-LF#%fpV91qQ(eIK#0l8?X^a=* zhpCVc>WRD1kC#1$5vRafpBy1=k9jA+N$0K`if$aFlfq2DE<#t*M*BZ8`A_a{geq(4 z;`WPG>i`Fs)991#ZfX241@C}|S#<%j%8gL#nu9puk27 z%%o5HUx<2Kpn!oE1989;^^@`0K-~WAEXX__xMy`Zu%Z@Z*$(+Y3xij3q0@5wkYf6+ z$j0hq-rkq3c^BgzE&Ng#1n)9H%o{<>oumP5!F=^HTKFlt)I71H62E(O2+;N7RtQ{M z+uGnk*z|#skvKI38ySEE@mkPANFFtd*wV5iwH5E5Oew-PaZ`56Lvxzf4$7Xz!)v<1 z4+!N1fRM31RQ369$z>kp4~QvF->fz?MInFN__{%lp?xU4FS#<%+3`DYiLT=W_D)9x zjt_so7)JLlX@k6^m%46xxBw7d9>@YyW<=vnfQZ>^%ob&)*sPE>50>kEBJ{4o{l<6^ zad9^IwSY~2GSCweFLgu>dI$O(61uY3?Ln*HaG4F@C_ok4fC?Ie_B6ea#M7ZgSNyKs zN6TRn;A@@|p$;C&4;w3)2N>*PC`bpUFRAAGbH)D^#8l=Pz0AB=S5KLCgOXJMp=_dH}nFO#FHDr!D!S%PjDnJPnHEhPfE30zWcWq6j=B-_(Ih` zi1(bO0qL+zS6#tA3imU%O3kjgI_OHN|Gl1%IQXuS8l`BJnw77ueHO7b z+z7}!VbW_?rO9c!YQmPN=(m$MtPg(p?Nb9qhXK=UrnXv$6El{NpzwPf)y9DNLNbk@QoQ6Cssg2HeWzdV!vdFf_<^AH{;cEB7ciH~Z{ zn*3kAc_e(;)BTzSj)1?{B?WR(=NA^x6>gsO1eE`G*n?@zVbABpIe2&yj$eaXyaoL3 zK(V;nYbn9Zf~q5$F!DxaUtdYkHKJ5809XblUS2{jE-pq<(Uh>8iCbSZGKj!$2=LsF zUb=6X6JFuM+AHGuyk6;mC~u6rL~on0S^@WU^Bxg6)V%W{j}DufUw#-ipZWOSBtOuD zX>U{mFt?tC6YHY_fxY=lneRJ|cOr16;FzL@P+dJeInbjtwc)kD+5)U?lXmB4K+!Il z0L}82Td)4<5#e+#)1>BLpYFT>pimCkl(DP`i=F;bP<32uSZ3|CzxvQCBisIasnr89 zbBL5{772N=@m2*{$?SB+KA~$laKWmJ863*0J=LGV83KEKf_AG~$Ct9ReITJhPuo2J z_1$hUcWcm4unx>vvY#6Psurw2BV?MZbqfLYAk}nR6V9c>LZcM9R!Z7{Y-Tf1xU#>s z&SW1vf?oo=^E;e6mz8LfqW1I@63m!syL#{&45U`H_0K;qwmk8w04?4IUCy6ojc5n6 zRo91A^*#X}f}ne=|Y@TQRh(DlkcaafBk-7)ZC zV6_!9@YP}Jnl7PJ^Bn5!72@ve?hd@?_d6xgi~L`U*FqU^snqmRy1>q^mWFqFf8a^+ z*kOAS3gvo}eFLsz4Z{(mgzsC>Yr%$v>^;)kUR&$xbza9J!V?S#2uRWn6*EwU-@?Od zjGt#EApi2^%lk2wB|+x#_PD(}aiQQBIe0fg?+f!mSIb7{ahE1*xU`^2&ba!la?1Ovw++#;NIUZR*tui}W-_%1>;zg7+DUH#Vor1OQny*<@zCe?Eqp%)vxvFpn&T z3unv|Uc$uPXv+ybfrbCBymHI-4^(iR_zlSP#!u8k;*jpUhDkV|i;GLjE6q3@1!PNj zdPruQYzS6~097k*Uwt9TAMT2s&`YS3tX7Z+sn=@Z}-bE6l?j zkCzaad#096Q#=-RiLwHIFo9<{7;@dF^jEF{bx*`oKuGPu`u5j`$`pm1dD%^3aBbRI zB_qHTYfNj|a)g{l=)o}DDfAs92m;?q*u9yI?a>H);hO9jsVn&`LKqmK!@g|ha*;p4 zk*h+o5{JbBx{!76tBYfKU0upqzvDS;w@{yNI$bj;l2*!lW7)$}n|^Es(_SQ=r_>Txi`JFl!A!OO~(7#rR2)%HwDjUPvC#j5D|N zC@2hHJ?^G3)+L}^S|5ANb+9qCea1SGOYj|YX%((6Ty_)OE@y%7$^Il0e~+7=jP|>A z8pfU}w8{rMU#b7g-;Cbfr`rbkAxvqv;(GlxE)kwE|A z<0)G6C;~e|V$%s5tQ4nch+>VV=WU8NZH*CT=Z(QpsC^%mbqc~#)+r&x+Lp}FxlE~7 zZ&LADvHBDva9j0}2u$?z@)$}{rR7A}Ezqe<4QlBNpAa(x?c7$U#s8-LAG zyHj9j1Zkv81SAA$1f)X*0Rd@{uA##KM3L^0?(XjH&Y`=XjrZ@I`~2_E^WwZXzEOu6 zu50#Q*WPQb{f#0@>hGqZeLLZ~yS60Y0$C-HFKB5!GBhlQB&Z8QIQ3IESYfDh#xxnW z5uuq{*&VTC>UyyC`x10B zTawOfKTOy(#f>7SkhJ>>h_;As@a*6lb!{9v1&Z1V9$V1Y}Lt9Xkw_%@KnzEf>d`hpgvx zA5DBI5*#e*a{}-aXVv?xs)w^n@Qn%!S1g!+E!4o#`ZWaXSGXgj`tiRFdO8~@z3Y34 zhKK8Rg!_(=*pL24Vjwl@42W`3z!w3+OSBKyNm)5n{q;dcvCHv-X$fP>lK1&0Luc?6 z8);-cn(Et($=Pgy5o{%}8U}Ua3*gmLV9T%tgu@*hRo@$LmT-4VympLK^hX;qDtso0 ze5Nmgg7lpiBZ>e~#S27w{r%nN3vk}I2vGCJM9FXthmYVkCjT4gR^Q`4W(hY(O`F0+ z%1PnECTq2a|H}wUOf4+Z*=JShK>a91q5&$UQy+Nl$M<3*u8!E(LV1+^;u#->Z^S;7 zy8^xO#op6qINNFl(PicuaKYBvhiZse|MHPaayYdw0Z$vw;G{0zjhz#T5HM}WNY zDD@iOncM=ZK`lJ%pA6s4{dLI&#(aQrL-ziX!?#}8Svx43-^8hfv8H)(BTcVxLsw`v zD{BU^vcC19dA^Q|3XWz#R-bg$p|MNIss)Iv13lLfz8gg-s zr#^Qw$183@iwjeBJw*K_r-kJ+Qy(yJOVXqhy+mxBBVX1?R>OiBvlroiQNl=5Q7a+x z)oj<6OX>~s`;t_hA46xgx}XngX1PYor2D|^%2Y~x?^PAmbVbCXQ8@7rP5Xi7ZnQa= z{9e9gN%Aw078?ZA9oIxZ%ftTPqB`>%lWv113DfO60+na`xqs@>0sX4&n!jYZR8} z-7$JtZ4B_C&_`{B)B&hv0s2DofIOJxX`3&H<;{0@3kZ)s z`zLAX>EfW7N4^zlByC!=HIga$;lopm@Dvx-@ob}f-QZ%Z-{gPr>ijHDVAU*s(&4FHdGd{4+E6lIQECJobNC+ah%|1{1{ZzmDqpmywr1 zTWcv2@J)XL(qDJ*+~yC0fH;>qi$C9k*2W7GY~oVK>OMPX0*ct?kDcLkjO$!h8Q2_) z<^z`j^m8o-BIMMFZX8ZX%*)cL01OkMrqL(v9^vVPlGU~fY-))u3Ib2m7L`bh@k&Lk z|eogm3>UL!M z06cIrocFK$*OQbNlO;_~Z}ICyO)mJj(f$eAd^C(@~v3jI!Q!Kp(&Jq zX~!w9!0bhP{UcOt9n52RVjTlSR~gb9ToQC)C5S(UQ~`$4#00jDq29O@Y3+Goi%##@ z4p1(L`QXutm3Ry-z#5j;n->>XkB_+nMO@_!W57N{0AI$k5WXn}tB$f;H z9`Dy2t2FzY)8(M=?I!p@^o_xo_%#~OQ5y1z-|)VI-NFmE6wza%WP~X2`hn(7kkXXO z8|;9`uc9cfF>Z=?QQ|5c)4xkatr%|i8)_xi5~#Ajt9HbD2Zd3;1BY~z2+n}a@qW$I z(=(4E(|R!p_n}QKC>1x6N~pLj`Ex(@9I?eeJ3GcB+9fQAwuqL zGJ-*n62@Mm@Yip8U=~d`@ZXRQkulqi|0o-x1-+_}-@8%PdOmrQG`Pg|i1lc?m@O43 zS|F{E-b01%8~f4RXyLyj(Q+f04UUKSJAyiC5$ z50C1q`}P6TiAT`HXYsRme%_LhiD_|Al7O5%cN$qTp#_R#mU;n%nlM4TSp}$qnbhH49<%a~T>e>UwYcxXVTm;IRiq#pqu zj*_Kh`;Gp9SOd?u1uaHDL1kce9}ILx;1Q59l_|27K!3vSFM>&b`DILF#PW7R{-2hu zR1-MNbx69#(9G?D6Luzr_wq4x@x_g{7D*{;hLuioJ*u6$$m{9Hn3i8?4GrGstP_im z_W&&5Z=E$ZkWdA?YHD{kN$@WLS^^80?2yP`53(pCr=x0i3Ho4R2z8=2g*N`wxdzmx z_wqJck8hDlLn49|c*DU#zNTtC&PHUQ=Kay#mtmuWUH67WT+tg%*w4_k*=h2p zXDbVd_*u-gIIdfZ84_{-hm_YEwa5L!YZC&cK+bP3>RgHwITE1$f6tY-Dh4XT&HX5J zbCu`Ns!kQ7coke?E<^rN=6pXe?cfdW;ys)DPQ{~kL>qNIMAyX#)Hu9qJdKxDfrV)< z0!eo4)7uSCk7H3K_Q4o_aEuQmU{q`br~kd(dky!VSvfhEjv8F$I28pn4j~8;zGIj**B*%ww(4`Yml#Qcv1n zQO`25a0^3;VYbNsl#a|0HpLO|WO3c?M^fMLf8CxPt@YUbWc=;YoTne@qSs-`8rX?o zvb1o=yPQ+!#epioL#~RwWzw2CF^9uaITw-htW&TAW!ZS5QK?C+2}(l_E?GeQHgO-* zKfg153+tGGnAU}o1A4>U*hm}K^s%msdFsS7UahAsw)Qn+U79w9enmt4R;hY_g4mQJLMMKaK($|qqH#5?4cXl}~pU5$J zVS}om_i?k)ams$gOpv2b+9Q93~XW^|x7*5R7zB%jC@&LFI!k*~+O30^R%bP~~FdBA1|b+zs{S4<5Gl zOxXQ2ybpprzZ$nZF5KT%2GT^lkm1Ba8fYO2Xt%3xrz!Xf#dx-ISXt=s>C-Oj-Cyk1 z)H6}q@p;XyPbEmxOP$5s{>K19gx?kxUq~YY6&9WsGGPtq$^N?Jm!t{0S^k?ii_%*P zMd{_cSqSe?ypuPP(;&hANu5NTjOIv~VW?%eYF2owL53Gx%#VyC+FQQslo22c{lz~1 zvW6z3hi#N38{5EtL$dN;4meISTt>0Af1&v#CGR8uycJHHJaLfO2!&j-?@+`)sQR_y ze>n15r3hw-i9(LdEQwqufwclWlzs%7?AoP4yMOfS;vrB&e|iATPtP_)4}X>i-LL!G z;4M9=)c$PH`nyuX_Es`%5qHlI9B!-OdJE%r8#YO-H+8Ef-Oz+o9C^AwG|z?+OLE5F_4E+E3GVo@IqXv@`UbWbsKk z^t`)oUnvupB87O}5LsGJZFZCy#drRBvP9s~P0YUEfTo_W zbL_X~_*S{Y1Rm%xoj(TR%Cl$P6nPIF-g&wc<|Q&`)c*L0o>6K669Gltht76+qOMh`|*AFrtPRMzLZrxnN%me$iNc z!#-@AmKaEerDpQcpeGXsmj80PSY!Uyy-%&t?b6jwK5HAng1#jZKk|7%4?%m=7Ds)6 z|2|*K6_s;KSYmO~K(p%R#hc)<-CW$`CMoUK-&*2BZT1PadgAp-T^O?(NjKQ3mURQ{^TwRLWi3hiCN+s?qc2}2<(VGjoIMQP5YMHjTLD~8$ zMV!3NRO1~s0pCs}l~uDLI8gn)j-d;IEFn+CZaUxOcbCRYzj)D(Wa_c_t83pq{Y^Mi zR#Dy3rqtftb>Htd=}KVi6TZ?Q^Hn`h@z9H zIbDQ6fQGk!ZIXaxQ*hb%shC(|{$+>j19t2p0_V&2Oa(_TkY2v}7Z23B>i?GqYW+s2 zQv3AteqG1%i2ue=Gs4SiN_aDZ_@>4D`n#;&7C(*ob&In_&2s6B#=Uemu z19#+06Xd4wJqWA+*B?RK*T}jqUOW`nF!`YP5@e13$iOaxOo@p@La>3vc4dE3vz2MQ|Ae^O8d)&@Z5W9s>nJQMcuhf^Rv7k8k8 zOCSuD`rikh3YAIcakX<+~$vRu!``K`8ixVR3FNa ztW;8lprYl7b9=u#hvGn>S&ecadd=s0{l#iv2KN3~VtZy(LGS2`0yUPFgiW$PnJo1S z39LG22`*&#IAfE>_Bx%t_BtPojLD2iv`A8K^$Q%!z%)cW#kyHYJaa`l}71(rxy+jHzE*1iJ2 z=yjkOXs)qelS3Suu@@xc*7u*FtK})EUK+_qal>vSmgU4FR&9J|V+t-rFrk9Bgjn{5 zIYd}Dh^}9sP~Sq+mD#4Cx4Ac*&Tp8J|2)MX`4?(&haD9PCI%WoK(=_YN*vW@h@=sF&_Ixcslv{fLYVrt zi*kYnRJ#w$evp)EF4+h>cpW5o<<(|?w>L@g;^^UI^pE>1{8G9t$w#~S2i12*yz{}hAfwRufMEG1C z(HQv6Bg=wE>_kGw!3i>M94@rIuTD!RO2{ZlQ8Yb4N#`s1(#Yb47SH-c&C-h?0^<=0 z6%A8&T}rh)6)10MCicfy(T7IZS9gg_B3m;XqS5DTwrPsDaCar;#^*R4TsBQl!`^;+ zMfh9mIxjtZK@%#~e>zDtidvEOr1ia}ZJAc+)srP*d`nOkS->c(#jk&GEGpC zSqjGp3OjC{fAqQc#F^KVU=?tNkbilbeIsYrSCsnNe!;N1JNDSo0Z9)see{gSG@}CB z-u7UR6J?~mT(DRCuFyv|L4@FLgx`3gH&si31Ct=epml@XI#fdaKGA~nR2iaCJz-+t zLg(JkL$j8HjI=h5ve%RGZNLw=YU`W#7!aDX*79Pe`5Y;D(PyJpzzQG;eKPlr~hhyTmpD5M6hxPkmEJ7Ps$4mYG{@AlB-DUP;`CN7SBAt4e$V1;0B(`nOf z6rU&AO-6n|Us#Kl2tVrAm;}j&(`6&U0v%#sr*GkD+`~D;wfL z_zrT7ZYM)Br?FARMb9Ur^Ck?u<_uYJhfi5A+h%mh9w{{UprX1X-_9Y=ib4d?e=5x+ zS0B#zy%zRk*x8hWzDKu~-EVxBGpIJP~fn-Uwbz?g}Q zA%fx)9vZOv#ae$*85yji>88l`r1WRf%S2>dlHIkM?(6F_q}+0gxmf;KQ1wVbTWr<; z25!M+Rv03{VD+?^InO?A7~fIWr%Gs40jsn7m9OUNtGsjPR)II(Os_xji=R0I#Xb{M zrIVIE9Zi2F6QcF)O{-Z>6ip6i7w`<;B~qJ=YNC=hAYNzgHRVvbANDPCr+}EZ&Te{F zBgAT--!VTZ?UKPmb6AW#Ay=j>?_lm%a3g}c)t^UP=y0w~JAC-UpjN?j@cn@Fn+u!5 zzH_$Pjc30wG(0@&0}ZU{m{tQQ@G$J+_}b)ts9nJ8eyYfd-#{owNu-|;3=-Ak$22$jM`}rIZ^za zM~$zdg?dHpFrc*Lcu@t?+P{$*D)P^TKfVGV$CU^x)^4O7wl^@S%}X3})X7S{Bd_-v zNKTx2!LC)eam7%cPPsM6X3e@*za53E&_hKP`zNh=eg^v|0tFY%pb}w*)=$bs?4RDL zsKKYLWtJNON_3BjFGXHs*>f7jfz53u|2fqnY%p3m{5Q(=)0x5#86`tT*wRzu%TSZk z$?XMif=>!T0)M2(71(li_5zqfM`_^Xvj09vt8^5)qgr%&e^L!<`_g>|>1%!S7R8Kn zIy$aKd`6mMS5!@Z+dAfMnM3sQubc$&hnsB$TG23W6S$aQ-td?&>E{4LJRqI4xAFAckl-z+{G*)&%v+(@)g+Uuu|xU~G=9IA`XJP-LMbp4;? zi!nFfVd%Iow10N?dn1;ZjoKTEUtsOHo1e;3xI&|OJkTUIjvLs zH^?E&wCAmSYxH9ewOMFY?(dxt7FHMWHMsojPVT#-RKRNpRBE)}T;Yqu(74|?V{pn4 zPRiK2+k=>Y_&9DPZlpDD1#v1Ntwn-g+$X3JG` zQd2KlD0HVPL&(>YjIS>Epn{brQev%P7i5f#c>#S6AjDceT5w&PL-?+E8fmKWj5bCE zyd?cX;`?!u?CwM^zNwM4Brovnin1VatZK1?YwDOA?2cQ}xwd87)wZGR zrp4GSoi(nHa}d2?$_b67FO(hzNY$Ia{A#L&fB3N`J44xxOL$`HcDK-U%Lyk+Vlc># z*6yykTXB9O4ji^a1xafvh%pj&iqys)#kM|qX_oz|N;Y(wonqQM`f6iH|8H0&dyj=b z2Ac>whVPTZH{YP5zTwaJlQ!lI#}>}X5e-6#3fR%ww>L4%PRj)Bx!@RSXA4Cd(OM*$ zrHm|;H=p*Ni$+NLoXN@_NxgYhaPZ-Eu?A#4C{S>+KTt4ke4P{J^7gs(aN(atZtEh? zI6oVb#PvYIi}P`^*G0K4b`@?n6yvD-BMP$BDNU!(*mzq*Ft!<8=*^uBF#X9#QGBq2cX$BEL7Yt_5V(Im_a;{!+@x(}5 zw@uQENIV>S&UZ3w^(B8=g!YlG1YEIlFnRm+N0QVtB*{57u0@1?sBRYqGA6nYzZ+rO zx2pSmPTWuXObX2BO1;ZlvD{yR$}%@3{mA$HPh8H%60vXgM#)y+=-g>A$Gi`Q$a=_c zc2+tdGb&Y?yh$RE_V*8ICUhovXTV5tAQm=>i1Ur;9a`eLk5&q{=o}|X*CBEX#kUB4 zv0m||4Jzu72eMi1y+l~{2WxxUy@DE%AK|cULu{I}F)ZGZSbX})UkYb3Bvg$%HdOZ* zL#=)NZ9K2OpB4&I-d@hz@SBS^WtscO>B*7C`ASMB4j-{J5N;H&{_bsYb31Qkv6|G4fjY$m7}XAdyflUKyNLR)+9l(Bjjc#gkc+ z+9GL3d;?@?P%~jo%HYvZf}qvGD~v{b8)2kWfl>wYFGaN8bM10YF5su$Tw zj+AGeR>g-Bf8wJIy+{8b?$xd}a0jA#K_dXV4ns^6rrf zg{U{;TDu;k1vxF9ud!ZAItDk{Ymt+$Q;+mOPK}sHDW;$yyz-wcw-E`kHZQ<;_#+0b zlF2FTs(_2&0;zCjdjLEevn3lzN-v%#rJa;=@>~0Co}}6; zcLWM*J!gCr%KzT5%0$r0muxY9)PK?ntANn5O6`fB!c$>~9LcL{TEidl?<0S@A|U?M zsQ@lX;21y#Xn%m7Hpe1>Zb?tj9ZAEWXW zrjl>Pl9@tj95=OOGYI6^D=--FEf1 zs2>I+TuhM)#f$;QNgW5r$1Cl%!;UT+Hkzu#WqQOxrpk?~aqH9agYPiceaG?#I|`fk z=b2!V@b78Y*XuZRvONwp%5HdLqddrtUV!m$=KE0ht8rkfB)ox^ zfz>7Dn^2wtXQXuuWCKxJ4ujO z)0H(PesU-7n6)XQP-3_f)Xg=l`i?csb}SFN^7B~y#N^xR=Fs1J(#gQTl!zaaPqPDnH1k%mP&(7YLQ$pTc$(u-0^{^`-62Xr}EE5HS%- z^I?7%N{fqUOcaiN0cLUp_#BqD`Rbt=XNlp9BC-%w2}jvb)otpR)=Y+7dL_uyTnvz;5(!s4JoB6L-&Gbw|UzT zOmJe~%X%4VcI%l?dwXKK&oCFln;MT63Kxa9p9Vnw|`Z zJvSnG!P`;9>7(L7v&xNMlGmquK%}ktzVVoBDa5%VajS|1VJAbmV(8UGpfFtyWi1~i zvGMR=d&W-RDA-KIf}m*VVjBl?V9fAlkwg=LP3K34L;YF3N;Xf^Oq{Pw!8V&%7u55+ zNuXv0cX*w> zJzCqxn-=QOQl@lliPb>(m|umS8nMI@kV{mO0(^F8 zwH4O-((k@do#jw)aX0pDeth4KbY)UEfaek*KrKv%xE+taG(wu5Z`0U!LhB;>fCi7pf`-Znup-Z}29uXe^51W0%1-Oln*>S8s z$N8NYrQ(U2(litAN>qk3F1wE`Zp8W@kqN$JI-Wju?SvbnVf!cPWcbua6g@~^*M*c@ zeE|K$WcBE|19=Nlu0G|;QrsHYO8jDT=S*Rt6|i=s*0#^fFXXl2S9ZeSq>+y(9#i;^ zc>)LNhljlrP7@bb3XZOa@C%61;PELQI3I&$oq@WjT(-aMrid+Or1;R zAI(RXwckG_uzMQ6O{PBAr=vIyK}cs2U8eCWw- zp7l$S;7b~{)28j7q$&Y5cm2vYGx0w^UArOU8!IgbEx@s!JP&C~#sk|MD?LRI{4ZPD zW};7B(Vbz6Qr*GItyZ62^!~z<{mn`6)(<&U;%njB>HS0Ff%en-Gy1$KKW?Z;6y!%p zv1L0n%msIR-p7GBM^c;qtxV6oiIK|^{A+oarHXj@Se59w-m=%uN_z__aqni2F!;NGZuoBrTx5NZa1Y4T1YEF7z!VwZhM=D zEeSc+WY-!CyeEMvhIcf~>L{U{ol)RqT6vkr&$tQ|W?)u*@Igf_ZgCn&JS#U zS@`B=XnE;N3PX0YR2tqk&c;@TBnbvo&gXDULPn&9=oAsDwvk5OPbbUB+kRpqygt0* zO|hju)u=M|VX7@`Z^mfQn=D4j{HSEh*0oN0ZZl2ENKc{ixRg7B?cR-^w&_@3{#gEH zcQ%Ee)AKw0XWa6b+Vg9wU;&KMNm4{|D;x&kpTLfCu`tc026j{~5FEdb16Q%Gqn0+IvvEA5vljQZIC_0BY&~gK6&ZWA zuL6zV2!j!N0p%nkJ?ZSE4p;3l0kk{G@Eh_Gd{~8;+^=6ME@32wu*hWdef`FYTn=*1R*|3 ziI|D7<6MSeD8uSqrzD}Yjz_QQ?=B|&FI*k>tFDhcEt-vt+ykqcn=XS z;G@LBLUp}CWBo0Op>frt7VX11wO3O5p5QgMYqOg1NA|7J7@T=q@V$Kre7fFC61{VD zoD7zl!SKGLI+r0-QgBb4=bor|cTE=K914R_8Q%LERE)uc%6WL!6y)%V6Z}K}X%Jc$ zA1Y^;N^JBO3sS>=eI}W4g_cJxWHm_m80RAjqsXD>A2ua4ILL5in4Vr$=#DUtR)@v1o4Qc%e zNYPbhk8Ga91tp%&M$2*LRAHG;#M|H4n^cr6=<2Bm@I~8&Sii>IBjd7HK%8g_aC^Y1 zYV5uYOdu}^q))o)<}FE0mp=sUgJgXQLu;ZC_}6OVt{&c9hjx}&oI_k!;J!%=MLbU6 zq@9_!){Rg+yoVCxm}iS5sSF)5zsOA#5F#OFR}_B_m4aK}zUoVP^tFEN(XuxD>l7@p z#!Bj=7u3es^BA0;u#-{k6qOO-h$)l-F+q1KO3Xt1n^NRH0>b<)Zhne+>4_gj(}X!oLu~V zxKb>0c8tKY<%+CucXYvduNU6e+yZVV`;)e-qBoWM23jT8dIh`lmy}MhJHpS-I01FL zh?P^ljY|kSMOUj_y{9L<=EtJ$g(IF+wH5ho+2NK^^{yyKXAp_#8pds7#VtSNiGKQ2 z8rqi&Iez;{*hW2NGm*>_U#}h+7ej=yaOg9p*@!jDZ6=_EYT?31#nxp^q@C&C3v`X? z8?A_t;zskGK%6N!Ge0$oBquS{3T^nz{Is1W3o4 zP)nwQ)r6gCood*ID{lN@;pEW`ik`P>c|&p<>;y=0J>;Ix@C~uI5HKxS8(a53O`yc7 zp=c{Hv{7Jze+GTc&-`NSF?<5|6iReJuRcq_)ae7^28hFNgo`KRSpv?Z8RgP7W%ra$LfnThR- zO@7e{32eFws_M){ZYP_-ifV$q*R0{(Zo{#bK z@GM5lP~znobuLA*SW!sg7M{P8H=p)fe$(^PC|NY$VNI3&rS4>@JRxmZ!tjUOwmn;4 z3+JTzfPEV*iuU;PCZ-EYg%??BmXEl`;6pu;5WX^lDBy4R+I$ia+~wfHhb}3pOU^ssz5* zkJMDUoLrs#KIYlqVtwT%I~F`-h=_=r2tl@@Y7RTB00D$y*?idxjDsIQ-J_$Uiy-c_ zsvWY2PA@KwEiEmJfOR$|Ip1rsfl>S7#0P1est&848;M?&<>lqGrFC_p6_64joc_+# z^wYH#vHE4^slS-mbG1J`aXA6|z;bJIp`pRnDKiz!s^y=$KtPw>I|QM8I4sYBHcsu2 zOUs~#SLh(4voel3CRkhyvCjDUW%SI2Ehfz+*hTWU+WYKuFm0EdtQ{Pa{Bba#3-NOZ4;E zsB@c9=E(yneUFRo=JN1|n_jy*n>#Bk01Cx0a~49^at3POq4FcFG$r3eU60-^G5h06 z(5JD$$7Fvvi*w}QDt|4Yr=bxDWOwWnN~W@NfxZu!-T>j95KNX#_zT0Y0r)Qk2Kd6N zPei8Qhh<+1W&HknYVWp_Uokj283a6FzGAq;94N2PfjQgyS#I^NBU}WpMnlBGMu*w9 zoeSLQA{z5fVMMXtjrXjBK-%+*@rxPYFt|7zc!riGDe87U+WhI>dq{n|| zCocYv$(~@t)i%rCNy6S@YY-k?A<*3jqYzYWz$P~t9>v95*Pof)iJyr`Akzh2U?exy z@JOr@AmSP)BXk4?bQ_2D=GqnEis@e8tWkO0Z~^hS%EIKGgZ_nrw6vFEAHxpHCIPx4 zN8--?EWV(iK-Yko*nPeCN2gS+kF5hcyjh-|!u~7cTR?%ia-2LP zVb@)R$Jr@qQxxBh`~1=VkEMmM(-jB&Y24btLtDCVu{<;2mLnzw{zh$a7ci zI)V_xi56ELJ;D@t^-^5@<8!D&YKr`T4JV zmlKDRU+Q&qFg@3C-_FjgR71n8u^F-Py4HE+d8qpDtG;3~e5$Jh(F4BYRXW7AN8KzJ zBZ+sdr$bS+|NeqZXh^I9mNqgIz@VqKqvLq|%fk@;^X>osP)$xo^FLlv`F~$}jKqrc zA1^`vw=X>=IBSWr{GV5F;3q76*R3vwS>@=E{@--Wt+HTFN<4+%JV zzSoXU-_^u0)p$A8p{M`qU82(DgVvva75Ky!)TjVCaJ!Hl48=nLr4b>q{xHuiVWB(q zB;Cyhzbw!1U-5wYK?+X($@I+Bo9=JQ2%y`8F(!^0O^dFDpYGpZAeRN+3POk4zY`9L z6-`ybOp{@>@o%i)O04?A#~?mUF3H8WctA`h3!&23fyws$HaPVL?cu&kl>z#sD#@Ec zTy7JV<4;EVcVZ-hbU_F1QM!W@(KrB(k>;fC{C!`F_gLGv;i)lo$lt5xMLt~hF;X6T z#<%{0^=)MdEX*+@JpjIW*$)Dg3w-{g(m!wY`=4)>%aR0Fw=1AyW=6lfyqq-=oM_4f zZAco3BwSDT_V%`a$-Aj3USVN!pjp=lpn<1e0X;?7XZ7m?iIISnlw4Y>9>d$()@Ic8 zg#r0^RZ9kVgidG%dlAY+I07Qlr>3o%{raz`_gE60e#zdZrhn?r$i9628ctW|^d+ zvDWn%bG;`UTdy)CJe-LA%Nq!+PV}&qV0O$G98ruJaCLTOV}lE(f(!1~9%FmnUoVhj zy|vqdb>9gsGuyXkkUg#$7iraWQGOv(qieeHJ%1G85kmw*tR{gK=|)Q=#{L@kls0ID17Jxob{t z10u(m&W~?_&S>SO>K}2a#}n9z8qhqiifVJ(1dO?>HPt_U2@)pvj6jaN)dL$4DcXQ6 z*dc(a+b6%2*>)_vAE|Q#Hp+?f9_M;{&S4OUsblBXF}1&l0J@e&YrVsi3i1=sGPCOZ zQoOuu?59T68}^tRGh;0Y>@5Z;JN(>$jlZ`5K+d0J$kxD$0mXRx=FJ=3PPePA%qqoE zJ7Y`B9xQ`KuLT(D01z^8wS2YELFLt(@Z79HNl2&MYROlaCha;240?sl!njzBeJB2~ zUSPjO5739Kgw)LzKFR|kA5^zvR(6ew1jX1Ru#J92@!LJ;hLs5TE;Ni97|(75L>O~D zl9bC=SdN**%AMux?EwPu2=J1*jaHEeIs)slu^if4Scn91!DMz6;2@!r^q>n%0B*&= zV}Bz-Qm_@B*H1-1hz0M-YS`Kq+VZ|KNsgiFpE7Gw%-vy6iNY99z6HSE)n;0Z2&>gI z;QC{GFM~=mhX9^gLmK(L1idMP4H)_>K`6_3w%c-R@PltdWp3kYpdL}z)r~n1nRPs5 z>Qg|ERqHc;ccUAV9M8u)n3vr2O3uagB}swJA%mhQSkq zZBHU7K&6ou{Eb?~`FE2DdQ1bGaNzZU7g_sEAm_5a|PM1RZ3c=B*( z(GYa4w3*8`4o@FIQbISgKW5A4{yjp$!NKuhad&apL4~zma&DA&7%Sh_!_mO{3*135 zU4qRUi9G*+U|BnlfF8$ZX9k&%Z-zyw%; z02jJJj@*KR_JgIC!v_TeNho$3C~OW~YgOao-d=w|5(v#jATDumalum*Lwo)VhWEUFaXmjM;>TW9g9`1RksUe?f}vD z$d8#jCT$V0IH9W+GmCm`FISoQ*aKJLBN0#_-mL)BYT!i|I&%ixn%jU}$4Sq>C!smv z8YJ4d5XeV6Mgwha3%j>EBQUPd)`1WoBaaA&yR(Xh9~56+T>Nr}1rZ4|bbR~%eJPmn z_aFy%S;F6eg}555XY8N5`uC6$tKvX}{2xRPo25Vv^=jGXnFOI?C4w19W^>Umj~z8v zij;YPya~&e_WX8p`wC!egUldd~$PHoO4trmJ&d=(0Eh9 zPJ>QATgC0<Ek=02MO?8&S$&tC@AY=zE%#^jQ4|k6_G#G!u_lppWd^LHQZe zrs0;4UANM(FySdIXc|<=O$pC{J2w@7zKMk}--6Z($HZ3W^)r5th5>H36LXQHPP*9@ z!2Wyi;=KU=(djsK;ESWQH-w`-tT~+?|4PpP4;GUDlhx>d`Ag33lSyLn^jwZz9)Ulv Mq!eEkNErJ5f5Uor<^TWy diff --git a/src/main.cpp b/src/main.cpp index 969eb72..883d9fb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -13,7 +13,7 @@ #include #include "testing_helpers.hpp" -const int SIZE = 1 << 26; // feel free to change the size of array +const int SIZE = 1 << 18; // feel free to change the size of array const int NPOT = SIZE - 3; // Non-Power-Of-Two int *a = new int[SIZE]; int *b = new int[SIZE]; From 3c48d87ae462acf5613c7615912fdab34749baf5 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 17 Sep 2024 22:39:16 -0400 Subject: [PATCH 6/6] Updated README --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a524d88..4c07d1f 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ Run with 2^18 elements, this is what a sample program output looks like: ## Performance Analysis -The following data was collected using a block size of 128 running in release mode and utilizing cudaTimers and std::chrono to gather timing information. Memory swapping between the CPU and GPU was excluded where possible to focus the running time analysis on the algorithm. The size of 128 blocks was chosen from many tested as on my GPU it saw the best performance. +The following data was collected using a block size of 128 running in release mode and utilizing cudaTimers and std::chrono to gather timing information. Memory swapping between the CPU and GPU was excluded where possible to focus the running time analysis on the algorithm. The size of 128 blocks was chosen from many tested as on my GPU it saw the best performance. Any references to non power of 2 or power of 2 algorithms refer to the input size used for the algorithm. This tests whether the approach is better or worse at handling array inputs where the input is a power of 2, or the input is not a power of 2. This is prevalent with the GPU approaches since the algorithms are tree based, which often rely on having a power of 2 length to properly touch all leaves. # Charts @@ -99,8 +99,12 @@ The following is a chart displaying how running time of the numerous methods cha In scan, the CPU dominated in performance over my implementations, but thrust proved to be the fastest at large array sizes, increasing much slower than other approaches. The CPU is marginally faster than thrust at small array sizes, because the parallelism is not fast enough to offset the heavier cost of transferring memory to and from the GPU. The thrust algorithm's supremacy shows that true harnessing of the GPU takes more than simply implementing an algorithm, but also smart usage of shared memory, data prefetching, and other strategies to utilize the parallel hardware. See more about the thrust algorithm at the bottom of the readme. +In stream compaction, the GPU has a much better performance at larger array sizes than the CPU. Note that the power of two and non power of two CPU runs without scan cover each other due to their negligible performance difference. + In scan, there is interesting behavior between the power of two and non power of two naive GPU algorithms. The non-power of two naive algorithm had an increasing difference in performance over the power of two input the larger the input became. This is likely because the overhead of padding zeroes increases as size increases. The same is not true of the compaction algorithms, likely because the main bottleneck of that algorithm is the global memory reads, which are present even if the input is a power of two. This was not present in the work efficient algorithm, which is so tight between the power of two and non power of two that the power of two line is not visible. +Across all algorithms and the multiple tests there is a very pleasing linear increase in performance. This is likely due to the running time being so closely tied to the array input size, and any additional overhead being trumped by the O(n) nature of the algorithmic approaches. + # Investigation of Thrust using NSight The following is an image of the report from NSight.