From d5c5bc219e22e0878a14208bc963b84d969e61f4 Mon Sep 17 00:00:00 2001 From: Boyuan Yao <70263930+Cypher30@users.noreply.github.com> Date: Fri, 11 Nov 2022 23:17:25 +0800 Subject: [PATCH] [SC] add GPT example for auto checkpoint (#1889) * [sc] SC tutorial for auto checkpoint * [sc] polish examples * [sc] polish readme * [sc] polish readme and help information * [sc] polish readme and help information --- colossalai/fx/passes/meta_info_prop.py | 2 +- examples/tutorial/auto_parallel/README.md | 79 ++ .../auto_parallel/auto_ckpt_demo.ipynb | 878 ------------------ .../tutorial/auto_parallel/bench_utils.py | 111 ++- .../auto_parallel/demo_gpt2_medium.py | 108 +++ .../tutorial/auto_parallel/demo_resnet152.py | 74 ++ .../tutorial/auto_parallel/demo_resnet50.py | 107 +++ .../auto_parallel/imgs/gpt2_benchmark.png | Bin 0 -> 66851 bytes .../auto_parallel/imgs/resnet50_benchmark.png | Bin 0 -> 72546 bytes 9 files changed, 470 insertions(+), 889 deletions(-) delete mode 100644 examples/tutorial/auto_parallel/auto_ckpt_demo.ipynb create mode 100644 examples/tutorial/auto_parallel/demo_gpt2_medium.py create mode 100644 examples/tutorial/auto_parallel/demo_resnet152.py create mode 100644 examples/tutorial/auto_parallel/demo_resnet50.py create mode 100644 examples/tutorial/auto_parallel/imgs/gpt2_benchmark.png create mode 100644 examples/tutorial/auto_parallel/imgs/resnet50_benchmark.png diff --git a/colossalai/fx/passes/meta_info_prop.py b/colossalai/fx/passes/meta_info_prop.py index 711439955..5137494ad 100644 --- a/colossalai/fx/passes/meta_info_prop.py +++ b/colossalai/fx/passes/meta_info_prop.py @@ -338,7 +338,7 @@ def metainfo_trace(gm: torch.fx.GraphModule, *args, verbose: bool = False, unit: Returns: torch.fx.GraphModule: The ``GraphModule`` annotated with MetaInfo. """ - device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu') + device = torch.device('cuda:0') if torch.cuda.is_available() else torch.device('cpu') interp = MetaInfoProp(gm.to(device)) if is_compatible_with_meta(): from colossalai.fx.profiler import MetaTensor diff --git a/examples/tutorial/auto_parallel/README.md b/examples/tutorial/auto_parallel/README.md index bed488022..e93a8288b 100644 --- a/examples/tutorial/auto_parallel/README.md +++ b/examples/tutorial/auto_parallel/README.md @@ -15,3 +15,82 @@ export DATA=/path/to/data ```bash colossalai run --nproc_per_node 4 auto_parallel_demo.py ``` + +## Auto Checkpoint Benchmarking + +We prepare three demos for you to test the performance of auto checkpoint, the test `demo_resnet50.py` and `demo_gpt2_medium.py` will show you the ability of solver to search checkpoint strategy that could fit in the given budget. + +The usage of the above two test +```bash +python demo_resnet50.py --help +usage: ResNet50 Auto Activation Benchmark [-h] [--batch_size BATCH_SIZE] [--num_steps NUM_STEPS] [--sample_points SAMPLE_POINTS] [--free_memory FREE_MEMORY] + [--start_factor START_FACTOR] + +optional arguments: + -h, --help show this help message and exit + --batch_size BATCH_SIZE + batch size for benchmark, default 128 + --num_steps NUM_STEPS + number of test steps for benchmark, default 5 + --sample_points SAMPLE_POINTS + number of sample points for benchmark from start memory budget to maximum memory budget (free_memory), default 15 + --free_memory FREE_MEMORY + maximum memory budget in MB for benchmark, default 11000 MB + --start_factor START_FACTOR + start memory budget factor for benchmark, the start memory budget will be free_memory / start_factor, default 4 + +# run with default settings +python demo_resnet50.py + +python demo_gpt2_medium.py --help +usage: GPT2 medium Auto Activation Benchmark [-h] [--batch_size BATCH_SIZE] [--num_steps NUM_STEPS] [--sample_points SAMPLE_POINTS] [--free_memory FREE_MEMORY] + [--start_factor START_FACTOR] + +optional arguments: + -h, --help show this help message and exit + --batch_size BATCH_SIZE + batch size for benchmark, default 8 + --num_steps NUM_STEPS + number of test steps for benchmark, default 5 + --sample_points SAMPLE_POINTS + number of sample points for benchmark from start memory budget to maximum memory budget (free_memory), default 15 + --free_memory FREE_MEMORY + maximum memory budget in MB for benchmark, default 56000 MB + --start_factor START_FACTOR + start memory budget factor for benchmark, the start memory budget will be free_memory / start_factor, default 10 + +# run with default settings +python demo_gpt2_medium.py +``` + +There are some results for your reference + +### ResNet 50 +![](./imgs/resnet50_benchmark.png) + +### GPT2 Medium +![](./imgs/gpt2_benchmark.png) + +We also prepare the demo `demo_resnet152.py` to manifest the benefit of auto activation with large batch, the usage is listed as follows +```bash +python demo_resnet152.py --help +usage: ResNet152 Auto Activation Through Put Benchmark [-h] [--num_steps NUM_STEPS] + +optional arguments: + -h, --help show this help message and exit + --num_steps NUM_STEPS + number of test steps for benchmark, default 5 + +# run with default settings +python demo_resnet152.py +``` + +here are some results on our end for your reference +```bash +===============test summary================ +batch_size: 512, peak memory: 73314.392 MB, through put: 254.286 images/s +batch_size: 1024, peak memory: 73316.216 MB, through put: 397.608 images/s +batch_size: 2048, peak memory: 72927.837 MB, through put: 277.429 images/s +``` + +The above tests will output the test summary and a plot of the benchmarking results. diff --git a/examples/tutorial/auto_parallel/auto_ckpt_demo.ipynb b/examples/tutorial/auto_parallel/auto_ckpt_demo.ipynb deleted file mode 100644 index cacf5d5f3..000000000 --- a/examples/tutorial/auto_parallel/auto_ckpt_demo.ipynb +++ /dev/null @@ -1,878 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/home/lcsjy/.conda/envs/autoparallel/lib/python3.10/site-packages/tqdm/auto.py:22: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", - " from .autonotebook import tqdm as notebook_tqdm\n" - ] - }, - { - "data": { - "text/html": [ - "
[11/10/22 18:04:14] INFO     colossalai - torch.distributed.distributed_c10d - INFO: Added key:                    \n",
-       "                             store_based_barrier_key:1 to store for rank: 0                                        \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[11/10/22 18:04:14]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m colossalai - torch.distributed.distributed_c10d - INFO: Added key: \n", - "\u001b[2;36m \u001b[0m store_based_barrier_key:\u001b[1;36m1\u001b[0m to store for rank: \u001b[1;36m0\u001b[0m \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     colossalai - torch.distributed.distributed_c10d - INFO: Rank 0: Completed store-based \n",
-       "                             barrier for key:store_based_barrier_key:1 with 1 nodes.                               \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m colossalai - torch.distributed.distributed_c10d - INFO: Rank \u001b[1;36m0\u001b[0m: Completed store-based \n", - "\u001b[2;36m \u001b[0m barrier for key:store_based_barrier_key:\u001b[1;36m1\u001b[0m with \u001b[1;36m1\u001b[0m nodes. \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     colossalai - torch.distributed.distributed_c10d - INFO: Added key:                    \n",
-       "                             store_based_barrier_key:2 to store for rank: 0                                        \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m colossalai - torch.distributed.distributed_c10d - INFO: Added key: \n", - "\u001b[2;36m \u001b[0m store_based_barrier_key:\u001b[1;36m2\u001b[0m to store for rank: \u001b[1;36m0\u001b[0m \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     colossalai - torch.distributed.distributed_c10d - INFO: Rank 0: Completed store-based \n",
-       "                             barrier for key:store_based_barrier_key:2 with 1 nodes.                               \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m colossalai - torch.distributed.distributed_c10d - INFO: Rank \u001b[1;36m0\u001b[0m: Completed store-based \n", - "\u001b[2;36m \u001b[0m barrier for key:store_based_barrier_key:\u001b[1;36m2\u001b[0m with \u001b[1;36m1\u001b[0m nodes. \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     colossalai - torch.distributed.distributed_c10d - INFO: Added key:                    \n",
-       "                             store_based_barrier_key:3 to store for rank: 0                                        \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m colossalai - torch.distributed.distributed_c10d - INFO: Added key: \n", - "\u001b[2;36m \u001b[0m store_based_barrier_key:\u001b[1;36m3\u001b[0m to store for rank: \u001b[1;36m0\u001b[0m \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     colossalai - torch.distributed.distributed_c10d - INFO: Rank 0: Completed store-based \n",
-       "                             barrier for key:store_based_barrier_key:3 with 1 nodes.                               \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m colossalai - torch.distributed.distributed_c10d - INFO: Rank \u001b[1;36m0\u001b[0m: Completed store-based \n", - "\u001b[2;36m \u001b[0m barrier for key:store_based_barrier_key:\u001b[1;36m3\u001b[0m with \u001b[1;36m1\u001b[0m nodes. \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     colossalai - torch.distributed.distributed_c10d - INFO: Added key:                    \n",
-       "                             store_based_barrier_key:4 to store for rank: 0                                        \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m colossalai - torch.distributed.distributed_c10d - INFO: Added key: \n", - "\u001b[2;36m \u001b[0m store_based_barrier_key:\u001b[1;36m4\u001b[0m to store for rank: \u001b[1;36m0\u001b[0m \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     colossalai - torch.distributed.distributed_c10d - INFO: Rank 0: Completed store-based \n",
-       "                             barrier for key:store_based_barrier_key:4 with 1 nodes.                               \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m colossalai - torch.distributed.distributed_c10d - INFO: Rank \u001b[1;36m0\u001b[0m: Completed store-based \n", - "\u001b[2;36m \u001b[0m barrier for key:store_based_barrier_key:\u001b[1;36m4\u001b[0m with \u001b[1;36m1\u001b[0m nodes. \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     colossalai - torch.distributed.distributed_c10d - INFO: Added key:                    \n",
-       "                             store_based_barrier_key:5 to store for rank: 0                                        \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m colossalai - torch.distributed.distributed_c10d - INFO: Added key: \n", - "\u001b[2;36m \u001b[0m store_based_barrier_key:\u001b[1;36m5\u001b[0m to store for rank: \u001b[1;36m0\u001b[0m \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     colossalai - torch.distributed.distributed_c10d - INFO: Rank 0: Completed store-based \n",
-       "                             barrier for key:store_based_barrier_key:5 with 1 nodes.                               \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m colossalai - torch.distributed.distributed_c10d - INFO: Rank \u001b[1;36m0\u001b[0m: Completed store-based \n", - "\u001b[2;36m \u001b[0m barrier for key:store_based_barrier_key:\u001b[1;36m5\u001b[0m with \u001b[1;36m1\u001b[0m nodes. \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     colossalai - torch.distributed.distributed_c10d - INFO: Added key:                    \n",
-       "                             store_based_barrier_key:6 to store for rank: 0                                        \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m colossalai - torch.distributed.distributed_c10d - INFO: Added key: \n", - "\u001b[2;36m \u001b[0m store_based_barrier_key:\u001b[1;36m6\u001b[0m to store for rank: \u001b[1;36m0\u001b[0m \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     colossalai - torch.distributed.distributed_c10d - INFO: Rank 0: Completed store-based \n",
-       "                             barrier for key:store_based_barrier_key:6 with 1 nodes.                               \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m colossalai - torch.distributed.distributed_c10d - INFO: Rank \u001b[1;36m0\u001b[0m: Completed store-based \n", - "\u001b[2;36m \u001b[0m barrier for key:store_based_barrier_key:\u001b[1;36m6\u001b[0m with \u001b[1;36m1\u001b[0m nodes. \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     colossalai - torch.distributed.distributed_c10d - INFO: Added key:                    \n",
-       "                             store_based_barrier_key:7 to store for rank: 0                                        \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m colossalai - torch.distributed.distributed_c10d - INFO: Added key: \n", - "\u001b[2;36m \u001b[0m store_based_barrier_key:\u001b[1;36m7\u001b[0m to store for rank: \u001b[1;36m0\u001b[0m \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     colossalai - torch.distributed.distributed_c10d - INFO: Rank 0: Completed store-based \n",
-       "                             barrier for key:store_based_barrier_key:7 with 1 nodes.                               \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m colossalai - torch.distributed.distributed_c10d - INFO: Rank \u001b[1;36m0\u001b[0m: Completed store-based \n", - "\u001b[2;36m \u001b[0m barrier for key:store_based_barrier_key:\u001b[1;36m7\u001b[0m with \u001b[1;36m1\u001b[0m nodes. \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     colossalai - torch.distributed.distributed_c10d - INFO: Added key:                    \n",
-       "                             store_based_barrier_key:8 to store for rank: 0                                        \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m colossalai - torch.distributed.distributed_c10d - INFO: Added key: \n", - "\u001b[2;36m \u001b[0m store_based_barrier_key:\u001b[1;36m8\u001b[0m to store for rank: \u001b[1;36m0\u001b[0m \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     colossalai - torch.distributed.distributed_c10d - INFO: Rank 0: Completed store-based \n",
-       "                             barrier for key:store_based_barrier_key:8 with 1 nodes.                               \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m colossalai - torch.distributed.distributed_c10d - INFO: Rank \u001b[1;36m0\u001b[0m: Completed store-based \n", - "\u001b[2;36m \u001b[0m barrier for key:store_based_barrier_key:\u001b[1;36m8\u001b[0m with \u001b[1;36m1\u001b[0m nodes. \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     colossalai - colossalai - INFO:                                                       \n",
-       "                             /home/lcsjy/ColossalAI/colossalai/context/parallel_context.py:521 set_device          \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m colossalai - colossalai - INFO: \n", - "\u001b[2;36m \u001b[0m \u001b[35m/home/lcsjy/ColossalAI/colossalai/context/\u001b[0m\u001b[95mparallel_context.py\u001b[0m:\u001b[1;36m521\u001b[0m set_device \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     colossalai - colossalai - INFO: process rank 0 is bound to device 0                   \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m colossalai - colossalai - INFO: process rank \u001b[1;36m0\u001b[0m is bound to device \u001b[1;36m0\u001b[0m \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     colossalai - colossalai - INFO:                                                       \n",
-       "                             /home/lcsjy/ColossalAI/colossalai/context/parallel_context.py:557 set_seed            \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m colossalai - colossalai - INFO: \n", - "\u001b[2;36m \u001b[0m \u001b[35m/home/lcsjy/ColossalAI/colossalai/context/\u001b[0m\u001b[95mparallel_context.py\u001b[0m:\u001b[1;36m557\u001b[0m set_seed \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     colossalai - colossalai - INFO: initialized seed on rank 0, numpy: 1024, python       \n",
-       "                             random: 1024, ParallelMode.DATA: 1024, ParallelMode.TENSOR: 1024,the default parallel \n",
-       "                             seed is ParallelMode.DATA.                                                            \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m colossalai - colossalai - INFO: initialized seed on rank \u001b[1;36m0\u001b[0m, numpy: \u001b[1;36m1024\u001b[0m, python \n", - "\u001b[2;36m \u001b[0m random: \u001b[1;36m1024\u001b[0m, ParallelMode.DATA: \u001b[1;36m1024\u001b[0m, ParallelMode.TENSOR: \u001b[1;36m1024\u001b[0m,the default parallel \n", - "\u001b[2;36m \u001b[0m seed is ParallelMode.DATA. \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     colossalai - colossalai - INFO: /home/lcsjy/ColossalAI/colossalai/initialize.py:117   \n",
-       "                             launch                                                                                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m colossalai - colossalai - INFO: \u001b[35m/home/lcsjy/ColossalAI/colossalai/\u001b[0m\u001b[95minitialize.py\u001b[0m:\u001b[1;36m117\u001b[0m \n", - "\u001b[2;36m \u001b[0m launch \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     colossalai - colossalai - INFO: Distributed environment is initialized, data parallel \n",
-       "                             size: 1, pipeline parallel size: 1, tensor parallel size: 1                           \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m colossalai - colossalai - INFO: Distributed environment is initialized, data parallel \n", - "\u001b[2;36m \u001b[0m size: \u001b[1;36m1\u001b[0m, pipeline parallel size: \u001b[1;36m1\u001b[0m, tensor parallel size: \u001b[1;36m1\u001b[0m \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import time\n", - "import torchvision.models as tm\n", - "import torch\n", - "import colossalai\n", - "from colossalai.fx import symbolic_trace, metainfo_trace\n", - "from colossalai.auto_parallel.checkpoint import CheckpointSolverRotor\n", - "from functools import partial\n", - "from colossalai.utils import free_port\n", - "\n", - "from bench_utils import bench, bench_rotor\n", - "import matplotlib.pyplot as plt\n", - "\n", - "colossalai.launch(config={}, rank=0, world_size=1, host='localhost', port=free_port(), backend='nccl')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### ResNet152 with batch size = 512 fails" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(78990.4404296875, inf)" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "def data_gen(batch_size, shape, device='cuda'):\n", - " data = torch.empty(batch_size, *shape, device=device)\n", - " label = torch.empty(batch_size, dtype=torch.long, device=device).random_(1000)\n", - " return {'x': data}, label\n", - "\n", - "model = tm.resnet152()\n", - "gm = symbolic_trace(model)\n", - "gm = metainfo_trace(gm, torch.empty(512, 3, 224, 224, device='meta'))\n", - "bench(gm, torch.nn.CrossEntropyLoss(), partial(data_gen, batch_size=512, shape=(3, 224, 224)), num_steps=5)\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### ResNet152 with batch size = 2048 succeeds " - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(74495.8486328125, 5634.262561798096)" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "def data_gen(batch_size, shape, device='cuda'):\n", - " data = torch.empty(batch_size, *shape, device=device)\n", - " label = torch.empty(batch_size, dtype=torch.long, device=device).random_(1000)\n", - " return {'x': data}, label\n", - "\n", - "model = tm.resnet152()\n", - "gm = symbolic_trace(model)\n", - "gm = metainfo_trace(gm, torch.empty(2048, 3, 224, 224, device='meta'))\n", - "solver = CheckpointSolverRotor(gm.graph, free_memory=torch.cuda.mem_get_info(device=0)[0] * 0.95)\n", - "gm.graph = solver.solve()\n", - "bench(gm, torch.nn.CrossEntropyLoss(), partial(data_gen, batch_size=2048, shape=(3, 224, 224)), num_steps=5)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Benchmarking on ResNet18" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
[11/10/22 18:04:20] WARNING  colossalai - colossalai - WARNING:                                                    \n",
-       "                             /home/lcsjy/ColossalAI/colossalai/auto_parallel/checkpoint/ckpt_solver_rotor.py:82    \n",
-       "                             solve                                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[11/10/22 18:04:20]\u001b[0m\u001b[2;36m \u001b[0m\u001b[31mWARNING \u001b[0m colossalai - colossalai - WARNING: \n", - "\u001b[2;36m \u001b[0m \u001b[35m/home/lcsjy/ColossalAI/colossalai/auto_parallel/checkpoint/\u001b[0m\u001b[95mckpt_solver_rotor.py\u001b[0m:\u001b[1;36m82\u001b[0m \n", - "\u001b[2;36m \u001b[0m solve \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    WARNING  colossalai - colossalai - WARNING: Checkpoint solver failed: Can not process this     \n",
-       "                             chain from index 0 to 14 with memory 500                                              \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[31mWARNING \u001b[0m colossalai - colossalai - WARNING: Checkpoint solver failed: Can not process this \n", - "\u001b[2;36m \u001b[0m chain from index \u001b[1;36m0\u001b[0m to \u001b[1;36m14\u001b[0m with memory \u001b[1;36m500\u001b[0m \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    WARNING  colossalai - colossalai - WARNING:                                                    \n",
-       "                             /home/lcsjy/ColossalAI/colossalai/auto_parallel/checkpoint/ckpt_solver_rotor.py:82    \n",
-       "                             solve                                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[31mWARNING \u001b[0m colossalai - colossalai - WARNING: \n", - "\u001b[2;36m \u001b[0m \u001b[35m/home/lcsjy/ColossalAI/colossalai/auto_parallel/checkpoint/\u001b[0m\u001b[95mckpt_solver_rotor.py\u001b[0m:\u001b[1;36m82\u001b[0m \n", - "\u001b[2;36m \u001b[0m solve \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    WARNING  colossalai - colossalai - WARNING: Checkpoint solver failed: Can not process this     \n",
-       "                             chain from index 0 to 14 with memory 500                                              \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[31mWARNING \u001b[0m colossalai - colossalai - WARNING: Checkpoint solver failed: Can not process this \n", - "\u001b[2;36m \u001b[0m chain from index \u001b[1;36m0\u001b[0m to \u001b[1;36m14\u001b[0m with memory \u001b[1;36m500\u001b[0m \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    WARNING  colossalai - colossalai - WARNING:                                                    \n",
-       "                             /home/lcsjy/ColossalAI/colossalai/auto_parallel/checkpoint/ckpt_solver_rotor.py:82    \n",
-       "                             solve                                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[31mWARNING \u001b[0m colossalai - colossalai - WARNING: \n", - "\u001b[2;36m \u001b[0m \u001b[35m/home/lcsjy/ColossalAI/colossalai/auto_parallel/checkpoint/\u001b[0m\u001b[95mckpt_solver_rotor.py\u001b[0m:\u001b[1;36m82\u001b[0m \n", - "\u001b[2;36m \u001b[0m solve \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    WARNING  colossalai - colossalai - WARNING: Checkpoint solver failed: Can not process this     \n",
-       "                             chain from index 0 to 14 with memory 500                                              \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[31mWARNING \u001b[0m colossalai - colossalai - WARNING: Checkpoint solver failed: Can not process this \n", - "\u001b[2;36m \u001b[0m chain from index \u001b[1;36m0\u001b[0m to \u001b[1;36m14\u001b[0m with memory \u001b[1;36m500\u001b[0m \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    WARNING  colossalai - colossalai - WARNING:                                                    \n",
-       "                             /home/lcsjy/ColossalAI/colossalai/auto_parallel/checkpoint/ckpt_solver_rotor.py:82    \n",
-       "                             solve                                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[31mWARNING \u001b[0m colossalai - colossalai - WARNING: \n", - "\u001b[2;36m \u001b[0m \u001b[35m/home/lcsjy/ColossalAI/colossalai/auto_parallel/checkpoint/\u001b[0m\u001b[95mckpt_solver_rotor.py\u001b[0m:\u001b[1;36m82\u001b[0m \n", - "\u001b[2;36m \u001b[0m solve \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    WARNING  colossalai - colossalai - WARNING: Checkpoint solver failed: Can not process this     \n",
-       "                             chain from index 0 to 14 with memory 500                                              \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[31mWARNING \u001b[0m colossalai - colossalai - WARNING: Checkpoint solver failed: Can not process this \n", - "\u001b[2;36m \u001b[0m chain from index \u001b[1;36m0\u001b[0m to \u001b[1;36m14\u001b[0m with memory \u001b[1;36m500\u001b[0m \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
[11/10/22 18:04:21] WARNING  colossalai - colossalai - WARNING:                                                    \n",
-       "                             /home/lcsjy/ColossalAI/colossalai/auto_parallel/checkpoint/ckpt_solver_rotor.py:82    \n",
-       "                             solve                                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[11/10/22 18:04:21]\u001b[0m\u001b[2;36m \u001b[0m\u001b[31mWARNING \u001b[0m colossalai - colossalai - WARNING: \n", - "\u001b[2;36m \u001b[0m \u001b[35m/home/lcsjy/ColossalAI/colossalai/auto_parallel/checkpoint/\u001b[0m\u001b[95mckpt_solver_rotor.py\u001b[0m:\u001b[1;36m82\u001b[0m \n", - "\u001b[2;36m \u001b[0m solve \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    WARNING  colossalai - colossalai - WARNING: Checkpoint solver failed: Can not process this     \n",
-       "                             chain from index 0 to 14 with memory 500                                              \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[31mWARNING \u001b[0m colossalai - colossalai - WARNING: Checkpoint solver failed: Can not process this \n", - "\u001b[2;36m \u001b[0m chain from index \u001b[1;36m0\u001b[0m to \u001b[1;36m14\u001b[0m with memory \u001b[1;36m500\u001b[0m \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    WARNING  colossalai - colossalai - WARNING:                                                    \n",
-       "                             /home/lcsjy/ColossalAI/colossalai/auto_parallel/checkpoint/ckpt_solver_rotor.py:82    \n",
-       "                             solve                                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[31mWARNING \u001b[0m colossalai - colossalai - WARNING: \n", - "\u001b[2;36m \u001b[0m \u001b[35m/home/lcsjy/ColossalAI/colossalai/auto_parallel/checkpoint/\u001b[0m\u001b[95mckpt_solver_rotor.py\u001b[0m:\u001b[1;36m82\u001b[0m \n", - "\u001b[2;36m \u001b[0m solve \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    WARNING  colossalai - colossalai - WARNING: Checkpoint solver failed: Can not process this     \n",
-       "                             chain from index 0 to 14 with memory 500                                              \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[31mWARNING \u001b[0m colossalai - colossalai - WARNING: Checkpoint solver failed: Can not process this \n", - "\u001b[2;36m \u001b[0m chain from index \u001b[1;36m0\u001b[0m to \u001b[1;36m14\u001b[0m with memory \u001b[1;36m500\u001b[0m \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    WARNING  colossalai - colossalai - WARNING:                                                    \n",
-       "                             /home/lcsjy/ColossalAI/colossalai/auto_parallel/checkpoint/ckpt_solver_rotor.py:82    \n",
-       "                             solve                                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[31mWARNING \u001b[0m colossalai - colossalai - WARNING: \n", - "\u001b[2;36m \u001b[0m \u001b[35m/home/lcsjy/ColossalAI/colossalai/auto_parallel/checkpoint/\u001b[0m\u001b[95mckpt_solver_rotor.py\u001b[0m:\u001b[1;36m82\u001b[0m \n", - "\u001b[2;36m \u001b[0m solve \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    WARNING  colossalai - colossalai - WARNING: Checkpoint solver failed: Can not process this     \n",
-       "                             chain from index 0 to 14 with memory 500                                              \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[31mWARNING \u001b[0m colossalai - colossalai - WARNING: Checkpoint solver failed: Can not process this \n", - "\u001b[2;36m \u001b[0m chain from index \u001b[1;36m0\u001b[0m to \u001b[1;36m14\u001b[0m with memory \u001b[1;36m500\u001b[0m \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
[11/10/22 18:04:22] WARNING  colossalai - colossalai - WARNING:                                                    \n",
-       "                             /home/lcsjy/ColossalAI/colossalai/auto_parallel/checkpoint/ckpt_solver_rotor.py:82    \n",
-       "                             solve                                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[11/10/22 18:04:22]\u001b[0m\u001b[2;36m \u001b[0m\u001b[31mWARNING \u001b[0m colossalai - colossalai - WARNING: \n", - "\u001b[2;36m \u001b[0m \u001b[35m/home/lcsjy/ColossalAI/colossalai/auto_parallel/checkpoint/\u001b[0m\u001b[95mckpt_solver_rotor.py\u001b[0m:\u001b[1;36m82\u001b[0m \n", - "\u001b[2;36m \u001b[0m solve \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    WARNING  colossalai - colossalai - WARNING: Checkpoint solver failed: Can not process this     \n",
-       "                             chain from index 0 to 14 with memory 500                                              \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[31mWARNING \u001b[0m colossalai - colossalai - WARNING: Checkpoint solver failed: Can not process this \n", - "\u001b[2;36m \u001b[0m chain from index \u001b[1;36m0\u001b[0m to \u001b[1;36m14\u001b[0m with memory \u001b[1;36m500\u001b[0m \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    WARNING  colossalai - colossalai - WARNING:                                                    \n",
-       "                             /home/lcsjy/ColossalAI/colossalai/auto_parallel/checkpoint/ckpt_solver_rotor.py:82    \n",
-       "                             solve                                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[31mWARNING \u001b[0m colossalai - colossalai - WARNING: \n", - "\u001b[2;36m \u001b[0m \u001b[35m/home/lcsjy/ColossalAI/colossalai/auto_parallel/checkpoint/\u001b[0m\u001b[95mckpt_solver_rotor.py\u001b[0m:\u001b[1;36m82\u001b[0m \n", - "\u001b[2;36m \u001b[0m solve \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    WARNING  colossalai - colossalai - WARNING: Checkpoint solver failed: Can not process this     \n",
-       "                             chain from index 0 to 14 with memory 500                                              \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[31mWARNING \u001b[0m colossalai - colossalai - WARNING: Checkpoint solver failed: Can not process this \n", - "\u001b[2;36m \u001b[0m chain from index \u001b[1;36m0\u001b[0m to \u001b[1;36m14\u001b[0m with memory \u001b[1;36m500\u001b[0m \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
[11/10/22 18:04:23] WARNING  colossalai - colossalai - WARNING:                                                    \n",
-       "                             /home/lcsjy/ColossalAI/colossalai/auto_parallel/checkpoint/ckpt_solver_rotor.py:82    \n",
-       "                             solve                                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[11/10/22 18:04:23]\u001b[0m\u001b[2;36m \u001b[0m\u001b[31mWARNING \u001b[0m colossalai - colossalai - WARNING: \n", - "\u001b[2;36m \u001b[0m \u001b[35m/home/lcsjy/ColossalAI/colossalai/auto_parallel/checkpoint/\u001b[0m\u001b[95mckpt_solver_rotor.py\u001b[0m:\u001b[1;36m82\u001b[0m \n", - "\u001b[2;36m \u001b[0m solve \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    WARNING  colossalai - colossalai - WARNING: Checkpoint solver failed: Can not process this     \n",
-       "                             chain from index 0 to 14 with memory 500                                              \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[31mWARNING \u001b[0m colossalai - colossalai - WARNING: Checkpoint solver failed: Can not process this \n", - "\u001b[2;36m \u001b[0m chain from index \u001b[1;36m0\u001b[0m to \u001b[1;36m14\u001b[0m with memory \u001b[1;36m500\u001b[0m \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "def data_gen(batch_size, shape, device='cuda'):\n", - " data = torch.empty(batch_size, *shape, device=device)\n", - " label = torch.empty(batch_size, dtype=torch.long, device=device).random_(1000)\n", - " return (data, ), label\n", - "\n", - "model = tm.resnet18()\n", - "gm = symbolic_trace(model)\n", - "gm = metainfo_trace(gm, torch.empty(128, 3, 224, 224, device='meta'))\n", - "peak_hist, step_hist = bench_rotor(gm, torch.nn.CrossEntropyLoss(), partial(data_gen, batch_size=128, shape=(3, 224, 224)), num_steps=5, sample_points=20, free_memory=2700 * 1024**2)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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devWwrJ8+fKIiJg8eXJERDQ1NUV1dXWcc845sWLFinjxxRfjtttuix49ekRERGVlZdH2W7dujdtvvz169uwZ48aN2+txV65cGTNnzoznnnsuli9fHu+++26MHj06/vd//7ernxsAgITlsizLurrxnDlz4vHHH49NmzZFLpeLq666Krp37x4//elPD3gf559/fgwZMiTq6uoOeJvf/e53UVFREStXroyLLrrogLdrbW2NfD4fLS0t0atXrwPeDuBwtGvPuzHwb34eERG/vmNMHFdacojPCODDO9Be6/I9sXv27IlFixbF9OnTI5fLRVtbWyxdujQGDBgQY8aMiYqKihg2bFg0NDTsdR9r166NF154IWbMmNGpY7e0tERExAknnLDPcbt3747W1taiBQCA9HU5YhsaGmLHjh0xbdq0iIjYtm1b7Ny5M+bNmxdjx46NJ598MmpqamLSpEmxcuXKDvdRV1cXVVVVMWLEiAM+bpZl8Y1vfCOqq6tj0KBB+xxbW1sb+Xy+sFRWVh7wcQAAOHx1OWLr6upi3Lhx0bdv34iIaGtri4iIiRMnxty5c2Pw4MFx8803x+WXXx4LFixot/0777wT9913X6e/hZ01a1b88pe/jPvvv3+/Y2+55ZZoaWkpLFu2bOnUsQAAODx16QaqzZs3R2NjYyxZsqSwrnfv3lFSUhIDBw4sGltVVRXPPPNMu3089NBDsWvXrrjuuusO+Lg33nhjPProo/H000/Hqaeeut/xZWVlUVZWdsD7BwAgDV2K2Pr6+qioqIjx48cX1pWWlsbQoUPbPfpq48aN0b9//3b7qKuriwkTJsRJJ5203+NlWRY33nhjPPLII7FixYo444wzunLaAAAcITodsW1tbVFfXx9Tp06NkpLizW+66aaYMmVKXHTRRTFq1Kh44okn4rHHHosVK1YUjXv55Zfj6aefjmXLlnV4jEsuuSRqampi1qxZERExc+bMuO++++Lf//3fo7y8PN54442IiMjn83Hsscd29iMAAJC4Tt8T29jYGM3NzTF9+vR2P6upqYkFCxbE/Pnz47zzzou77747Hn744aiuri4ad88990S/fv1i9OjRHR6jqakptm/fXnh/1113RUtLS3zhC1+IU045pbAsXry4s6cPAMAR4EM9JzY1nhMLHEk8JxY4Eh3058QCAMChImIBAEiOiAUAIDki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9evXx4QJEyKfz0d5eXkMHz48mpubCz/fvXt33HjjjdG7d+/o2bNnTJgwIf7nf/6naB/mqOs+qnlyLR08BzJHH/zdv7/84z/+Y2GMa+ng+qjmybV08BzIHO3cuTNmzZoVp556ahx77LFRVVUVd911V9GYI+payvjYjRkzJquvr89eeuml7IUXXsjGjx+fnXbaadnOnTsLY6ZOnZqNHTs227p1a2F58803i/YzcuTI7Prrry8as2PHjqIxY8eOzQYNGpStXr06W716dTZo0KDs8ssvL/z83XffzQYNGpSNGjUqW7duXbZ8+fKsb9++2axZsw7uL+EwdyBz9PLLL2cnnHBCdtNNN2Xr1q3Lmpqasscffzz77W9/Wxhzww03ZP369cuWL1+erVu3Lhs1alT2mc98Jnv33XcLY8xR131U8+RaOngOZI7+9Pe+devW7J577slyuVzW1NRUGONaOrg+qnlyLR08BzJHX/nKV7Kzzjore+qpp7JXXnkl+/GPf5x169Yta2hoKIw5kq4lEXsY2LZtWxYR2cqVKwvrpk6dmk2cOHGf240cOTL7+te/vtef//rXv84iInvuuecK65599tksIrL//u//zrIsy5YtW5Ydc8wx2WuvvVYYc//992dlZWVZS0tL1z7QEaijOZoyZUr2pS99aa/b7NixI+vevXv2wAMPFNa99tpr2THHHJM98cQTWZaZo49aV+Ypy1xLH6eO5uiDJk6cmF188cWF966lj19X5inLXEsfp47m6Nxzz83uuOOOonFDhgzJvv3tb2dZduRdS24nOAy0tLRERMQJJ5xQtH7FihVRUVERAwYMiOuvvz62bdvWbtt/+7d/i969e8e5554bf/VXfxVvv/124WfPPvts5PP5GDZsWGHd8OHDI5/Px+rVqwtjBg0aFH379i2MGTNmTOzevTvWrl37kX7OlH1wjtra2mLp0qUxYMCAGDNmTFRUVMSwYcOioaGhsM3atWvjD3/4Q4wePbqwrm/fvjFo0KCi3785+uh0ZZ7e51r6eOzt37v3/fa3v42lS5fGjBkzCutcSx+/rszT+1xLH4+O5qi6ujoeffTReO211yLLsnjqqadi48aNMWbMmIg48q6lko/tSHQoy7L4xje+EdXV1TFo0KDC+nHjxsXkyZOjf//+8corr8Rtt90WF198caxdu7bw/yLummuuiTPOOCP69OkTL730Utxyyy3x4osvxvLlyyMi4o033oiKiop2x6yoqIg33nijMObkk08u+vknPvGJKC0tLYw52nU0R9u2bYudO3fGvHnz4jvf+U5897vfjSeeeCImTZoUTz31VIwcOTLeeOONKC0tjU984hNF+zv55JOLfv/m6KPR1XmKcC19XPb2792fuvfee6O8vDwmTZpUWOda+nh1dZ4iXEsfl73N0Q9+8IO4/vrr49RTT42SkpI45phj4u67747q6uqIOPKuJRF7iM2aNSt++ctfxjPPPFO0fsqUKYXXgwYNigsvvDD69+8fS5cuLfyjcf311xeN+dSnPhUXXnhhrFu3LoYMGRIRf7wR/4OyLCtafyBjjmYdzVFbW1tEREycODHmzp0bERGDBw+O1atXx4IFCwpx1JGu/P7N0f59mHlyLX089vbv3Z+655574pprrokePXrsd3+upYPjw8yTa+njsbc5+sEPfhDPPfdcPProo9G/f/94+umn42tf+1qccsop8cUvfnGv+0v1WnI7wSF04403xqOPPhpPPfVUnHrqqfsce8opp0T//v1j06ZNex0zZMiQ6N69e2FMnz594re//W27cb/73e8K/wXVp0+fdv/V9NZbb8Uf/vCHdv+VdTTa2xz17t07SkpKYuDAgUXjq6qqCn/13qdPn9izZ0+89dZbRWO2bdtW9Ps3Rx/eh5mnjriWPnoH8u/dqlWrYsOGDfGVr3ylaL1r6ePzYeapI66lj97e5uidd96Jv/7rv47vf//7ccUVV8SnP/3pmDVrVkyZMiW+973vRcQReC19bHffUtDW1pbNnDkz69u3b7Zx48YD2mb79u1ZWVlZdu+99+51zK9+9auim7zfvzn7P//zPwtjnnvuuQ5vzn799dcLYx544IGj/gb6A5mjz372s+3+YOjKK6/Mrr766izL/v8b6BcvXlz4+euvv97hDfTmqGs+innqiGvpo9OZf++mTp2aXXDBBe3Wu5YOvo9injriWvro7G+OWlpasojIli1bVrT+L/7iL7JLL700y7Ij71oSsYfAX/7lX2b5fD5bsWJF0WNIdu3alWVZlr399tvZN7/5zWz16tXZK6+8kj311FPZZz/72axfv35Za2trlmV/fGzQ7bffnq1ZsyZ75ZVXsqVLl2bnnHNOdv7557d7TManP/3p7Nlnn82effbZ7LzzzuvwMRmXXHJJtm7duqyxsTE79dRTj/pHmexvjrIsy5YsWZJ17949W7hwYbZp06bszjvvzLp165atWrWqMOaGG27ITj311KyxsTFbt25ddvHFF3f4KBNz1DUfxTy5lg6uA5mjLPvj/wAfd9xx2V133dXhflxLB9dHMU+upYPrQOZo5MiR2bnnnps99dRT2W9+85usvr4+69GjR/ajH/2oMOZIupZE7CEQER0u9fX1WZZl2a5du7LRo0dnJ510Uta9e/fstNNOy6ZOnZo1NzcX9tHc3JxddNFF2QknnJCVlpZmZ511VjZ79ux2z5J98803s2uuuSYrLy/PysvLs2uuuSZ76623isZs3rw5Gz9+fHbsscdmJ5xwQjZr1qzs//7v/w72r+Gwtr85el9dXV32yU9+MuvRo0f2mc98puhZfFmWZe+88042a9as7IQTTsiOPfbY7PLLLy+axywzRx/GRzFPrqWD60Dn6Mc//nF27LHHtnum6PtcSwfXRzFPrqWD60DmaOvWrdm0adOyvn37Zj169MjOPvvs7J/+6Z+ytra2wpgj6VrKZVmWfbQ3KAAAwMHlD7sAAEiOiAUAIDkiFgCA5IhYAACSI2IBAEiOiAUAIDkiFgCA5IhYAACSI2IBAEiOiAUAIDkiFgCA5Px/+stDv7Sfnq4AAAAASUVORK5CYII=", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.figure(figsize=(8, 8))\n", - "plt.plot(peak_hist, step_hist)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[540.0,\n", - " 653.6842105263158,\n", - " 767.3684210526316,\n", - " 881.0526315789474,\n", - " 994.7368421052631,\n", - " 1108.421052631579,\n", - " 1222.1052631578948,\n", - " 1335.7894736842104,\n", - " 1449.4736842105262,\n", - " 1563.157894736842,\n", - " 26711.86572265625,\n", - " 26711.86572265625,\n", - " 26711.86572265625,\n", - " 26711.86572265625,\n", - " 26711.86572265625,\n", - " 26711.86572265625,\n", - " 26711.86572265625,\n", - " 26711.86572265625,\n", - " 26711.86572265625,\n", - " 26711.86572265625]" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "peak_hist" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3.10.6 ('autoparallel': conda)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.6" - }, - "orig_nbformat": 4, - "vscode": { - "interpreter": { - "hash": "cc0ad6865167fb9a52c12f0fd0c8203c9a7690797bfee612a871d56b9d2024ce" - } - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/examples/tutorial/auto_parallel/bench_utils.py b/examples/tutorial/auto_parallel/bench_utils.py index 365e07e21..d9d656b85 100644 --- a/examples/tutorial/auto_parallel/bench_utils.py +++ b/examples/tutorial/auto_parallel/bench_utils.py @@ -1,16 +1,33 @@ import time +from copy import deepcopy from functools import partial from typing import Callable, Tuple import numpy as np import torch +import torch.nn as nn import torchvision.models as tm +from transformers import GPT2Config, GPT2LMHeadModel from colossalai.auto_parallel.checkpoint import CheckpointSolverRotor from colossalai.fx import metainfo_trace -def bench(gm: torch.fx.GraphModule, criterion: torch.nn.Module, data_gen: Callable, num_steps: int = 5): +def bench(gm: torch.fx.GraphModule, + criterion: torch.nn.Module, + data_gen: Callable, + num_steps: int = 5) -> Tuple[int, int]: + """Benchmarking a given graph module + + Args: + gm (torch.fx.GraphModule): The graph module to benchmark. + criterion (torch.nn.Module): Loss function. + data_gen (Callable): Data generator. + num_steps (int, optional): Number of test steps. Defaults to 5. + + Returns: + Tuple[int, int]: peak memory in MB and step time in MS. + """ gm.train() gm.cuda() step_time = float('inf') @@ -39,7 +56,8 @@ def bench(gm: torch.fx.GraphModule, criterion: torch.nn.Module, data_gen: Callab del args, label, output, loss gm.to("cpu") torch.cuda.empty_cache() - return (torch.cuda.max_memory_allocated(device="cuda") - cached) / 1024**2, step_time * 1.0e3 + peak_mem = (torch.cuda.max_memory_allocated(device="cuda") - cached) / 1024**2 + return peak_mem, step_time * 1.0e3 def bench_rotor(gm: torch.fx.GraphModule, @@ -47,19 +65,92 @@ def bench_rotor(gm: torch.fx.GraphModule, data_gen: Callable, num_steps: int = 5, sample_points: int = 20, - free_memory: int = torch.cuda.mem_get_info()[0]): + free_memory: int = torch.cuda.mem_get_info()[0], + start_factor: int = 4) -> Tuple[np.array, list, list]: + """Auto Checkpoint Rotor Algorithm benchmarking + Benchmarks the Auto Checkpoint Rotor Algorithm for a given graph module and data. + + Args: + gm (torch.fx.GraphModule): The graph module to benchmark. + criterion (torch.nn.Module): Loss function. + data_gen (Callable): Data generator. + num_steps (int, optional): Number of test steps. Defaults to 5. + sample_points (int, optional): Number of sample points. Defaults to 20. + free_memory (int, optional): Max memory budget in Byte. Defaults to torch.cuda.mem_get_info()[0]. + start_factor (int, optional): Start memory budget factor for benchmark, the start memory budget + will be free_memory / start_factor. Defaults to 4. + + Returns: + Tuple[np.array, list, list]: return budgets vector (MB), peak memory vector (MB), step time vector (MS). + """ peak_hist, step_hist = [], [] - for budget in np.linspace(free_memory // 5, free_memory, sample_points): + raw_graph = deepcopy(gm.graph) + for budget in np.linspace(free_memory // start_factor, free_memory, sample_points): gm = metainfo_trace(gm, *data_gen()[0]) solver = CheckpointSolverRotor(gm.graph, free_memory=budget) try: - gm.graph = solver.solve() - peak_memory, step_time = bench(gm, - criterion, - partial(data_gen, batch_size=2048, shape=(3, 224, 224)), - num_steps=num_steps) + gm.graph = solver.solve(verbose=False) + peak_memory, step_time = bench(gm, criterion, data_gen, num_steps=num_steps) except: peak_memory, step_time = budget / 1024**2, float('inf') peak_hist.append(peak_memory) step_hist.append(step_time) - return peak_hist, step_hist + gm.graph = deepcopy(raw_graph) + return np.linspace(free_memory // start_factor, free_memory, sample_points) / 1024**2, peak_hist, step_hist + + +class GPTLMModel(nn.Module): + """ + GPT Model + """ + + def __init__(self, + hidden_size=768, + num_layers=12, + num_attention_heads=12, + max_seq_len=1024, + vocab_size=50257, + checkpoint=False): + super().__init__() + self.checkpoint = checkpoint + self.model = GPT2LMHeadModel( + GPT2Config(n_embd=hidden_size, + n_layer=num_layers, + n_head=num_attention_heads, + n_positions=max_seq_len, + n_ctx=max_seq_len, + vocab_size=vocab_size)) + if checkpoint: + self.model.gradient_checkpointing_enable() + + def forward(self, input_ids, attention_mask): + # Only return lm_logits + return self.model(input_ids=input_ids, attention_mask=attention_mask, use_cache=not self.checkpoint)[0] + + +class GPTLMLoss(nn.Module): + """ + GPT Loss + """ + + def __init__(self): + super().__init__() + self.loss_fn = nn.CrossEntropyLoss() + + def forward(self, logits, labels): + shift_logits = logits[..., :-1, :].contiguous() + shift_labels = labels[..., 1:].contiguous() + # Flatten the tokens + return self.loss_fn(shift_logits.view(-1, shift_logits.size(-1)), shift_labels.view(-1)) + + +def gpt2_medium(checkpoint=False): + return GPTLMModel(hidden_size=1024, num_layers=24, num_attention_heads=16, checkpoint=checkpoint) + + +def gpt2_xl(checkpoint=False): + return GPTLMModel(hidden_size=1600, num_layers=48, num_attention_heads=32, checkpoint=checkpoint) + + +def gpt2_6b(checkpoint=False): + return GPTLMModel(hidden_size=4096, num_layers=30, num_attention_heads=16, checkpoint=checkpoint) diff --git a/examples/tutorial/auto_parallel/demo_gpt2_medium.py b/examples/tutorial/auto_parallel/demo_gpt2_medium.py new file mode 100644 index 000000000..2739a4c2e --- /dev/null +++ b/examples/tutorial/auto_parallel/demo_gpt2_medium.py @@ -0,0 +1,108 @@ +import time +from argparse import ArgumentParser +from functools import partial + +import matplotlib.pyplot as plt +import torch +import torch.multiprocessing as mp +import torchvision.models as tm +from bench_utils import GPTLMLoss, bench_rotor, gpt2_medium + +import colossalai +from colossalai.auto_parallel.checkpoint import CheckpointSolverRotor +from colossalai.fx import metainfo_trace, symbolic_trace +from colossalai.utils import free_port + + +def data_gen(batch_size, seq_len, vocab_size, device='cuda:0'): + """ + Generate random data for benchmarking + """ + input_ids = torch.randint(0, vocab_size, (batch_size, seq_len), device=device) + attention_mask = torch.ones_like(input_ids, device=device) + return (input_ids, attention_mask), attention_mask + + +def _gpt2_benchmark(rank, world_size, port, batch_size, num_steps, sample_points, free_memory, start_factor): + colossalai.launch(config={}, rank=rank, world_size=world_size, host='localhost', port=port, backend='nccl') + model = gpt2_medium() + + # trace and benchmark + data, mask = data_gen(batch_size, 1024, 50257, device='meta')[0] + gm = symbolic_trace(model, meta_args={'input_ids': data, 'attention_mask': mask}) + gm = metainfo_trace(gm, data, mask) + budgets, peak_hist, step_hist = bench_rotor(gm, + GPTLMLoss(), + partial(data_gen, batch_size=batch_size, seq_len=1024, + vocab_size=50257), + num_steps=num_steps, + sample_points=sample_points, + free_memory=free_memory, + start_factor=start_factor) + + # print summary + print("==============test summary==============") + for budget, peak, step in zip(budgets, peak_hist, step_hist): + print(f'memory budget: {budget:.3f} MB, peak memory: {peak:.3f} MB, step time: {step:.3f} MS') + + # plot valid results + fig, axs = plt.subplots(1, 2, figsize=(16, 8)) + valid_idx = step_hist.index(next(step for step in step_hist if step != float("inf"))) + + # plot peak memory vs. budget memory + axs[0].plot(budgets[valid_idx:], peak_hist[valid_idx:]) + axs[0].plot([budgets[valid_idx], budgets[-1]], [budgets[valid_idx], budgets[-1]], linestyle='--') + axs[0].set_xlabel("Budget Memory (MB)") + axs[0].set_ylabel("Peak Memory (MB)") + axs[0].set_title("Peak Memory vs. Budget Memory") + + # plot relative step time vs. budget memory + axs[1].plot(peak_hist[valid_idx:], [step_time / step_hist[-1] for step_time in step_hist[valid_idx:]]) + axs[1].plot([peak_hist[valid_idx], peak_hist[-1]], [1.0, 1.0], linestyle='--') + axs[1].set_xlabel("Peak Memory (MB)") + axs[1].set_ylabel("Relative Step Time") + axs[1].set_title("Step Time vs. Peak Memory") + axs[1].set_ylim(0.8, 1.5) + + # save plot + fig.savefig("gpt2_benchmark.png") + + +def gpt2_benchmark(batch_size, num_steps, sample_points, free_memory, start_factor): + world_size = 1 + run_func_module = partial(_gpt2_benchmark, + world_size=world_size, + port=free_port(), + batch_size=batch_size, + num_steps=num_steps, + sample_points=sample_points, + free_memory=free_memory, + start_factor=start_factor) + mp.spawn(run_func_module, nprocs=world_size) + + +if __name__ == "__main__": + parser = ArgumentParser("GPT2 medium Auto Activation Benchmark") + parser.add_argument("--batch_size", type=int, default=8, help="batch size for benchmark, default 8") + parser.add_argument("--num_steps", type=int, default=5, help="number of test steps for benchmark, default 5") + parser.add_argument( + "--sample_points", + type=int, + default=15, + help= + "number of sample points for benchmark from start memory budget to maximum memory budget (free_memory), default 15" + ) + parser.add_argument("--free_memory", + type=int, + default=56000, + help="maximum memory budget in MB for benchmark, default 56000 MB") + parser.add_argument( + "--start_factor", + type=int, + default=10, + help= + "start memory budget factor for benchmark, the start memory budget will be free_memory / start_factor, default 10" + ) + args = parser.parse_args() + + gpt2_benchmark(args.batch_size, args.num_steps, args.sample_points, args.free_memory * 1024**2, args.start_factor) diff --git a/examples/tutorial/auto_parallel/demo_resnet152.py b/examples/tutorial/auto_parallel/demo_resnet152.py new file mode 100644 index 000000000..5861371e8 --- /dev/null +++ b/examples/tutorial/auto_parallel/demo_resnet152.py @@ -0,0 +1,74 @@ +import time +from argparse import ArgumentParser +from copy import deepcopy +from functools import partial + +import matplotlib.pyplot as plt +import numpy as np +import torch +import torch.multiprocessing as mp +import torchvision.models as tm +from bench_utils import bench + +import colossalai +from colossalai.auto_parallel.checkpoint import CheckpointSolverRotor +from colossalai.fx import metainfo_trace, symbolic_trace +from colossalai.utils import free_port + + +def data_gen(batch_size, shape, device='cuda'): + """ + Generate random data for benchmarking + """ + data = torch.empty(batch_size, *shape, device=device) + label = torch.empty(batch_size, dtype=torch.long, device=device).random_(1000) + return (data,), label + + +def _resnet152_benchmark(rank, world_size, port, num_steps): + """Resnet152 benchmark + This benchmark test the through put of Resnet152 with our activation solver given the memory budget of 95% of + maximum GPU memory, and with the batch size of [512, 1024, 2048] + """ + colossalai.launch(config={}, rank=rank, world_size=world_size, host='localhost', port=port, backend='nccl') + model = tm.resnet152() + gm = symbolic_trace(model) + raw_graph = deepcopy(gm.graph) + peak_mems, through_puts, batch_sizes = [], [], [512, 1024, 2048] + for batch_size in batch_sizes: + batch_size = int(batch_size) + gm = metainfo_trace(gm, torch.empty(batch_size, 3, 224, 224, device='meta')) + solver = CheckpointSolverRotor(gm.graph, free_memory=torch.cuda.mem_get_info()[0] * 0.95) + gm.graph = solver.solve() + peak_mem, step_time = bench(gm, + torch.nn.CrossEntropyLoss(), + partial(data_gen, batch_size=batch_size, shape=(3, 224, 224)), + num_steps=num_steps) + peak_mems.append(peak_mem) + through_puts.append(batch_size / step_time * 1.0e3) + gm.graph = deepcopy(raw_graph) + + # print results + print("===============test summary================") + for batch_size, peak_mem, through_put in zip(batch_sizes, peak_mems, through_puts): + print(f'batch_size: {int(batch_size)}, peak memory: {peak_mem:.3f} MB, through put: {through_put:.3f} images/s') + + plt.plot(batch_sizes, through_puts) + plt.xlabel("batch size") + plt.ylabel("through put (images/s)") + plt.title("Resnet152 benchmark") + plt.savefig("resnet152_benchmark.png") + + +def resnet152_benchmark(num_steps): + world_size = 1 + run_func_module = partial(_resnet152_benchmark, world_size=world_size, port=free_port(), num_steps=num_steps) + mp.spawn(run_func_module, nprocs=world_size) + + +if __name__ == "__main__": + parser = ArgumentParser("ResNet152 Auto Activation Through Put Benchmark") + parser.add_argument("--num_steps", type=int, default=5, help="number of test steps for benchmark, default 5") + args = parser.parse_args() + + resnet152_benchmark(args.num_steps) diff --git a/examples/tutorial/auto_parallel/demo_resnet50.py b/examples/tutorial/auto_parallel/demo_resnet50.py new file mode 100644 index 000000000..4cbd53eba --- /dev/null +++ b/examples/tutorial/auto_parallel/demo_resnet50.py @@ -0,0 +1,107 @@ +import time +from argparse import ArgumentParser +from functools import partial + +import matplotlib.pyplot as plt +import torch +import torch.multiprocessing as mp +import torchvision.models as tm +from bench_utils import bench_rotor + +import colossalai +from colossalai.auto_parallel.checkpoint import CheckpointSolverRotor +from colossalai.fx import metainfo_trace, symbolic_trace +from colossalai.utils import free_port + + +def data_gen(batch_size, shape, device='cuda'): + """ + Generate random data for benchmarking + """ + data = torch.empty(batch_size, *shape, device=device) + label = torch.empty(batch_size, dtype=torch.long, device=device).random_(1000) + return (data,), label + + +def _resnet50_benchmark(rank, world_size, port, batch_size, num_steps, sample_points, free_memory, start_factor): + colossalai.launch(config={}, rank=rank, world_size=world_size, host='localhost', port=port, backend='nccl') + model = tm.resnet50() + + # trace and benchmark + gm = symbolic_trace(model) + gm = metainfo_trace(gm, torch.empty(batch_size, 3, 224, 224, device='meta')) + budgets, peak_hist, step_hist = bench_rotor(gm, + torch.nn.CrossEntropyLoss(), + partial(data_gen, batch_size=batch_size, shape=(3, 224, 224)), + num_steps=num_steps, + sample_points=sample_points, + free_memory=free_memory, + start_factor=start_factor) + + # print summary + print("==============test summary==============") + for budget, peak, step in zip(budgets, peak_hist, step_hist): + print(f'memory budget: {budget:.3f} MB, peak memory: {peak:.3f} MB, step time: {step:.3f} MS') + + # plot valid results + fig, axs = plt.subplots(1, 2, figsize=(16, 8)) + valid_idx = step_hist.index(next(step for step in step_hist if step != float("inf"))) + + # plot peak memory vs. budget memory + axs[0].plot(budgets[valid_idx:], peak_hist[valid_idx:]) + axs[0].plot([budgets[valid_idx], budgets[-1]], [budgets[valid_idx], budgets[-1]], linestyle='--') + axs[0].set_xlabel("Budget Memory (MB)") + axs[0].set_ylabel("Peak Memory (MB)") + axs[0].set_title("Peak Memory vs. Budget Memory") + + # plot relative step time vs. budget memory + axs[1].plot(peak_hist[valid_idx:], [step_time / step_hist[-1] for step_time in step_hist[valid_idx:]]) + axs[1].plot([peak_hist[valid_idx], peak_hist[-1]], [1.0, 1.0], linestyle='--') + axs[1].set_xlabel("Peak Memory (MB)") + axs[1].set_ylabel("Relative Step Time") + axs[1].set_title("Step Time vs. Peak Memory") + axs[1].set_ylim(0.8, 1.5) + + # save plot + fig.savefig("resnet50_benchmark.png") + + +def resnet50_benchmark(batch_size, num_steps, sample_points, free_memory, start_factor): + world_size = 1 + run_func_module = partial(_resnet50_benchmark, + world_size=world_size, + port=free_port(), + batch_size=batch_size, + num_steps=num_steps, + sample_points=sample_points, + free_memory=free_memory, + start_factor=start_factor) + mp.spawn(run_func_module, nprocs=world_size) + + +if __name__ == "__main__": + parser = ArgumentParser("ResNet50 Auto Activation Benchmark") + parser.add_argument("--batch_size", type=int, default=128, help="batch size for benchmark, default 128") + parser.add_argument("--num_steps", type=int, default=5, help="number of test steps for benchmark, default 5") + parser.add_argument( + "--sample_points", + type=int, + default=15, + help= + "number of sample points for benchmark from start memory budget to maximum memory budget (free_memory), default 15" + ) + parser.add_argument("--free_memory", + type=int, + default=11000, + help="maximum memory budget in MB for benchmark, default 11000 MB") + parser.add_argument( + "--start_factor", + type=int, + default=4, + help= + "start memory budget factor for benchmark, the start memory budget will be free_memory / start_factor, default 4" + ) + args = parser.parse_args() + + resnet50_benchmark(args.batch_size, args.num_steps, args.sample_points, args.free_memory * 1024**2, + args.start_factor) diff --git a/examples/tutorial/auto_parallel/imgs/gpt2_benchmark.png b/examples/tutorial/auto_parallel/imgs/gpt2_benchmark.png new file mode 100644 index 0000000000000000000000000000000000000000..eec121758149b516cd5437cdb0df140b753f26cc GIT binary patch literal 66851 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⋙I<9ShUiCT|0A`)lcX7O%Snvg1M}6Lc1yu&(&;B zVIt%VM0J7(V(2>YMAOaj@mwNxGS_QVnfY^ddIgk1jBo4Q_sPy;%Y8&8IA^D*;*@et z-FmX&36$C#s~cfBf)k7_MmB0&x(OqBX^_?QnR|j zybzdT7J3(?wZ^3ufOjER)old_%${1Qk46FS9A$0wuG8tyLgr30^?Qt&US~4eZQ-8D zEkf&E#+`FyqM7t)jMP22r9BV(lbyf<>*Zvv5abU>BQy(Pa7#Rlz0fWjhg!|$ig)Ze zYGtjUIuj|$jcXMhu8~)nT@uZt&OY}!iGHlwqi>Cf*q5a4L1HE?v%ZBX4OXw>Jvqx^ zuiQ`}f3ds!>*5%x%gZDeI;lT3fPeA=DBZDOVBO^G_?d-23;J;N%RI5wNPB<9{dL2` zMmIDsZJfd=6Ys*l-kA{^4w9msihslyXUg#N-Pj`Yo84};!APDsF|zFBxW^wVl6F;{ zV)#vgtl7RmJ_=2gfPZZhYVZq*Z%~npkkMH$<5ZSW}z+SlURev`pc6I$`l^Uo%&N&!5$ZpFt&6rrf-F=07kKFuIV`ZR2YKWaDY+>DUjz{ps|0 zUgT0jA}W&EvQyGJNh@0{-xj)X3O#3}ucG!z=c;Ga>NyYVdfi<|xOrndXIs7g@S z^VY-FaZb~#%|eGHtRAIrR>t3?^n-i+C4c;D*095F+`Zcl!i;RhYibkO^e{&ILQE`t z3y0dPx!PWieX|wm$8W#&Jg3|_mhLe@EBUHH00y9@4gTw9NDi?y$}Gshh@XI$1AU}C zVTwEMV#8Qldve}FAf3oQr?HrYHv`(k2h+6fcey(nbY1%<4oUSf;*|^PR@Y{a|O)hTmI@*vyrB1uV7Rp4QvV9Ma9nY zoh&0Jxyhyl&FpFcGqOcZKBP?5Ju>2wHB-&7%zOd~os3jxa$y1`#HOskehntBt)@F>HaXP|^NL@Nm$ShTA$;Dj>~$>laHR1YfTs}zz)FujBP}ZHhjAq{Kg39@hFaE55}XlBl7N#oxX$P zdrMDkKIUHY9Fgcrafk2jV_|R+iinGog1I#Ry#3CkS>yw5U!M$GZ-6YI^Ol~QC|u;; za+|kQca~`{FbkAc%-l}pQ-G8by%C@~ zBUst>Fy7=Oz6l1hIf)o6@jH7*mC!DKS$Q^Ecd1W6@b$3*Q}3-%nw$eRh}vioeIXoZ zF|G#GtOJHb8DwmGVdG>$!*Ngc2}5DBic6Z|+DxJ*Y!;44>gBR%(n1}sP>wO$e)#UU zTrzfb*U*QaNQHNol1RhO&aM?Mo;$~upNX%&#r1turNdKkf8!#viKD{|(Z=}nAKU3r zS~^tVvB!7Gm#%8aQdp=$EkjHD*2l*urGI~d;cz!X>Z28J#~XXiYWU7SMuqyy4!W%s z-pi`#$fj6(Cv%ckOkl6|c740s$f zA$&4F#$(kYLsQ3a-Lp)fa*@i1Neg{o@Cd+RO8{+>q{{pD0m)IG4+{POY?Ywprb3ko zX4|RnI=RkiHL-U5ItpGDJnp@JDr|9GqBKi3Ika_$KTlY7>O|)$CM|^*C+(cHy!<>s zHbyW5&U~UW5*Rpk2-jDIc6w5j8HrXDqz}(d4_aR!#ej9MVsQD2RV8OG5gd@6AlL^S zFn0xJK0yZI_E1Ub1~N7Uc>Xkyx{7A*#jC&$h@_4c*gmk*y`yhbU^v>=N!`rYEN*KP zf4H+e;J?;scAaeYh9-uA7`aw2`eW^bQuH>z9UTzCsUViQLM|8su6ODS@~yBHcIq;M z?|yaEt7*r%faAQg61uZKPPgzLwWzMyO$bBQ?m|Z#G4$;lOf>{>TK-IcA7j%k^yhry zDC^cC+OU5~R^T>=8S_Wu^di&#P|Wo1&6^7oY_SkYO*9L&yhx<_UhDtehP^DH)8K^x zR|jyoz?>5YV6`j!>Ge+V3?J7sJ*C=?=9TH+H!>S|ZGQRf_YUov$X*U*XU{JFA{#uZu2NaKRLe|*u9uVVMpdVAI+QSbtnl;m zr#!0ls$vA4*`swFNMJ=Dz`Zn|otcyhvmlV|{(7w3oOric_i?%cxh*4E7sbVKQY2E< zypM?Zj!Xnw|5>v*kbM)tin+P?nq=wGI*7lC@dLjs-AA`pb%dOa9@4syYlX#RUE3Zq z+JaK8Z}ltg74ki1iVj&S+B!QPLuxcb(0D-ZIcaHW1R{8jYzrtHKwh~4Kn7gy@krvP zbkF#^)T6>(s&I4S$7QJ_gCG4vLoV|(qx&ooPKN`AVnbp{25Q=c$vP1jCWPBeYAXY{ zN6xb;{Zu{(<8mfrUb17hBmz7kur#p|ajib$%dwwc3PEoovIA>k#Zs@cF602HLYxRDJwxRpqzgY=r~3*J2B^tQ9~t&Nn&>{=+=bl^NHbuR%!&o4HUwjpa47c=5`~-xp@$5g0FZx=%v4N(VLIzJE6vlc)9~vN?Kg^s z1``t_3Db}EVKkCd*Zj{w(bZb~sV9Q14`< zq&$megJLNa>bZvI=6)C>1tR3VVr|4O6__z8sHGr^>w^^7b+=eDr(8HD`Kx>UX?>-Y z>>TMIOeX=FL9D2#NQ(UJ_vi4}y?ttQy10spKh@QoPLVE)?wzXB`kV9izhbgbk)_~}V0zcI)*pxU5fT@^dCO!cTKagqcCMG7@cD>>a zO-)-c!|hySNIZgCsVS$hAAVo5`-=2+$D!An}u z!;wfGX%RV<%9ks~Zfq}U&OahSCtMI;P}%SiR_RXWB24g&yJ5Jb-JB+=mqqodlKoiOEcI<5uux*TGbo`8Juzox6yHQjpAk=0XjW$#l z&odT2JGKoK+>(T&y$`X`(;9dRa#ydSLwAO$-G~z7%fp6jE=CONU7F2)uPUgU!z?u8 zu_xkswtFfY9#{3eP3vn!@SKbOd-31CJ%ZF(+`)lc$YtjlsF-Hv=lh|j62k_`XevA| zHU2vw$9mxSVCF6%Z>t=fR5U+5!v-+I04Bg!HSAk=;PZ@QJ%rQ_ZlYg+&9m}R5D|$3 z#t8%mGK>E}F$r&Ys*S&UV|`m-6!c{53!d?JfU%&W zrk*t}e)#S80~kQg2f?aO*ks~C_z?b6+cEn5m=Y(P@0kTJ`u^PAw`qM+t6dcC60n&t zT*@|2mh{LwO-eMA5s0Q=5;%k~N2e1R-U%nmc2HFv8SMsBm}OmD_@Qwfyn)@LH(|d} z2?>#T0fC?sM^R)6$L$lJ%5E zZYCX)vgrxo)%Rr83fgZfqG-y$rlBJ3;TPz`c@qVN^&t) zz64ea;Up1q$7`jzP2u5@?Kf{mS=yrN?F)&bjM+~F#c?3(bfy}1mUPqEp ze716?4d^I2UiMG|bAH=St8NLFn3jX1c&1(cf)r6hb=j|vPqFvazm6pEZaBmZ*pL~b z83;Vam#5FhAiu@M#RY5?9UiGv%wCo-9@tuz*izTME?H*8MUVG=-s%|ib33#?wK z0q+2{(i;0^6cv>>u--TdFzOO6sxQ*j!NI{8TanX0&H85oG;D0)(4c#rj7-+fZpWhe z__n?y6iESLVUxMZs!AkfcIU)D7Tynh@EuPs_2;5v|8$C$s4+EqR05o~u_+1htf3zm zZjo7xEp#}`B=SeXAiwkP6H(&2P!bz|v22N5y<3FRzYDu$ZZ$SL?`O65TM?}W{baXp z`d7;wpImQNa%O)XoBIU6F`VOJ19<0l!dc%bou#@LJ{CXe<61mv;7r-2Mzdvtua6@L_qvU27)#nTLx3WFQQ^$35EZ6ojn6+Cfu7e z?}NipLtSYbyRRSnZaWu#x|Cb_^ZSK~`16U8DEf2%(La#Hcfe@QnFFALkU#^jMaD4D z7AfhE#M@m4%hx-;$G9{H2=*0{t=^#ySJ!B$Dh4dJSef@=lhxUHbM9{rpGJ&X%q5ODW%LP@TfOc*JlCi3q2QMyBS&q*aNQB~7W86sY2$1GJU=e63 zsTVLy?+OXK5A0sJ*;?#}b)aWRXyIp#02Xbc-3@rlbI^)06D~o1Pe>@SYOONJte_&p zz@bT1U8fPLtAOA5mL9F!2J@?&L7|HTL8&byyu*ynR7gq@AXe~nf7-y<*tV5A`Y~Ak zD`}S9tK^Qqyd18m5y>XIKIhv{aG9SPt>km8@m<%Zm0A!6Pr_AuF(Dj9<`g;of){wy zc{|zX7E5Y=p2cyF^Ld8WP26kFj@SshTFlRB@UV;qQgJ+_D&Gr&($7JHi48KMf|@-o zFh%c%RKKNay|x{+(oK*!SF2mY)VdCM*OJoGRB*L{7Q`BY`PN&JV{9(~uo38l114w# zk%OT3FoJN0MH(u;(m*hbj{^e?#dIkmBr5{gPDZ9f{-hHA8G?=!K{g7?hz6kbI)Nsw zmSzFS0tJd>I-tW~-s)@5v!hA7<)KxcGbT+7(xU_1%Fi2_)s{$QRD@aa1O1W3t`U zk@7bgR1_vGU;FR9`4N~33AL)tcXLxX4_?5^0UCv*vZfJ;>nX0%hoowf2AClUs1h*XR{ z-yiWAlFL*&eU|#sWvjzW4nXv5Qda;7Di%_M7GTYh3>MjeFp*P;goI>gv7Z(gA^HbU zcUg3r_2xS>b6Z$;W-Vq1$9xF{l#v}6kSixH)D!W;2G9P`03$1G&1P|r5zP>9?xmst zJ%6LCo1lDo7a6H)BTR@#)>48pIiqXw=3#wP+COrmpsgfTtb9H1J0N?jDI5`~RS6i@ zNqKfSTvt99X9n5i9eKgc^APfeIExWila1NTrRuDK7rt&?e@LSm4{{m6j^+FB7gd zXPU3xbje`$ssL?(s@fMk=6V2?fvc?%4(-daFU+9eA)`&OItMvd9p4ZX|6d_ix4}qe z*vtAbmv(1u!ZmEVzprn9JNc{w)=jh0j{Yx93o!Q|hO1uYIv4_D`<*p+e;>y^0>sl==#b5!UZJ9h#x;+wI6_S5Y!{YAPgAPZEWl6$^d#$aCbnt&cw~af(3TN?}Dne zRQQLk(dDQMdCzyHuJA2htF2u4UfmpqSFF@#ps7V2m7~@S7T8K z@v>Z4mjtpsc8_BxfTS8~0`1%AGp*py<2i%_MeZ}KUl6@UbB8f$efPQf1C>X)e*x^J zQTtqgDx<(?AXsI{VxsjU1?!yNbX}%;{Na^_p&0T`vx?v^sO$kyZ}7Z*uVUeQ*%lZ3 z&#YcUTDd+6N7iL@q`tSDG{(+L5J<}{Q*^^lqHzU*!()q88@8$&C5b|VKO_M zs|>y#pufLgFGS%kJZ+Q9&SUrB`$fAc;McstaorBF+9;l}R#71=n{asQHF8`D39UcE zm>>e4I=Xw@aUO|xdkbx;hzr_Zz*kj6P-y2dKxkl)Z(KJnv23YdlYKc!*Q$9BllHLU zqCcW}$xMX7TaZ>kLSczDmt^W#00)j5apP#XIoIW|I1!+S;}A ziyG6Q`LUpC@z_>3u?1)Ph}c-otx~uR5#~^Dpz`^B&*lE8Y{$Ks!kV$391kv=%Yg{a zU6Xtm*MGK61T+YZKpEwN3N@POJ;%e6vCew{J{(nXzkQ$fFhBmncR6F@5Vi5hJ&A9> z&$GZQ0?i99KL@%GTM2CY^-fBx|MJfOE;>Qt{OaE%gn%C(J!+;pt$+JR4K7Y4m(ko( z{*^N$BK`UF&(Cy-%fgbHy(!!zlI2?ArTd62sUxVb(uEf|kFQUVDq+qQThmt$QEYuF zekR5ezn!|+TTSfAxBVbYLkSvKZ!r=wlYtjLCb9RBNf zS53n(D&eFMQje(DV1x=Ba+B6=s9Ybw$O)LpjE3Q%72sv0S>?bCO+!+xF`$Boc3X#< zGe*dj8(v?D#e_@U3>`Wh9l~I(?IB}(kzz0yG)HW1OANxAF<;9V%QjZqn8!~nt_Tt2 zH@Ci8vR(OVFX>-OavvR7{U5xla>vlnF#P@d$3{jp0RaJ`nN%k74(5IzGQat)|F|73 zQ(h2V-}hsu9G<|o%18l_!r>aGZphm`UhLH!FQnVZN>nxNP!HbNl}7qH-1_s zjxzvyV^58nFToZ2>G}6^Xo}FRu%U+XnSrmYio_o}Z=VBeRkz4hwt3T`0-<_`E0E27_i*UwjzjkqEK$>JWZrygv%1L~Q{i%%qD$I% z{FrmdaBc(6v~W!P6E_*cW>W39$n!RcEr+Ynb1#%oqYY!0-}oa65U9r3VQ@NJ#+~q{ zv12%luR^1+W&H@ckM&389d2f75$^EQG0Xd0+HVEq%{rlk#D~4FM87dycNz&fPt+}4 zr`JDzB>#LU0JK0XpRJJ>u#t_#L`135{c+>APt1@I{Ih0GvVeb&GHxJ8#zOS^^ev+Y zGo5^P2g^<@m&K(H%-lP5l}05uD_As6}JI z&46<57f$CdOLF^XGX0f4EE0m9V|K@4p%RP$dM%V~d+}#A4Q-jpLm<)>%d{T#WJ_b( zuz&=EaV5dG*`|z}Avte{R2N}lJVbe~#AYi9`F4&tYw!FdR-5O}d|Dhg?x_|(QBcN$ z&WTwXF6;(k&ICr?vNYF$i4gP_k;{O4rVyU*qY?{9_5A{nD+&OsCP0o3UV89f?l0PR zS){4etqgGenJ6Dk!^N8}iz8>Doa{Hqcpn#qi25C@sxc9%dHn3zQ>etdEr&ljeeOu=`}WyD)dr3SI!fo$clwL|?^ z{}I;yOmTpWj`ewnj!xDJ>Imh<4ReFCZO2}fDXOS6z|GkL9hJOuG5Y>tVe`l*z?F6x zKA}(drBW`QI=SmL_VYX;-Tc1@k~^JA*FUwS{5dxbpVP^S2V zX&t!+My0^_+ixr01r%Xkb+uqY#oQf;R!^QkzXv)rLSkZ@uNQ7TfH`QXA3u7_v0eMW z=`$LDk)B1#Lkp&A=X*XuF~d7Ax-{%=e7IK4n{}DCBSTJBePLp3B_q-0CDGKH1?`52{r4j3Mds61%Hn zTcJ&lg$PLTuSIGU8{q@ypbxW^>{fn+Lo~UVsFVUZc6v)&;jh73g&1kA?NibN9g4tj z_tpe=6<9=?xW=hX4w})EnEl;wdbF3icr~obWZRl5qi(uTQof(qGc$kA@ z1J)Ba$jCZjEY5AvC_07`9#wMZf7LrG*}O#rEYAdx#eyJRLR7AhGueU=1}Psm0GrtOp&y3G zlGJ|~>QZN?0ud>l92&CF|M~hz#RVCy>emGGnVTc2yLs&$ztaoVH~NMddDC>c4jnBT zG|BENAwk1L8gsvc`V+$^cyBiSvOLzHU^uq{!bWi!ClJ?31$=YE z6Y+e{7){!h$!LRUY8?xOFu)>sL!K^G6R6dV@E*{nn}A3(!CRvrd=pt}_h0C`Z8owG z3KnJ!%VYL36OJF%?t9>@cWO4%Ugl_Fq&r8+&(OfeY}OC?7s3$uXxyDuLTPl0VxjyyY{$1c!$(l(`rT+cDn=-3RHC})%hq)q9>>J zjD~u#EDNMR+S;UyYI&4=d?a3g!LYp=-`F{e-oHzJX zI+T{C!RpD8-_G*5e<=N6yUMmU!z+ZSi>}Y92cuz0$shJE#^&ZsUpmkl*8FL&_jT8j5&oy=#5xLgEKh zBt21S(!rVi+M200-HE-0IHV4QY5&r+Qve>haf*Z_98XafJ-Wxcl`;xEm%r}Y!AzwD zX#;fK-{b+F#T+zlA_Cl2zv{8r!%>u^exHYL@ra~OYdW?`Yae#e{HGvRZRRH67egzN zY@RJ^n`r|_Lj-hsR#Yipj^Qivg$X~vq&J6xRWkB_bf`=7Yz_8>sDy<59{94mIGla` zEl=(u5OgYmdemFZtE&eI`s{q2NR3f_l=?jb1TvU;T(XVEj9e==o`IoVTw*b}Fbs}IabIOtJ zIM$0vdp7v;+y3k2qiU!<#_g1Yqa~@^Zn<=^~{hh2-wi* zu}++?M}+c*5><;8s8z=QR>Dx8m(*w|F27ocDiW0aRE+bP)J2E}0$B;*(J%~+7h}@x ze*Jrt(}du_u1b(x{xxBia;88$KR5?Eo?@5ns|?NJ+dufoKpA$vs2@pkE?ek?Peu;}w(!u|ngO?1mLBCEp1MY)N&YLi!l-!Ub+`Ra9D!wN(jqoC zXXMk()Dm>(CuR+|mpm~Aq2emVzqj1q_jvSm4}U|6^+$DZNF>3OPiGlMTs4$8i&$Q# zC*Y3i)SE6)rxX3RG_%Oke63_cf(ihZMTQa{trcHd(L2lUJ7UQ&*^BE>7-;`x|NF>+ z*}cz1ds$bQtZ(iUeFk}^MP2+AQ=8Us*^2D}vBW)Q^wH~GnUT5Oh_o%{!W92*;==h= zl5836lB72jLoIk+G$DGjiPBP{bFlDieurSc<9?g}0d;6R z`7LT;RIo1-A6f=*`2~<|!v70&zzg;o?k;3%$pC~qTXymPgot!ps_9lu=^b{QGf zPaCAY+BOCpEPO>IL4Czeu>bUp^7W_pwEaA4Fdy^^(^OBO7jPV~OO$e^mK!K}lwyC~ z(C8xvRy8mflRje!+6=*V|FTMNs9impditxvf zlW5s3Lruk4HscgO^SEmf1A6?sN;Njxpal^5{QqLp;fb2(DSL>>(M>Gx@?>e&axZ;? zf}2)q7?sWcq8&&!nDDk6G5Eo8wSJ&TYGGya2x4WS35?Jho=#w)Cml)U1|;hr*{{gQ zYM+zF5GqE9cz72?So&NG4iHE@Vxf>JMq+?8^7Gpwk;S7>ik>FOZl7Bb{Fzu21x3&I z)SXwsiSbQ8Doi+Kq*8!E+*wa}G_4hhgpRAc{}Va{KrE>1y3E|AYlR;vR^g^R>vXkh z4?jmWkbs{Ho%88m5Eo@)>HGaTabEk2fgP@D4p%Y|YDjn4Tk1yGR;F1=#a~njwAFh; zcKd%FzdD_{P&aayT`~(DM;xw4W18UuAx*=z@^*O;?(i`Gv$#Q!Um)s}&P6jMihHM1rVJ25gnz47^MmKJEeNa@nCrk{0gn~u%&TJd-CSW-qWn>qg_#VR$n>{zWf9g zE-b}sw13E4@E$(jM|Uv<{aPT&Mzm;4o&Sft_m1bX|KEqTCmN)(8bp+tS*S#j>``VB zGRoc=O+^wVBqJ$%6(K|^dt`*{J+k-acbww7uJ7;u-jB!q|9w5K&*!Sd`#fLcIgjIb zp4=;NlgP5)h&4vNZcN+hD9ETlgi|=Z-&cKAe88~AM!pQ;fSYME4RRCf*rEhI?z85K zcD_0jenjG%{rec$IPXKT5zNI&J^^+Xv-^c#`-)3D?HsOjI@E1x@O>oq&n{|OO4Ii& z?EkS8lgDVt#>T^R=i8tExSwNcTlwmgP{Quy_N@m?Jti0;lM?>AlCT8>HECg;?)RLA zv-|bpnpDj*tbg&(T1s{G<3Om#tD0_!QYWz8D;}^eGtllq!+bT3a8UX~Bc0rYC)J*jnKn`aF}#~9 zHasL^`ex4kT4rg3N|%o(`9dAWRDr#o3wEL=Ed8aQj1pM|Nt6L;v&s963rjm&C36H0 zpV|~sNJCoiyrnpUi=dV=UcQh(|kEsaSge)z>|6aC_tpl~(M?40t{$Tn(@+1S#W zTgh*-Fx>V${FF8TR>ai?le>se01y4#_huV_RUj~l@7k@+Pc-*! z49?YeFr1Csbs+Kus-F^du`u0f_R~^`q@E=D3-A>~4Pp!D zZDgrbt711+-D4GYHJrG)ysO?MkKDGJDHhey{QAJ_e{$5$WKdB2l2%Sbl~nHW3;GRr zE&nLHhii3<6PL22PmvTwM9N3pr^AF2L}T6FmOiFiUT{_QTC3aKkav0jP1RvLw zDJLH~r~DK$p+K01U)&1bplSQKc_DBLA4^yyC>z{BBw8%A#I2J?r`LI?=B2Q!BFc(q zy9^`jc2pTq5^NDL3AvaFdtZN|rGu9=KfmzWcyTh}4G{S&!V)r5Am4}Jo3NZNg>P58Pv_*e|FB^Y`E~sGeOcQ9+!(E5BFcXiw5gIv9-J% zB~CrccP35&g|%sY`K7Gu53nd^(2T(!;wDeKuu@iLw9m}C-S>zxNGA5KT? z$grS1HnU!vN+Eayo4_1X>} znraR&V!M@HA1cNJcV6gSxWhNwdouf|J&R}8`&*q|au!!!Cwjn5+5}oNQ_+_v*?vsB zt8UvTe|diAYmr@KgOrw^y~7;;vT=cXSGp$W2ekcF2uQ64D5*Wn(tXIztC>r3QaAL!~fAybWrFmPjXZ)=D-H7DF{5!!KBX+nXwWlGYl9m)=3ff?BvH9uQYCY zm;F9EY2Zn1|5N@VtT1tne#BDQe;(cHER6#p2HHIk5@dm!Ib&vHanY1)gb?*Cq4nzB(glh5AQSva7;(65VB^y zh@#I)4R1viYvo7%mD>g(SyKXM~uRwK6C+bR8i z?TylbI={t0h3TuB`(>Ozy%6iIx1Ai*MVoX3QIT~6Z#K>TU5J7Y1!x4Q+FbA6GdyMH zZmV0!LPBubt~P(7alX)~vFUxu9j|WDYivn^w9?KEjDS<%BXlLft>CWb>lpt;>IWF1 zjMJwV0!E)kM_(ur$^4f<@3h&}Jtv|y7}2)b@Eyj^XSdez-}$j7WxBAXASBu9+!9Hq ze7t4JgtY2XQA@JZvlP--G#eH)Eqj;Gth_%ZCFL@58CWJM%}HN> zn;X_|RJXXjjqGO2E-87j_LG|4in+R-9b+wn4PEnHx=p_hb(sH@PusKAHK#S? z`7_D4|G}o0AN6L@_%xW`4xZpXgdik9?bhum=Y5J~7+Q^g`d zBGp5tIy5t7G{Ez3eyUVwTo+X2IKVtBD&gvG4g!u%iG39 zaziO=zvrZhOucy4wXxBHr8_c%EKaw(p8xFqw%`}Z5P4#y(!oG`8T8BE=uaE~?CEre zB_2-+=}^zh{nc9^iFT{e>4`$KHF{S*{aZSSJ%EG(J6NREq;;XI^tN{BS>njY34GaL z#wnLYcXe{JZTFwHJfWd`Z*Mik&q#VpGOYxy@}{sXU{>7&+IL2~KzyrnEx!=2;P=O| ze+VW(9LZlF1+n$%h6O~UlsHb)T>d-ZMS zn-ZLN`4Ed2`C9TnS%OJXYvyl&{wPtn~3q8Y3FF`&9^;rf7&)1bUdxiuj{+`Qm)Jk3d*m}GA>phLl$OCt1EYO zhRZQThOVxnk8txlUCzJNoT6pSqgqw0TXu3@y}`$5{JhZcB1pw_Rw%XN@hcT3_h7mN!Vk zLH_u`mn+5lYU8G_CqGtm*;lJ78yD-1lY90t9r>BA!?hsDxb)>09m4_}0`&L|ME{3X~y(>x0GY0yS}RyBtp*u|RRTDr!Id)t7U@|E^jcJ%I%$Tmnq*>5Mhr|7LS2X|+wmDO|Ca2br)Z*_BP ze(Ldft69TAtKOQU{=3Oy364~@zjzSgK6hOP9)f~m&&W4l*6Et?=I1K1=YCD^9ps;o zEfqQSK(@ywW{s-i=C|yux17E!-MeG55}QR*xOqPA0wQFY2z9gUFA>Vb?G2HrXa;T#$C_d{Fyul<~jdDMwD z)LLCbN>K!8N73?!HA2@(U*G9kLE5bnLvYLvOB<*K8xky~nYsU1BS%i>n@9MvczlN{ zK9Ka--4I%=4kw-1wfoT6S}h^6EfPOFz4O0AXXWDRfpB928_8^}av#WJL|)W>G6ffd zV8jsZBBYGp&z;{8&|`9anFN9pNS)*qFX3Ke@q-mjl4GIbotFnsj&YP4H=8!s3~hJ) z%5$1g!eOOU3hZob{paU4dhwko3?8e0reU5Toos7wgQ8uj2aK|1&E|jCsSlIvjSu^7 zUw8>`C4EE5H*3o1JgByFbhZWI!zBu)lSR*3n$M$Hud|Z1>^hBdCOD~Y_1}*+y|yy` z?WJWNXLau!8Wdf{NEOwNpN*D2_YCJtnYT+4<$eyGUwUi~c7(MUKb1sRrco=vRpQCh z{4Id$+lR*-odu4bOh72s5vZ+w`mfLAJpA!du-UFVP-`Iw2*UD61tvgK3;?+Wthj#2 z4os6#CW@`)Xo@=vM3X8E^%RUzS$B2h{Mk)St9?y%kMlyyN&8bLye>YJZii#dp9vN^ z7v{!xq-Q-t?>OCerQcJj-eFsF z?Ddv5KR64Z+d~W$8Zs-6O=&6wWhWbwU>BbT{tLNZcwZwBQp3*fP}Y66d`G}Ab)NVc z<9E#h)|(Q-wPZwhsLV`xlr(Q?4HfDh$(s13=}~fLnEm!QYm?kuP$Hq%N?ZX z=(jUgJof$j!qY@C*#z#hIywisT(5MunvQG=Kg4MrzX)Jn?ZV}uoeo0P4&TXjoSTKT zf8-iB1!O**>Wb0P&>KlS8ycy??e&G0x;#Zk^cBNm)#ic%_Aus8T#4m!UNa=!beBC@ zh>}W}V}fyx^~QM{7B!oW%7gC&*)FW~?t8?~-cgtAaEB=*EuNF?J&OH&{%}zs3y=TD5SY9X9tVyQKHE3<09)8=Y zYFacJ9F$c}uk4sSmze0&TAGC4+8sPLbA3u@&0x`d?}#7k)z)+eI)}W^!G@VrCN2Vp zCr?dw>B_#d9%=U+axqy-?@p{Kd$9kK8@)^h{gEa8GM%Mq(kh{(=@H+h`(^Y^W3@$0 zXU)6Y@)Uyaj7;_0^@k+>?C)vI<9_(nHH+iz%w4|L7J9u4C62qB7TSaIf`qn{^(oBT zmd|ngX%q4k>NDu!51AhMu!W=THGVrmZ#v!i!&BwbLtmNZv09M^^7EQn^ZYk?Gfck) z0l7*|kRL1I_zfW$?ViG6gq8oH2wUEb#Y6r?)3KFhjW1r z4CJ`yzeUC8z68mut|u+*`gFNaiW;1m2;(XhI?d2)qx#Wq(>hJR!rXzhq+8GOi+pLM ze@$^DFP#RYXF5P7`Ww>bWUPe$Lv5gW z1TdYvfE8+iLHzOS2mlhZ%2)XfohxmKEQaG2Ox>sW9-xs}5qe9hDK+$Da+LVhoH2Uc zV=mU_I#viX*xF!F{EkfvNn6z|kJXuyx;TY8ZO?3JVLmLw(;T^6OArMgQQQ|8R>z zrP*DEWWl?P{tnBjc4aW8kxy1MI%h>kBdg#e=_LkD3p_&tH7#RFskIUlp}0?@>{D zdD5h&RLvq|^CHy|q095B-C7~4nOb!0D9EN_)JbKc&Ur!W{>|A?ZXskH0QMj!0jQa= zWQPlYp@c*R2VS)<#RM3*8JWeo=A{Z8=F_8iaBomH&iGDdUwSqE7L5wB~iBa+VW-bq^-^YicZnKCeuG}cWf0q@`=ci@UQk=>C@hlZxK^F)A6{XtGI)T z_Qy6VtJYyXp2JgXc>+Y;gAy#ZjXTnXh90I;`}ebEmyk|0aN5&>$#z~!@lp6D%eJ1E zR)^*eagO|4Vr0%g>a<+G@J20+=xr^Y=cnmHdB9F*c7N#E;qP{|y}v(eUcWn3yIpHx zo12?k@Od#&b)Wq2aNNYFBtc^4LIpXfSLB{*-xCU0*VraGJ4hSV9N_vo_Tk!hfoHSF zjhjiBMD`K}W%*mIi}oGx9>3=-bGgtWn0*sLas3%@@iu=wTQRCzEVrB(6kVmM#EG>g zz9UTN!^kbih3* zA((}LcSfqEun_`#;G3sE@jqd(3v`AO2*ASX?airz$e%(aysJA(+H{&+)dOqU5?D@mUTv z1p++w2qNHtfM3eRYmRhP5^T(rCVN(DUgHCxG!Y;{@E=@&XY$RcMueIN$lN}NP>}#I z`xZl>2xL16^cuXpy}yAqly@_waWXm$IQDoln&2t^z+0G8zps7xk^wJCHf_=Dk@*@+>Gw8h|R0!kTrBfhdQ2W#2cJRRV6& zlI@^x?sZIM1Z)hmFV9}P)_N=Nm}=6El$oxsF7JQ=(Lo`ScVh z9*&Wl6gP&`OEOcq^}EwlQ}0i5eYI0nez_CPfCcH=zGHx|M%{uGVmIAj+>%4TtK*F; z9f-J*9juIuj6E-sf(a5~95tsqtP2wCv6QBpg!x(^HP#rbv{;s^!9A2eVC-@uD|NEY zXx~ZeW5JG-`!I}>ML-jTHpsWu0$|G4&dtRYp_S!S;0N|zaNsgCQbI~93>d4bIE{dw zo}Oi9Zp)4otIc{=ZQStsOdIO7=oOfgn`@(~HIF0NnL0o)VXd*5$dh;A1?QMe7490IWT6T1qu+8h^l| zh~B<^ibO@jijv@g5n3p~^&W*{Z3lpi9rwtEnG1CDpB>!3|HLCGdYD3&X$&Ufd0=1( zqp!Mo%hFYfR45Fk+4h`(Aci^8i_Bma#F;wyJY}ghPuu$19`RibsLWlOs#dh0_MoXa&g|;Q7JR}F`mYW(lp?}y zg8ZYi`9D^I0SYt3qds=%y{S)*TE363JDYreuO@AS2UJwt@glFbzh!%9dN3)A#J-6> zt#&0InA}FZOj5?(LvcgUCW;TruXwhQ)_$2u6?(YeYS2>@OJ%0>d*|U zzt$w(GVe%4OJ^sQ^Q_^EcI%*`pnLXWQw1Iy0Zk6XzvD zOd^;5WU2p^n`6-{JG66w4FNALhbDS3bH@jlA!0U5ho z@=6D?=~Zjo)raS4Y!}wrCbRc9>`z;bhsc-_La`_ux$XOPoesonL0LynF(-cmJIno) zO*w_^2jli%e}DGfA1`+Vy~KO;xrJ#2f*!IjU74RAcRtg{{ZG_MIEo7_ zzW`yKH|W5i0$sUuLmJc-d{E%T$q7_zDRQO|5pKQJbKC5n72EnGAmk#;FS@2>CRIsIvWU@)eA+#%u{xZC^D~a(dxDi(P`iB zwN3NcRAsxMYjz@^D8m$m*WX>IAl_Z_-D7vI>7u!9B&nSpqQIKo%io~2L^~hOeQfEJ z`Ko*IVIht%05`g3jgPKCSFwTZsJdhS8Lw?$tavi&sJK*es65Z|)BJOKB}s{&?K56X z!$vy^$matZGuh*db>XCME*!t)letrKU>!ld;nG<_~?%xf$ z6qd5>{Zhu3_irhr)nB!Bu1%uwmcQC^BSM|~pBU3ekodN(fQZF8JMKX`C>JeBBg#G~ zDgUlEe?5Et1HO&lK3|bd+XEe0Z|}pqSJD9a$m=-1k;5tEU)n2&s&@keI<~U78-iz# z9SdHcsDv_4L?f5^YBcL3xeR}dm%dVPQ7fLLCDEd;GEKq*n=vHefmPHaY~q1x{Z1Ublsg1)Ad)rlx3#yZy9TT zNN%$6+t2;VWC}A<%o|(!DjQQc+w+FV{IwBv-x#rmV z;`{;mkCK0%4j^#s1g$JNq!ht#+JP0taeWVljMtWoRtMWykq&*)vGzA*7CSnROaHxq zQ4zOoWGmK;0pLD8q{2!vo%eg7w;@dL`dX@vZ;w7+>(;wby9H6XcH5zUHqIX#SFvVf zW{Nr$D$FGFGvu2r^yVIVZKK;wo=JCi_U5&0wH;c=|J^nTV%s9;)m{Ys;K|XKzfAES zpcQq8v+ns>7ortfTQql2($1`ITOk2hu8RjV_S$eluW{M&5cEO`B(W83$gYVf)I( z3tPH|H*k_ur09Ccr^m^}^BmX*yWX}qAVcnW6y#i+o+k5~I&$tu_EFE%mi=GyR<|V% z+mfVp>eQ{B^z8Wupvv9N{^x9EozkJ*(?!nTs`TCHr<^vbE*|7s^;bTucsQ|!N0HHX zi|(Byr|hjyf(WwDKfBWP+xJaw^uhBSNhg{9{p%-*zg|VvY|=7l)4k4Ar|ce7U(Bzs zWvAOjzx}Aw?eX9@bHBVEFXIQ`)YaX#2(FRn%xfFJsm^`-2(I9)wNw{+!jII4JEUdf zNl)}|W@@1Q$EFt&SK^R%&L?%kDxfpTpK;|9-Jcrb{H9Sws8X@b?9gTvWoTbLyT0%k z6~guYD*3wcQu@F(0Pygjd!zLc;Uh#TTXmy_=2EZSZJtMNr`7*D0g28aZtTbN&`=K1 zrq?CVIE~a4cuCX}K*XG*<7Xw+93WLw5l!7JsGcyiYTuOh!f+VL`FwJ-nyxf2QwUhv@eg5erNic zT`v2!_uu_)CHA}K<#prsKds#G&6Vk*qPKc}n>XKkm^0iIe6=8N$8!>@j5QPW{SK?| zPf65L9CV2_-bbwQa)jtS)ckbWM*N}{W!_&(xABtwxg)Dl(AJ}b^Y@`80u;c)*jDMQ3fubYrHM4 zDrQ&8&>df=t#-dfgi==T$kDZMezTVrM+&rs{d~oZEgu1LErq84lu%D7`L$_*VM&wx z#xFx7D~4qGPAx?7g~zu-9FoK~)#T)7zWC&!Gb&D`CK_v7zqMVVH^bhnyaB^PHXOg! z3AYV-xg3mtQ~(dYcjsNtO$|akp=7 z+#q%hEwE?QOQyqLHZ^9f1@$J)|7Yr^*FqGbI+H>xhMHl49H-aX2&a(HYyZ?q@$;Po zDP3>#)1O~TD{8;c5k8GOWbm5lV&4w6qg-27)6FGdDSPz^K%`xn%t5On=~vZJ#THc7 zM-K85hq%n8;ihaRr#kPYp=rGQTGlxzAxXxdX*U+M^zc`J4QNDcL(=!c9Mwak5=g4q zXM61i_MqA8=#I7&#WR8?2VEKOXU|Tj+-megDo&Tz)!l6Y7LdiyGn>5d=V0KWF43^2 zSee-MT5RK5>zhs|;;uBz-?;2ZA3#q;R%0UbR_c{efes>g8COEF=?-ImH zeJbZdX4Y`DI{8hoP;{JLEM0E#QG}pr@Py!UUSvzVkJNAsG92>IL({bHeb@Mu7?qd? zrZ7LW5e%9#1c=lNugXGvD7k4DUPS%}Tu4+)1(&&>7Bd(&_1^ZFx*h>jF0oI7lJzCb_vRj&v59W+_D@ zC{%d`1%0U>B32Aazk4sfJoW~~5-8(v+mGLm{RF@UNxy^z;g9Ko=)7%_UZ9288@5m&KHs@(6LWvA1#_gvM+T&%mlNjTq= zWnT6kYZcS2Z-P6z+zGHnCjdisng^z;A{AWGJ9O>uH^v;y9~fI10ZrMG06v@rknncx z-fc5Otk?J)ww=X~cmwCw0Pp3EPncQrv)hh;X2`T!A;DFK4?e+%2aHP08TDVTX0Wob zXk(%`3K{KGS$qc%-T~JgTsm9SQ3N2gHfi&j_|Y!V)P82!a{W3bp9s(yN7C%q>pS(= zZuc>yD4Trr^vs&P6UXzJmmkE4mP4CiG^Y)@Ke5CPCSS zQqQgqPXghuw3qjE*w#abqixa5380VHDi3_|YUd57>n8Vo?aw?v+=|3NaeVo7u{@IfBE=r%} z5U9BlEPVu4jjG4DFm0iFo;m+P%_dk5mYTcU@@oHrXo++jXRI)B;)=lQsc%j-O#(J`Yz_*N zl~R)x1paGS#h#Jwh@?@?ip7fQikuM9%nIG)VI+o||BRDf@5|czAwy$7=TrX)Ps27Z z#~ohy3^J+=4y&aTA|!uO9*l{ftyV?o+p!w@%CE<%D)b_)H&1JM5P3`^D{!O4mM0mZ z4jr%PA8gpMkaN7f<@uq1%;)580CEc-?;lCXQ>5+lKA9sBe^yHU`f8!0 z!U?jrEN`8Roo)vw212&&$&>42I(d3Xp|3+U=U(ewxgAf$;iJC}-)9>hPu{p_ z>6n93w<~Gc;kxlr<>#mU0^ZCi5ruNXS};hgfxdu`yxNDc)RruT8Mfo@bxPQ| zT^V5kloQEn(JTquH+D;(?y&ijS?EJqk z=5rQHyY^+;;ov*$(z=Uv#|)K@-g2U$Dd;+XP58;@)McPOQv>BcS-+wr&idLH_=Yv? zP6`$Cd+o&T2hfX&4L4aObm%;ia2acMv3C_?TPZs+_{d{dNQB1AZRSk6&hu|?A9^To z_#g$Te%5vbsQ>;o?ZGvNHuOv?kb~OhS}!f|LiEphxQF4AN}zt)^7Mr^xW14~hQw#kdV4k2!{q zNBllT47geT?#QY~M1Gc~V7&IV(01PA4+LG;2YRf0(T4?_Tlk8x{U8mS6Ak6fzhohN z(K=`2qeFin>eljvyEFt-yD{+v;u3-zp5VA#vc%iBWc&go?l`g}KjMNvXYk&uxh7n$d16B$~= zHzTpPi5?m$;YU_O^j>{qv&7@98od`5l zFl+SGy=1#wZ4)_y^qjyv2oR5B`eIgG>$oP{!EwVEWLF#?L&>PIJdKK3lFK zT>SDZf%oq#h+$E7UHgbBRuz?%kKNtZwS20-)egkfwenCg5<(LlQc!rMTJPH!(MYrb zY$4C!tgwg|`>SwANOXiPUUmu|5_t$BLF$grTI(_w;UOU693`(*b|cEYvE<)NhSJA!124;pK@PeuYf?YpBE5ib)ehIuM{w!LB9WxV)q3R%+ zJ3rJn&)=0-^E(hCJ&>NVo?)R>c3x*fhDLSLNh;~t=+(-<#4IK6Y0K=e@bGoA_~9B) zYtVt}P)D$X?r3A@Z7HekXhb&X77uFA4;l3v6nl2tbpI#D)irVco?mo%^WoAvcLRU6 zks})1(JAtmhJmqLJYSx(ED%De%PO8mXdj&kUmxImritu^CI9O&u5)=C16Rr}3_e@n z)Adg|XL*fmb}^~+!n?!33)+ginfQ;w_4(z z7gz}m6G*AFLxCm~cNs^V+C`LH=mpdz{fP|9pz{3)I-nK<$u;J<<>fe!By6cIYoRZ( z_mnLMh6}WyMc;y~;VR-|Mmu%qg^4HBd{3Ph$AZy^eS}Ffp1_+B-%r;g;+?7RY#Ur3 z5Qfyg|FJb!*zUZ0^h(%K5K11m3lJ9Xf`Fwq(a?uH3L#$kgHk2Is!#c;;2&nl3!TU8 zn}R6<8A-G=A#LIn5y6c8$s?vpctg5Z0;9v2)GbPQh-9EH*$BO|DO3E67f%G*9v$Ax zsl6U5z*II3W}7eorvsPi4Fu^nwaB#Eu&~@O_swx*KM-d)B872z%hs@B=zoc#F`&(C z>C0vQ?K&p+_lY8E-3X*}-avB=DnOl0Yhv{&%>D(ufY0c&F<9tw!~B8uj#?{JU;Oa7 z{Ed$&k|N8#QhB1fKM-tsdFXWIY8h}8WebY1yQlnSBuCl-laIT1ujHTY-2x2GU5eeC z?lrllnVd~w{nyk|!n@=S2_n>8a z@1W>IQ(Po2i!Lc3ret8opjf+bE6;N;=iT~S=^g~u1d=~bag)7>zkd>~VG?~dth$mE zDysNzFP|-hrBmlei_$v0FA~mxfQ0z4s&o+oi38Jw3J)A4p~6HcQc4Tth6N5S{cvYeF;<)4>_bxVgF4^vNN`v%UiSDpjKudf1gOW@jktPlg z{?p)v0Vbq{B_upU{)rJW@VzhrH&U7{@Yo4v?c&7s#WMm@L?D|T)YtaGkhifr&lHtC zRr3Vi`a`L`;u)OB0f4hfuR!Gqz@@_!TQ|HsudKWW9|$e4hu^<{&mR5RH1gR;Nb}=| zfcqs6_dkC6^a$Y>2**(sujP!lhmJA zq(sXj7YEw@=vB+F3*bB+Sggz0m|nJ3JUBI8^zbYo(_zn&bMeh z6W6zKRGsgceu%Z{-oea`#OD(K@aAxzUj7CC&t>2z$(q&Qd=g!^e)ZS2WTY6){`a4& zC-JcRhiAHjSp@{Hym|A+oS$YEfKiQH4^I2p-f&8cfo5lCXJlZwk@u9AjT2FtyrE&# zeqLi{XJ=>9eO%|>y?e*TiKF@pH8wUG85zVpQUH_P_DMt3dKya5FT=ybaR`$vdn;I- zGORf;S-jD{FV^s9$ep$8*8PI4>CNUZjf`EsT2AGFomHip>0r$B9~tM_=fIhE@A~L4 zb!(!x@_bWM)7I_VtKc->U^rdscMNfogueU>S6A0VhYr1fK(DSaCQ8@9t25&{e&psF z0>P^??>9hT!3>+fWa6nK5Y4i%u}K%bJpM7a;K~4>ZXtyL4Vmus>zDiT)dskMF2Zkp zRS>_#nwf7@q_@&;Jbm+ujjU(&rK*HUvBqt+&(@g!K(t#mKVag_jX?)@ysiUU*uf=? zAJyL7tuH)3Ec#KmXb*9F0`L{T4{ zcyS$YmrG~P+`*twZqy^gw~&+bVMmmU5up<(oZ`{WqLLad=bIQNV0bHifY)fg*q{47 zhEg0kc<`%nQ^s$Yn5y;b*ZV=n{|cwb{P4Yz$w^+~8W5johv?@?KtMo2Y3V0z==7Sr zmJYW=84@t0+d9PDsP>^D6YP?WmGG0kd}yR!$M8n&FLQ$@kttb^bv&1Oh3F;#v8T>< zf#?B@!!#k>Q6;d8MBUd&$S&IPh?L*eTWOtp6x7v?Gs$T9uX;S^4w;SE-M7)O=<_}M zq`@~2lllH=W;@+*A>rw-VfqAi?-73f+Kl0E+p0ffh|FGca&m5yrc*jkIHB&!?OlvL zj`2e&cpvh*$-zdWC!Ae46dVAsaWTmRC2220o%vOM{sp6%CWj#&$Juc+e;H%r7&~B2 z<9ayj$}!WygW-8VfYB3yfVaf+Lr(cJC$!|ny&;Sm%h}aWe*#&MJ}z&JAHrTge4wh` zY?0QYHt{09j--1zvXR1EDMC`jd06~O!b`ZaOBlqCylm7*M3&mHD#FVj%Krkl{hiHNuWNT1||3klVbS3Anfs|HV z$w44cn)S%hqY{`{Q-diRv3?d)3i}k&=+$eXipD4brpG-71E|0XI?g5)b^rcsW%R(+ zHNE3F3yb8LGiQ{gU0y-UJ;rYylc%{(S7?A)C@ci7qo2M0d`8mq2dn&M$GW%kCe z(CoDqrpICw5TLAlC|*lf{4T5LwJdCIZf2aUu}g1wJ&(MYg_X4uNxYJ#rgRet@Z#KCx>)LnYkeDuW7-fuv7RL4(>_k^`zYEcVfBrKC>2GoUk?Lt(sH~< z?znoYED-C3B_)~FmESf1=zAWJKxJv^r>BI3;wLO+FJ(GReOhe9C4mu(0+!JpjjPVi zPAgLVjU>tR$?q2AJnQIrj2q9u9Fg0&kf>ZSHBDeZJ;9N!Z)%`k-($n3O-2|;!q%=| z`nntnjsIOLMIK1hJ3`f4HO>4TM#vb(l9Q2DV}gWbNB&OVX|3)7a|sH6WF8)AiOs0=Oi{RBMyASAxOhC^3*+*4F9F@8(=PW?-nQd%r($dpe`S?`gzsyE8 zG&WLFP@HRuTZgjYs>j&+9F>&!I z$df7;r_Dt^iEJQW%-j1GvndR*ud0dK4-n0@ay5Y{2Y=JtIo9ySG2MEoX}~)LgRy-@ zBr&cx0;d2cAePc1@ipESs^bNW??Xe+7WuL>nfxL?6L4+skE&6qE)_sn)=GCROhXPgrMd*;d$UUbNA|CQnU8_!a_;g5BCzZ|1M!iF9Curb>)hGvIlOMzn|aUkGC2H zKiW?iR({aE_}trD+k;-f{QLS18~iau>lG|5syw&b2L^67+4mi11to$fx3RG?16s)M z6B2$(!LT5>YsLf@txWQELC)LLri9Z%6HC|4-95Gju~Cd4mcoB{*z}|JkFCU1>;UxB zc2iO5djtzuACO0Q12Y6@yoAsak!N2=CJvSGC8cp=rHTCnkPic*yE_z8$&I=YN8nDtBC~tQG zY0i`T>|>u8>|#kz`P*3CQRO+HvvcA43jrdB1+Df&5pMU69akrZnoXV@)X#nwA{|4G z<3;wT{4=a&5MeFftXW&-f|O*xgpwvM9@ZJRxEQIE?%lh0pCEqd{rxfgH;zORFJ|>H z5sM1Ta0!t-M!|d*uj>H0XFec{ zD>LjY+AReyA#acZTs`*rC7t}=6Kyq2o*l81s9n0C9?6NPyZ_*UKSqQ3VG@1QekT3X z6LL&2vM;SRP26Y{BQ=u2`CQaUGm|G$1iDjO8Q3!0mkRAt_l?&CKN2|_(^e&1Ra0`?l z$KOW27wNpTI14^TtREgN3jP%qQ`Lix9PxFB>PNw4v)DtwH0@f7QIREG=Q1UThvZs* zNTTMbsIDH<)}~D)AB5XN%QJ2wDeh510!JpYD7HR~^n9C;kYIG;ZL>8hzeP?%s0_VF z1X5H}Q={vM5Dt-T=Z9OE7^nK>b{gtOQO4bOHqptNnI#hBCPR!-uluO)iAt=nuOIT1 z5rd<*F2JMl%Msc*u9%rWAw@0>C{wJ zUlEAyYF#}&mgC1`C5;ixVg&keEiEmqzCla&9YNdS5FR>u`goZ4qlXWRB8-!lm3;;X zMkF#NRv{q`()}l7&z-xEE86v;5oKESU5Nm zBr{S{QsAVJ7KO%Xq#JhRdtvh0^NYo_HVtsIWJme} zVn!kR{_~l3dnS&Mw3wG8sZ-}cjE^98@!g|Gn=yeiwQdL*SRm>Gq40Su?Cdfq%>KmW z4|Qz}8;ypRyD~iYFW6~HI=VPStcs8Auy+$cmqaBb$fCyhnwTe7;?I5FJIQImUZMiu z@*c<55eoHGfi;**6Px2oZiHc2-eJJ-_YJq^C`s2nr4a}v#^Sm?eq4?mBNnC}Wm_4j z%*S7Bz;&S5u_FW(Vb7XxgNM;5Pax zolq18Dyi(V5Db*ObjeCUpscX4qUGy7_SqSU3hd4J;@l7`FYl*9-jkL+A?)a*@TFj* zOy42SxnjfhghoIfxBC}p;mN4iP7F0`p{7xR>%$SdU|?p)0Wdl8Za$h*D=wTNSrXR{e+j77b2l= zZvMiKpGPJpcwk+tt#!1uqi95taFqZH6Wa-h3IVUu8up_)u6iA{74=D_v<2i80SFW- zVH*@wRSgLrfAwmJ0CEddn|M(lF?}45gmz?PgcIq#xVHh~#EC0`eS|mYc@4J`cOP^6 zDpO3f@U%qU$HbIpYisL=YJ0RD9Or zXRISPie#UAUPtgPx!Uh08Fv1Pa*xaYUvJNo<5iC0x&Xwbg3JbnXJB;4w`TdvmoIm^ z#UkwS?ZkCLe96o7;fmo^uSMMMtOuG8@ z?wIC-PbdMzs;5=xW)U?I24BY%ljf$`6eQDx%R<@TNCQ?3!-N(Wyi1+fP?-Ol8EG`_*a@VeI#2XrpaO<+qg%_uZN=qRO zG!l+#OyoU*@<(TPcQi6M7=QD~PHb4LU>tr+oF5n_%N$ZZyt)d;EIlUT=MSC_wo&~l zKTofO>;+vs&4DyIlOQp|z0hVTJ!bk77slC`zD+I>SL-G^_}dh*B9cW^dZ7 z^W!yOa&BdB5j}gKu;?mgDWTxwODSr)rKtDJ>DOw{J(qP@lN*3^8RiqJcl?1t}tgwnWuJ%anS} znl*&oz``_`ZCJgzgf`$T9NV%EA$I52!SMvc_kGqO5gA zPEKxgWJFF}T-?X?4z$g0pk!~42l|y}(YFq8v??5gH5UJPR7OC1}{nzo%xT_e4h%KNCfbi(@yCDiB3E1UUBPQ@pnt zE~9*=pr`j9y}lPgK~CkL66jrP z_&7G)9xEa8QuJeE;O{jm<|FvZLYvl;sIwscblGn;+9Bcd;za~X0q~-Ts$W<=cx5^1 z7K3QRpzZtPx! z5g-{MaEP!arz4%Guk`GV-aFP9QfjLU>L*@0W#1wd0x@mtp*V z>Uaw2HD0kGMu7i}`OUt~`qzHY zb$>`sPgGkGm#A{4TMtyAz3=nv*>FG}e44BR;)-`wRf-6VE)W$;@VE)LekthG6#yH& z7?O>D%L@ny%#IeZE8#OS-{}I-tm!S2NInqo&NUb2=SNJQ`kzaWm80DfCrm=J{=USy zGm5d#p6z&W|2{LSPB?@=?{3&eK~K-#+kbN!UD--lqi9$x;;ItyVG%Ftk5Rb#e=w?8 z&eAeTcwt<@gI=VG@dyu(66|&*Cilc)E22=-nre2=LM0^D4_+HHiLMkD7c0UVz`VpE z{_G>$fkHzj28^PJoI+Rz~yh;=rPG9M=T4so_XU*R@Rb< zrY=8vWPSRfxc5XripdI5s35ZHVStRJl$0XgIoj$NECUZCH@5Hz;r)F==MgoEL#Xhc>Oup~;@Pzo}OLB}T~ zB(?cOeA&`+bpgZKGO86KeIzelq(mlP-HARo^m}SLuX$8VF zG~rgEjuM+Yi5uziYS}VZ+in&l$=)OVn*R;TxC#h|VdjxYj*SC;a+Haw`~NJ;f9k!9_)zfa?v`#Mk|F1^Q3QzOH8LI+NAez#?NQa8P^&aC#otHx2@3iuGTo z0QDy*UzyF&aH|Qq11Zw9*ZifeK0tB`q>^DJiX@QUWrR zw9?%}$GeWArVh?`?MyHVcO4#D**aL6-(z$#v9mX~wYkb8 z$iv6Q_`t#8p}hz%ul0X?fXCL(jQ7&m*?Vx2Ll0$j>@k>QchUd$q)MciWA9wAF%P9#W;?R_k#a*JzKT2lIN^;3WEIb6;py+2Jg zOgTwtT;S;m*(a^B{S0d+0;~y<#15SmCjs~JSUo(uZAA;($^P%Ty5vshrxW}xOOHtPAAW_)|k({zrwSf=K$u8)L)Vq zMmpxWGB$C2eSP(Jw+8JiyRspO!Pf^&SJW&pq*#-<#`D&efVbcv%_cT)2_!WU@&opG6CmR zssrdWQk5?hfBbmKsKUd7NO;Mr6cLlVa_qL!O*W8|^$4zRC7UKOTSYX)^UTdscY&XpJQ3T^7Ago=A z!MrzN@LElvJj0WjntEw#dt)|A#4+7#i=;(&-A&!b#s)oEV`HQ4$A<}hUK`WQ^%1;A zHc5VrTU$DON2K7O{^G< zQbeq%bNbyXUk>f}Z`W65c_kzy3@SWyN}Z;O1Z)Vuam{gDx03kUEjm#r_3lFJt7VPF z_M@z>*UcKwTlajt(z!rP!cA_>Rz`GMHP$S|>B2K=_@CxJ#lVnrl1=f!L~ELEsZ*BI zbXSsG7>7=2*(un%2cI7wm}pLv!4IF|(f`>PD>^(da4)G2gK57Bp>#aeb#WwJGb@UD zJSoCZwJ}Cm;L*UXtnQzKhkTB=w2 zify^63C~QL>`AnLnP*kN7D!(X^P-1{689{j=ENDmt@AC~IC@JQad2R{Tt@Hj{Nv&2 zsZr+gsJGa@+K*bCrt!?4-?dlvpT-!!9gTBW#5-(ny4L5yGo@LyrQ10=Y6P4YK6U(f zkky-b*wj?D6h*Z6F|n~4ZzcDX&woEx;=QviwIK$UVmI2Db?_+drHdB_5~fQXCzGF0 z9Ge)b4GA~t$T8{|X^3vi(knVu^fDlzeXKcABUAed&eOJXtMFZ7Vn{yj{JRI^#3T;2 zWjmMSL@O5G`u=WJHLcy_Ceu1} z{+Z~ZIP?mwa_6M*9v&WCO$w|b7nzs@+?TEDE4O$nR^ORy!3MMy*&3~_uh(^U>X_7r zx4ojdil5@07c-k5_~tfSzA`jA%I56sTt4^ZFgsQ78e#i7h3tT9>u9`pHoIDKs%-E@ zJ9~SzmShFTwFMIz--JN%b=kGW(TI$UjIMn1#Gs%c;|=hWtcmt4PPmS%i%TlpM#O3A z*FMY6BHMU*))3RCxLB*+buqrSh531v5LSgHxaW3} z&=7;_I!~Vaip}+%&BcX<1$=aL^h8Haj>PsVQ?1h(Uc=T;|LoJqHO3Z~lyI0e#(+V$ zFdcpFHrhznmZ~BJYwJi;OQG+oP>2?^b8>12pAI3Lwuti#m%IDMsUr8#S>vO${K{bT z4y$u_+j5MIAPRA4X1?)SA7{f73$43{W@mY|w6wywbX21St>xOA{@F*-TIOmGhlaM? zqBS)b!ax{7Vc_^jh$Jnrq+tlUU>TP6;oN+Y^6YVWyxQ+2Swpb@{PWK-&p-@g#s$nC zpCb;-Q#x1_2UuA21v)acc&T{}^&z;l{!EY}b=y{^8J4@1xUXcJlqTUKCi=?V-AHX( z0uya5rb#6Z-b;h?OW9Wc`_lM}yzfz`1oRJc{86LWZ{R zgpVJup=FATi?2h3YfF%#AWe0uJ$m#=7eWfY@XD1d>*Fc$tzhozw*Ip{#d%;H;aoa+ zt6n?{t~K9W&7>*L06t~Wo*9Xv>;);`2e1m-%XfSrutsElul}2sHeIjCW*ou=nAjUb zPm+f8ty^OAVgBa?t(2cr(Lwg(x9Pct9?)}r2`e~G=(N&=r!IK-=O$^UR}aO^$B!Sk zmO9TGZ-~Jq;yjmiVy`{AIa{%jU9mcF7{YFbb$4MnuLWtMt;I5@oE3}Qgx`5azadss z3r@xBL4$`NP3|7doCCXhYS8j*e@>!Ip!oaVo?`pqsj18o$4TAoY45e+2o@|PFSq4R zvjX!LR+PrU%2hwy`_`IcB;g6?TDwe|uV%1ph!Sucjdfn?vdl3b{Qlaa=i@w+!PzCF zAMp}K{azbczDH=@3H5uZfuX65HpU9r4aq{NRGcka3^;h?>|2x-tDYZIa@yq9D^xGE z>g4y@bSdB2-VpKH{0K+0`04mt-2w{^Rf4SFXuSU!Ud`pH&bCaQt5_muPT4zfmUOA- zRO`##wgMij55cP@zP>zZzD&QlQThY+Spy8~*|TTnOJmLJLm^5ID>DYyS9+Bc`s-(hk$0Asp{sP|)^ap0|AV*gD>F%5{jks_FjV$y*R;{{Yw;`$x{2V? zD0ToI(G8~)agYTdf+IbSl-W{bW!cXM86IC*S;;E@hSAK-?7;s04588*@uW6H<`#rUg z-~Y4s0KfP4rm^*CQ+&=lY5#Q7hA6U&)?dM3%xy+~MEWw{hluyRAzJ7)fRS@>V?Mi) zALbuRN@%sR^{?>gf4uXnyZam%(<8if;CbPD*REY-*72I{D>wFhbxx@9a-{tCZ~kYv z>)lpntUs2Pp7XtXwsL2?^w0RXdA?OA@r9qC+k*zM8bM|nA=^HF-(w6mr#Ll#yQKu={+)DG7WE%V{h=or3Ol%vDWIO@AFeoX5p*<=)c^wM0Qy*6(xk^H(7CnDtb8_Y-Zvq~Xz8Q&q5i6xi>j zvlY=(*DTvJ%~v-z*mMd#*6gJ4A0T>DRLFoI^P?1G+!=S>9hMR!Y!7RCwU2`8EdCWZ zf%rqCK#uvmrP=3sd3jgh8qC&3R-O2PM`%4k#y?_&TXHj1ljLs4iMhT4XVVS0{`LNI zknt%F^_pBOfWyAbgBdv$xm^B%fkJWaGsVUmRuEKGDm>PhMt3VeKhHW z0M0PJrTEosvALfUgW)3rv_0bP?p_61J5?tyc^)kH++;_N(7k*2@CA;}&O)&3u~x2? zUR$rkTo=w3+4RcgiZL>Nnp;@NjiF$R8y$i}t*xxbg>zkDrU9RH8!DkVN^4A5wwHw? z42e0+5+^eZ5vSHwZD39En;-S-U%#~L7qSgXX%!U}!xt0g<{nmccXyBVS9;^UvW+Tj zTwGmQ^tNr8Zoj&Go{sKyP|)%E+_A9-A7izTu^_g@6_&AF71!D05kYoJ(9`Tam;o1 z_S~ti0!!cL&!4M61~Q(NiWPBu_3`6JX2;iOuY7svQm^jp6OI2ggx0*f|y5)sHmxn5vq@4#WxR1$Ba+yhvXA!7zY!1#~It6ineIm4A{ z23HCk##O_340Hke%GsTNSyZ#Lc#Ro-1?x*ax3Ut!>^S!G20cA}ZFsz>v!d#k;}{{E zo}ZA#L-Y^z=bGTcI5gzIsIi*eV5Cu2I`GW-07>eptyI5Is~w;`rM$IHVpy$k7$-_^ ztjsFqP7i$ZN5Nmvx=R)hpq!cI2yX5zXBT}(D7#wzqruyN##I(a8q}(MkCKQu-s{c# zf8V%q15qdxBhs|+QT*ob_)O}U%}Z^1MTA8}(jmEqn>aZ+K`c|oJ6*VNp{vX_4?s*N zSYQ3<@8#)klqVJA#bd3mrLuiCJBjg0kpW9Nb@puP8AF#FkPV4X51nj^QW=YHHZwH;1VdVg2ygR=2RxH&2IsokHyCbvBVvN z=+9IeMA+Wm_IvsAL(Ga5JPzOmjgD-Ckn{27<>i}OTOqN5n|cvE2B*%Qiyn%xg(n3h zV}lpfg7uyMNztW7!&kesF(ws%FRGI%j3r7mnY^b>+RC}O9%bwejM{R0?U(2bGAMT=sX931oBZNt|Fa>huYcaY z3nR(#WxxURK`v`wkva25&GnGh?&0wGD$9YIj#-;87Akm&LoE zKa~-3U779g`1oj$-+n|MtVF~2F0=Wf?REF%&?irx0I0qoAyHYK-QC=*0y5XQRT+``> z+?obpAxgr#VtDbg_qNCNjj6oa#-=@(Lu3VMYeQzzn=iTnxCk%=Yrl|rmd1|1LCIiM zh`Pkgd<&sRP%&75v!TTzx;R{yehcUrBFbLdYi0;zf`z)h>q2ZDU}9ZWm6Sn=!-xGs z>~u14EFfik1smL`m$W!}EV*zq-YAG3;DEiKfEnxt5^6SUHd~Y=*hNIvgR|e%MGNHs zOUwYb7%N}tYXOsi@X7L;K|&l`3irQ>)_`sdNa03K`Eu0v*XL3oW+bgvt%SVK%R`}4 zz?{e&EAFX_k_bs=VRdzte|+)A35n+bfQw#9Z`qoYl3tN*hk=ca4WO$5MAnN^EOG zUcy7t13r`l>t*dMv>$B*29m9rshx22oZwhqlXweAQ3a661Z?{@6Fdn7m-zvJ@Q?f^ zPXtcFuhk$2sal1sdYaY*U5FC4Pev{XidJ2HJr3yMo;`bNE9zxcHQ99 zaNpf@Kzrst-dsu7{%|k-Mo*#_8!l93)L)e-YPOvQhUvCN>Ok>NT1Lha0`WSKxVVoD znD>sL?%!dN_CFnV_biA0$M)Ir`gMzJVlxfEbTleFTwk9TR)r|0 z4$72(br=6@I??6eNsl)`BC)EsZapPDW%$X$5}kQvp6c1Hm$MoJVeUH)Kxd2*(0m8? zVktg61R(_5#bRhMHa7NV;>_@^9g_VQaw60lI3Nl6HQa=KOD{&$*#>lpOXA|&38Tke zZhLOuJL?M+e6e*u%Z_IL0~IVjFtCY(m8|2+&_pn8yOh^?O~zuWmkcWh#utV z`D@Am6O;iQECFwmc!XJCd|5p_KEC#IkW6e#oozkmznuv;QBhH;ZPYn=l!osXgu0eg zmBgXpVZ=XHK1^n)r36r(=1K+kVlCAk@2{S})L*-uff8av19xX}A#<#lt19IETAoI% zf~2Gmz};jB!V}wD8+Hy3@_grMF^udZP)p(j(YSnSdYbf^f`Pe|ujcX*NSb=Yeyx*R zd9UxD1wf&izTsqNM}(lNQSRngVAHGXzC7hRweEMCJ3XgjT@EZw?KQ1{s&z-Py%`Dv z{oXsCxsDLXw2Y01?ytn+LFTKiu9g8dq=u5-8h}8@fv<-OtU4EhSK2@kK~mdbbzldG zCiIh(8&q^6HGO@C07qK^i9$N#L^@{s^JmX=9>2T=I3yxA)&O6^YfwS}HACF4a_989 za~a@CptNBjEry5ANtFR!fQ%nUm@ew~iXL)=?T2v9(hzrDwD$eJb3!()^MlnP`PP7b z01kv~dN!EmCCf+R39*5Jfr$A5gkW3yz|;)FNFXfxW>vj*wpI`s2W)*4Fqr4m zI;69T?R86}TtY^XFX)9}u#p3Y-v+V?(vz{imWQdR+EH2oPkv7IJp2++Rg1o|V&EDn zkn$(jM&sdMiire8%zH92*Hi`D2e;D%+VT@DthLZu5By{dd|3Cxy=O>U_*3;f1NI)R z6*y{khE`5pON$y{NSxrAno7_LkV@hq z0oZpWK~qBlf^)Y39YD9z%QL;o=Q@>)j11%eLy&7!093aXSZW=hps)nR-fbk(Yzfeb zSbN3Zy?d7$g!;j>#M`ics}20Cz%lUkCFLw3K+2ES}yWU#aIz@I2*{8=vhH!i?y1v!qN)a#OM}U zr2#NXwe7EuQa>YNifY4RW3w0ChaxutC_Q?o?Zv znhcn{*3R~p20`|3cr4D#mzCiV5Sn4eLL9+^secb-$N>Z)EGjx#JQ^2*LQ(md6J&Ee zDCK*k8BjoLwt*<3B%qCT72Btr<~7Vj+9_<=hkUqaIoC*j9p(>xQT84nXg6e@l z3+}WRlHYYp9MWzFoKJ&FNa};;cL=?Z0a|ZK8?h0>JW%9jpo-Z*;p!V372#$rsCEN* z6DnicUEy$CfNNSP7(CuWdKxk;fK{AO7)63JK4|O)f`q|LGDwuK<@xl;-X5v`1$V0sqPv*p>7Yyx2`d9U zN#Hsa)N9_}*mvOI!HL8`aU#gKi7#IKwYIia+utuyD?9=9NMop^g0pY}^@Fl$JGiB4 ztk6t6{7i`ogf_5Am~{`LBtkRsd=$as{HZ5((zgQXE9 z7o_W&2u8Q$--ZCsI#~ImW5l;4CgM7>o~v4j8{pUm2=x=#-wqxJ;mmA|nob z%gAAK^^qqy8@SLz{GlJgxuE%v!PU}1*aI&`xO%#$SS{XT;UyIQvJB!He(zqhv)sLi zia|UR)uTW`(*&=}GB|+|BLVxt=+p&WkUDk#d?qkB?eDAKo*>0~eZZd=m7k=grPBaV zM~S)S9y~^GHBGdlM8Os#Rs*OOK)e{*tvu6)Tqj{n5c_2ca@UO5S1?{ur&+u?1anGC zN+LKH)jX-F{$PuEvf zSF^=(?1vA`*&g}l0Q%&yW=NliKYS=!oSzRaDst{RgFf&(;V(%a^*0Ts5M&g<8X!Hj z^H9LQe*irJWFTa%PEI|W)<==yX`k=?D_Akt1k{masq=u)bv*1egEiElw!*E@(!uRhl zQ(sb+1Y#W)5fK6QM#CC1o)Gdjg#cLt)r%pzM-Qxf_wP9Y|WON)-?HVtnLZ{|Sks0w(ekOfYW34JrhXIN9_X$xk+gp6v1*E!-Ak>;na6 z4y8CTa<2uZhVSD(w51sOix)56gu3B}GI1yrfR2!QUf7NtSU@$;HY`sUwjYtjSFBHP zQuF9*gV$-OtA~26{-Ln$E7O50)BAREhn3F1x}(ItR(NheX;!L!5~LF>9@M-nh;{6j zE+PJtn;8h&1w`&N1f3ch6sS4Wf5OJ%r=b4>HtyaD2S)0cYJ0URJg8WgGktSAykfLx${iJqPw)a+8!=Z1qaBeu(`w?qTnHyDZ% z;GoHH5J~gR|L$mu)7;M}s|J!H@acDmFifli0D7>wI-fQ(_*$s%C%}z&z(Fhk*_D86 zbQRg!A{3tkfQ5sV^)`^zRv^z%8sP%cR7V^Epo|tlD`=Gpwq`N*GrZPQl!hokDWD2MuluQC) zEt+@kyhSC-EQ3p6_5o8N{|IxK&%aAlA(grwgANmB~oNSSXJQg8bAY3 zN&Y0O{7+CmQ6(7^_!>KkYE%iftysH_I&RjNr!#=DS|XALoi+z6nc!sWyTvru?F)@_ zLqs+&QD>V?`=Mnr;(k*dC!~39ETdM0bp7I7X7gX~@1nnee8hqUEjWxrD?1ZBNDdDq zPQBR91Smm6ZXo!YDj2jXR4LSDvF$>(Qkv2AREJ<9gQJwa~o0i&8W}}LaS%m z(2&h^I{F184$K~YZu^ftH20DjU#6+OTG?t}JQQBlrGb7S87@P<_vRVV%HV9eAboq; z>sqpgYgq<=qwh=NpA;NMf8i@|t4ew?sXA<^I&-2u8?`)R=63#)gdaZDCT9=r2t+cw z%cPN*C)>&Emi4{xp8UH4>$0WEhqdQzr{&#c;>q3;8!Le!EW^I52hEd<}#3Ro`Ms`&`HV@Ff>nbLs+Nx9W6KLN$T41Q zKe=Ohj!|(&bux$WxPZX3$V_2osYOowF8it4dC+xSCc-S(!>m5P*Fygl^ztD&!Oq!U z2`1)l6J!0od6_oRZ+zsRVbC{MQ&zRjvAp9oC(Q5q7z^r^UPQnBbdr&LCMO~rh;{!E zBNgz8(XDQH<7)P+=-0-#J)+STGS^-vkY-tW*6xlnI>s?krv@t;(C{5$GFU!}J|-(k zJ~vrn0573e?POe0EC;nMo~QS$Z^AJz;p`8ViZxcO`^mv^qBZ`i4dmVb+jEmnXkypzeJR*Q&Zt+zvZ^v<}hjcCl0r6 zwZ)DlrfQn}C4tt!NVj_^opw0Sc5FcQc>A}K#2f4VeoT16jidhQwy|Hv+s~j+`Up$H z{|9LtpuDeCQ>-(yL zMrosz?9oak4%BWEn&qZb&BH+(9HA`=c^mCPDgO6MmdNp0mWFIO>64UskvsnL^FlwC=>_OtXvq3i-@ z1W)hRZy;cO-ZNc%{Ngb)iiR0AsRQ;UNjM|;Ffb^T$KWrLC08Q}zDxwUUc%HfV$$KN z%S(NJOkEBawH2wH))Sls!fK<%7yZ$9F!TZBeY{f|u*3E3*7lZ2?3ZKMsQ25U;Zvm- zMMIVpI_eg9@mF_k1tWHT_jy|WStH^Ni7|qzR_Y~Aq^bb>s1i~p^LWcLb!&d6QOPpd z6J4&6x9wM4NTpncFS8i0wwj#-wkSJ%$5r}%M@$fN`IZOPG24*w-&Yse{d~B;Xj1&T z?Cmo3w9?k0Du+pn#o9aNq?Wr_)k=|PB#W(g|1z}S^W>p~Pfq$09Nd2e4ZI`Zxe4t? zZ1O&FRLe$3nm?_1bM#rI8Vq}^8~GFYlGJwhsd_gGc0U|_%%4+!iZ1H%ltwiTzFexr z!EwUvGd*fK zG^Nz1sZ%%(l#{GiIPCIA^U3TYPH@~FdmgqqsChv>bUiyFCJ&q4H%|OE{o(;>{ZZiK zs&^VaY|*A=+6Fd?F{q>1E2;qJ&0@UJl+#P2$2@9^J z7K)X$3r_ZO5f$)JNC|Z0bKy%_y=JZ>F!# zT1GT`!HvEm*+mXak|TgEqR807KGPUE-M8qYNA)~py<>{Gh1lF1JU*28jWmYaY?0lL zcyRYd@eK@E@5W$xC)MW+Nnc3Bq;pl5`AyrdWC@>OmT?bBUdc@NJ5bh=g!~O|h14>P z<_JHU$y0VHtsmle^~;7d)MLUpP$A}$}o$0 z&v>Ry_>Z@@^%$HXwI#RU3CD~sWoS|_Bvl!_xNltJ<;^Z6=B>YBRwOR+VK$2-ZbD1JVWqd_ag8#9a%LMwS z)2%-KUwRqv#z*T>bpK`@Tbt_UH!}H7r-@8c6%9u=0nOGa7e|GD8 zs)snQ!mN%$Bh~VFJ43E72-Xu&a-zNNmS2EF29V1P zVO-7vT-S%|A95U;b9m_=e%dhtz)6pt92uMtlQK50%ufip$8S>x1m&dUnXY6d#B|1h zaT(J=I|h18ap;x`yQDG@Tm-1^Kl#D^Fm&nZe;rKKd0y^W-q?Ot;SyYLgj}&7EcwH{ z=~3Oelx3qbCZ#hJ4datJdxd+5aAod4fBpcoiwEt8i-LjzdNszXj!B@VRCMZqds9C4 z{uh2B{Dc#QJgdVi%W!nR#~+cD#)oKY8&xRZ@D680@$|lF@aCU*V0<4{d7bA83uvK~?oB(|19U<@K=zzNFic1|Ny%y4DKEOMy(J+AV$ zU%}DLKDh%uY6#(L3tg!v}g>|5xsDB6v z`5>BDe0}kEi5n>$+83EbMMXgq3DU$9vfQW%77e z+tT#tQq}Az3-+Xlx^g11V!VsNs){UW{OM2V0WQIeg#rYK{&}ZPog#qhtdk)I7sIe$ zrt!V2UHaE=^HZl!vw}7cGCb6V$eIu29G(!tz%Vzi5W7>rQo^UoGm9eV!kM>nq|He= z5fxiH=SHtap7RFy5!Cree4pk06Ao}q?WV|n!Z0uH!YDyvG}%(?Tp-0{@9?2N)%7I* zUmmN-OffpU0Wov1&ddCfQtf%pFl*lHLVUd?U7j{n|<#Es@j)<$6x7Z28>2%SS)}kVEY(&;}1hqRf^QB{uVuCr-SZ=`982OASjsC`jMFoessD zC_WQ8zezUvH*cZNuM2#y1(q{BGm{O40d@|KI$|=E%~9Vpu+dZqNtPhrqULH7G)M%B zLi){Tlt|xPpUP|EH~n!I3A5pXs74P=6Pm0f=&n7Kgeso~2qccs5w;}i0`%cQdj-=o zgJ8SU5hXj!!tMl|kWf`(+hTQZ2@QRgsuw-r6360e$xQ|@q66la5?FirNL82gCqX3q zXn(i~7Yqx1xFXY6=1PJN28-3XKX?Mj6)>~_4Q@K9w-|(eb)c@(y`@@EQVwB8tts5P z`9HzPkwUEyE26Qp(ZA!cweBb^%%ab|K2tht0c8de*98J|8W^qLt5>a1l;tLgL6=Or zdKw-yxMf)ql%@ZZ5Xxs1fxX=73)igV5je-@dIki%nLdA&6$YotUj>(kn`Y97bK3EN zDY%j)693?TCyPCM9v`uX;TQu@JAm*Pa>3{V>SErzZyyU90RZ`<@F@en71Wi^&Q9}{ znci?gD4ph^e}e`+)FT1)wGSYSNW8Q@v4O>caQo%U7d-fyB<7O4g@79GiVC^^7%xZUGOfG;d<2TRa|q@!y))gXXpZh zVI6!v)|_Eyim5>G<)j)PsJO1Kt~&IfxHJWV2y85DnwLL7ZQlRGVVaevFZ1QO9o0|H z|CF4jP5M&YBQVS2P2D&gm%T-1TXBl}89(iu1Jx8%U+zHAeDz8ppz%pm1+@nTQSsuv zJaLr5@jSiy#r8^j`lpE7g+MQVmh@ z2&bK$O+D)rIRN6WXEKf%wY(UXIYm#+2AKM_wU(ka$1rZu3)vwi^02cHW7R3p;Jm!N z)}aQ(RSz4Ex;&9^gI5Rj0f}hP-C30137wbFf(4ZpZfodF$cA=cTr?bWI`p>H#a%B= zYLM8#T7~=q)>DJoFqMn0W)<`HDpOBTi<;Rsl#f9P;vny}w{xl2GA(L@K*LZV@Ze9dic3ID=P@W@4yh$TQnHx(^#Q3UaCYyYe!>nVUeG7AnA4zl z%58gXw5`(Hd%81E#(Q)AIi$2qA0G?~RrppYW(f-mrx{gxA&*BTV{8a35@*6i486A; zkqa4l%s*3%6H9}N!2=lWKsA`#l`LQe3f11>?VCH54WvGNoF|Kdv-grks;s&Mh3LV4D-zK69| z;ZsD@uWi=ey{*wWs&UO*`7v};{J9!5q&eP8A+_**GO_waPlm^v&UbGdIvFRlqi(k> zs~vvukBozUnYf;_oW!P=Azq!>A!X#8m5KMF-*N3HKSMWJdh*#B*`_l$bRYlzh<&D_ z_0jF9spX!Azsd{8d;$!QhA@-Tb!2A?E^(i!&Zki&!{s~OWVk#xbZ-WGc<+fXfmU9s ziOoB%5x#dHjBj(&=1shr`Sz8wG&+&hAv2ZL#G~cy9dtuU%^MiR?AcB-aB_R9l$7D@ z=J9Sk5xHm9l}eA4Gi2;!U3=H|{0TEwz<;PU!hoZ;sh;I1C0TDWW+Brp7Y~Rv7B3v! z%7=bmbkw`J7QUra+T(rYRt~pVYKHS{eP1Ktu7ccH*t)cdZS}2DbX%WYg6C6RL^?VC z^Jc9vuVWN9wa4;HXKGtPev^6{#5)EWd?|+>wsq_Y(}#ya_|yI{r96U7@O=q8-GeW&_VBG&ZMV*s<+;_yf(1c zUvxIYGi&^qO~UR8Bgylu@N=9(U%`-1T+HvVw=B*b$A{f&$GLKdH`{=G&=Pcj!eRaP zQ|9sEb?GJ35WJn;dtB8$G7chhJW$FcE^<$Ce3Qnq=*fzkFu0$AgH!x1?YTL5=-b!G zuv2FV{iK2`aU)tPi5Zn@*JKp zDz`S47eF0)HQL@y{RsM|4>Nh81XeL^AQ^stg?rRv4bI2~WCs@bOEmTn&-ovlxb2c3 zbAD>ca8Y%_V3H zMbw9QIg-;^5GDEfm@gk0UzJO9I9J=Kn49N4G{+>yp_%9!&``jNEsbaS2dii zj=oAhai4rN=Zo>#U+H;iOI#(rN6O;raIlc5%UZUfo{MC}&6(Op=JLMOrw1jpb~ z9jMUq-tYRk>_2KJK$YS6y(1e9JR;dzBID(`ZPl1gWpP_A1Xfnt;3-|CRL6m)#BF4lcQ;C^6Z?<;jDAsIw?IL`ctyKw*|bIjZr*<*6k=O*#O ziX46XcZv3*r4)h^j@R|e&8C`3?=KCL?3!b|wmC*ZxS#luZ}u;>$5_LpTaMlfZ*-t` z`?J0CRQd6DUU|zLTpWrl9(m?Y{j_z1!%Y)QlmiGY3o;MR9SBfu~-?c4YM6h5eRSOz+k%nrsHXtWZe3tUgEeOEU1$^ zn`;DTCK6fp_4z@z*H7({gGs|%NsHYqDORd0@dW*EYPL3l{7wyr8de9(n8zWi zks23SU?P?;{T}&V+gHi(o1{Sr+_Iu-gsW-=N19;Z%d3-F@l@lZPdb>fOnTw% zI7feD^#bzO2sFE2D|C#>_fBRGY26l0dr+kwefxIxc-xw{#fFj4@EtSaXe>v%^{@wx z7AN^z<}Z*}ebW5a6B3Xk=hC-epJr969t|PjKa7HITA)CNTHw-n$c<;a4zf(%a;vbA z=+;rK@zxyGVfr+|QoGSOw}xMd_Cicyy$vc?4KuUr4&<5LN!VT8_1)E-bj8^{rAK>`BHb!h!_}4E>%dTu=jah*X_&qA?I|v$U2bGmJ=#W$K9gQzN>f`sCY`!2 zJBhbLm7cfb2-j(}Dxam@3Qi&8k{^Fjtiw(~Xij>oNgO2jdo3*Pyp~`6nEZs!S?G7k zgp_IqXQFxuay833l~dB! z1hQl_z8qupcefnB;8{v~b#Jf%z1{%?e>Jiu9uz4pBfBVyE!xJ5Eh6Q3MmR*^YV=Xh z{E?5Q+mCMGmn@#Vb1T)sLJ&Q|bM{k#Ats&5{x&yN0;qUM^>3+nHG#Gljy>=RakbE#gRYj^mYH-6N@S*rWq&p{~A7r8@gr zT0^J=zgI6-`dhO2b0mZZ>5z*dlBSwTDW~XIhjT8hg~}C*@QEnq{OHc1OR=r}+(_UR z(Nd3=Tgz0wP)Wbe&*;MSDB zF#oWWFwo7k&w@t*(kNSciV*;gzj(aX|n7kLq=plI_LG+v*^R;%KG$FpEcG-p`g~-vKLu0zJgwN z*@Bz8A(s389*7!O(Ej!lGU6oa&xmR9bBA zDqdpGtC_ywqH{Yfw5U`KPbf?Q2)pJKF9pK=Rtk>yObKVNk5Ig}ce z*mkcQ2_=$tBfpnHlpRnzX6)?L(}W1huGcsgYa(MTNN8+Zu+$CYuzQs6{Yi1p?|EV2 zU*@uj1GXT;ePaRWQN1`PhfGZW$qio3hw-5Zkm?wbiMG?6(UP_M~ zjU8gv8~QRdo@XOZ0wma4r1<9u&j}1+v$L1KRLRk^Iqh9p?|DbDOY+vqn+ZxCaq8+; zW#sEgo+fMIbNnv@!@?^r#dcoWYE|+pk2fa$cQ-;Qxl6syELL}qBp&?pdHPzx{OffK zoeP10jgzfKGe$z39;_61@1DQT+1<_jVioR1&lPLPEBsL|)(jVr9o`lp^&c*Eenye( zQk=oveh2n_>bG;hW+_+1v7T+FvF0W+xtS&FxMmZvT{Q6GOX9sO@+sy1%dq~rD|@a# z0t5m1@YKR%TGJ6c&}P{;AuIv{#ZNDxB2fD}-EiFP^Yg z%9}PG(M{@pd52RA$b(O&FN*iS&F8AMRDTN{YU-8`mgCRM>;h3FHiZJ=Pq}rs2b~!O z>io`vldXp^fuA7K4R&e$e7wDls(3d*5eLB;L9-&JcmG=FU*sfZxncPv-(3F7Vlo3R ztVCDS`kIr$b?=@mMB2SsOT)|b)w~RO+S5*A=+&~`73a^8+-Q|^UQEdo)1^9ET?PcR z#2&)Xmv$-AM}O^B$SgUDk{sQJ>5IPVmhVmGmn&^1!dy3~>C7|-i4{@ZO~{?vGfraS zd@@4H`z%#-IVsvS*(Hwk7N5z0az*-VW_gLzN(K4&eU6gl?)QQeY-v@2K-0pd;e5sm zq$$9O3d0sGcAco`UNB~^U%h5F%gDF2c`lh{$k;Z8JH;lw_N#T&IhPxzSDl~00vV^t z#;Gm!^RD^egIX&^7i%-NNO?RV^_NRIpKT>5UmD-`_R;o#cnoD$>wQ6M!d>0wbN1gz zlar3>fUTszf1TWl4@|3f{zt_9>KAf^`t*HH0RTT^;E|bIQ-mq^=R@qH>3K(UPDdpij=OsE;06x9kXicSom*iD-@(}$$Leb*zOw(-6Fj5QCT zus|!~kP0KH%rLwRLM0C5)`Co-BT~?1tO`>sLlYC}pl40O>twLYfB!$I#rOak5A;To zEIloF1q>QPgts6BU8ttONc!EI#rc! zGy&l7p%*Z1aO}Fg#;(iTil!i!@A$XNN1odA7heyKx10bXmc>j@v54K!3nT!e)qzfm zC%`1+7<6{GLt8kK#L!zYpqUO{l9M}?`2Su+rtvBRGJTl>fgr+^5K2IkPaT#^-IIiNn?re$OfMHq{gJIK1Zq zO{Agb&b5t=3~10rO~KGJOn`AZEPe!D5Ao*B*@ib)q);0ujA9wOPYWo-Tx<4|Ifkjp z1!c#>thN(3Q6gKXcA<6xVs-1x;)S}Askh_TGdQC2o`g{z2#SLD{baz@EE<1=4#43a zet}AO6@*1cb{4!;p$=Xh1pR+RXxopx@~z7UB$k3l+MbSCD$00%?-dq-$d3lm0Tg=0 zpw429p-^3;42_O{fq@bJ{y6+_c6K%z@^$<#%5&!bRGu|qexA!3>J(g17@F=Y?!{gFojprf0Ee)a?QM_|{>bv4RokS7L zvA_RIjkC3{x7Pq9%yuZ2pz$y?+6Uu?Ljgn8zsCnsp{!zgcgIZQQc868bLsIU;s1`6 zf({+`VU&W&BQ(IUK9(5hFx@5a4VuZJB7ojHqpTbR?^xi$E|5qHxv@DpIVQc(yaw;v z2{A5*(ORf~1rrqHU=}+94?~S0=+`e?Qhxi%TjCBzvfb%Ug~Q51e~v+UNTxWD(AiA~ z?OkwP5o2`lG{x^n{I-4iFeU<13)A#zo=`PFBSk*A_zH2GKfAccI27Ky@c`blk`8Ka zy7fmUVaII6W!h%IbyVs9#&uF>7}QZ40cpn5G6KXzpA_We`pxg8;bl02@Rpo07_LEs z5zyp`rjgdxSoGIu&&N1e^`jn05s=n*!RjSCZ#**6IUp?^{%OIHACxV+^{ zs_E9nOlyBQhF02nr6!<7=!9KvQA@j;P@BVmV8fv@#=OYV8(`rr+QI zYMPV0Y!sp(ZGAl0%6U=7J$q#z=2I8ySbuc;#gQ}6%75d@!8Dj2guomD7f1xBt#7{a zhvFSf$>^cUHlIEF)L||aZ1VxUX#q7DqmYYwk73XWjiIA&!DN49ZXdL5Lht=gn3vHg zu+S)98;OQ-rdFosP<;?96g`vVI(_m>;NET36rI{Hflx19T7UP1??{^E>&H(SBv0QL zjHafev!3R&@{5hdmRnv=Bmr#S+J)_AlS<>yY`1>~b0+KpV$JV#jFKF(se3SiEFgAv zT(~=yAzmq$jeV|P#&9x+O3it~MfnZK>A7}%M0{A@lkzY>Y0b}T@?9@qy!Z)?6)@Sy zsnrh2r47ac(Cgd|96sF&j_*L4&_MHFcz&1-q~_8_jo)}?>;4J@+p>9Ilv~I%(Cb69 zD=tv}uY00J`pjGHxMG+&H7)O!W^=c^`Qual^J_cM=F|QO`nDTBcOgmP*ZyNhX-%~3 z%U-#2@ZO*;+u^_Ij!~*9ISaWc@b zBZZD*tn;F9mcd0>1m9VZ%F-AU4r0XAtwJ5{K36ZR-51?(wCwGQw>Yb42tO1L+c=^) zpHSY?tX}&+jJFAOg}L z-Q6u9edde%ckX@e{o|bdk9+S&KHl$LYt1$17-NnpGyij9qh`o~UmdCHt<>xD^u~^F zERW5n&Mr;=4Pm?h^4cjEwEmyO^{1W7G4U4PN%2#o=U00}-e0w)e|LQe z>Tt7j2}146@OFNYdlUk>IcG?m=*t4eL&SgP@t^by2orK3cBWDj_>9nBr1>hhGO*7d+KCXM%Ua&heY>(IK`>VN~sth|Y~v6;IQZg95j(lw$FB+0PM8 zQO}L@nlSmhEA>c2A!gd?Y z?(=))3o`jjsU!Oww%v~jy??jYeBxE352}4-eweA4q z38M;v93LUC;k?D^(U*!lsfEud`L1TPKBsjrR*vf!vwPZ#^*j;~5Wq*Do&&46s1Q|? zJFQe#`NBIU{C_u&gq}C5q5c8QLLpu+*szPEx9yB3&Otq@gy8oMk?ieeEN?<0YO&% z)%nCNk;&hm)3oy-#K#g|mxs(b^sg_gb{2uZAJUeu7{k@GlO&jT(0Mi2WS;B}rQ{3S zoOFuvLIdO@0$;MlDA$P8YmsAkLKJ_=hphIaew&pdj+$g#oO^gVG{tAy1%>j(2Y#Pe zstQ;0D2){wzL;qCGbhtsLFtG5(8((~wQKkl3BUWFh|D9KYBd%?v^Pp3(!y}_9$8z- z6+14Ts3Qga7v1(uIC!%9vYS&+7f z5)Tv#VBs#y$;$?l$Tr=I)t0LAH4s z0UEH;wfN_h)5sk%8bYyp8)xyQ19^}+la{qag+Kh$XX!2(_OpaB4RG(C3MrIFBvr?y zf}K@!(Wb^{=jZ)c4cRfZC7{Reyp+mmDK#&C#JV!QCQ((r=z;NMdHsb#LMEQX0>uTC zyeFF@|J=+}wlnM2u=D8$Xl;d`bUzQnX3+pwiAnj~kv=k#e0&u+CFHcRZOFeDZOlMU zn~4_nSnFjJKM7u0!DT|37S> z6ac>bfz|9%gz349Lz8LKb}xe?MNai7a(HAw~6tBz5nl zxTc?RoUiJV5Fr@wHXPMYuEdZQV8R-muU#7>P}JX^BYhBwkoP0cP8BCj;uf+>LORF* z@+12wlK$}<_Onx~pNs`Ee~lf~jX+d-5yPJd(kBhj$PU}z`*FT;C$A$<@6pD5{2kf< z3-$LcZ{yv~RhvJ_m~+>TOpuHnObzp&?TB*YgsqRs$A_#O0h;N5E2oL99Jx(}yISnP zW8Ml4&8V(on%h-``^Z1gZ{Re*K3fZ6%1Lp~Bf3k$ zT-2d?7~Q_Z%RtHm)4%x>`fr8($j`mNGzuH*hy70Cb}U3i;59 zsF>?u0ZCr?Km#7G(+kJS=SW*Rd=YGfO7=(_*-h?w#{@VyG)#TzOdaOnWzq&6!zVcD z25gdKl?tj2u@U6QP}bx_ZjuQs%WeC&@bmgy$dXPj*&(eBp134*c-geDDnn`fKH?$> zsW6Enr{QXqWk0}PZ=y?MTHJJIs@zE)_jWh_V|J{?~=PXpBAhgUJkfemz zgxNpNXku&OboQ5J_8C=5Gk(kKLZ!?znoyK?RtQ&)J=z@%@PNnLcBJ*G2(M3`DLR`b zF^xv9T=DaWns)b$Nza93sQj;;?|FlFb(Q`7+6v0MUU0s#QRO64P z1pU>&1=jfYoq}5^IUU4_io}0ua5PdMF?pr$6g>ihIm^qEi_y6_3TbqJ>>gF%k46=9 z74{{0;dyo>f3+cG&xINKW2)L1#rT;bYInB7|VSjfmmfHM`Val-))zTr@XxLkt(6^cDgKNq4yIM*RWcw;P za@!h1_}#o5&w|iM??tk-5~+U?G~x$FC7S=uqg* zERelXk`zt})rJ(J8{^|s5>rJ-c>s)~3epeIBO5oxJo|V1V4VxXvS+qQjU_>rO%u8D z07SGgVctahdeghVMo%>N7VwaJOrr@M>Y%6eco?YWWhiV-v;~7Hm)fa(Y@zodk{*eG zp67|cN}hcf`p} zF{NcF4ttpeLh==#)`4CPY3+=R<<8mWNf7NwXd&%i(8jC-P--@(Cofu5GC=VZJ>gWojn<(eQ z-tgIl~aw=e4W5)vaN+(D!=P1;j@DaWC$ zoFWx+pEx{tUz6R+43pn1os~l&iGWnT&ucd=`#enjlUt=Q+f)`!8!U~gwsdPPpN2n4KTZWHg)+o%eDcASt`G6rnN@uajYS~qM0_>@#s{`?(}Ij%G7d~zvcTpQ(6gtAfiu|mVDN~cYJ~{Ai}uWy2GP%3GHB*0YGh$E5|vyPj)qK|?6rw3??u;S0U_ zUjg-71h3BT_8W=F%mPrCW&x}WWXz-3y@y~_im1&CjXG64iA-~d7=ECm#>^xzDEbTFHlWrJ&TGU#HF5fWi3fNFvb zo-z=sQQ%g z-t78;*}Wjg&j?baN{8>kIGnHN^Hn}62Oe}eEy+z0+;$NQbHs80z`Xo7j(PVyiSU&a zUPa7rRHqC8cHCjsk@=L{r??ePU~^B|CCUJp-BA7W14$M%uw~X+68l_ zbm%ic{MEow@hd=OQelYYJWwP{(9InJqIm@N0|ydQz^)M=21;YFFGV~+VRixdn`?j> z)nf60b}t}oy{k}jVCj5_&LNX@7@ua(cz(4t)1mNlD1ESIeema?fRzR=FEUh5Ke+!O zI(umEUk2A6Xi;V+h4q6pBEk*|mf&iukT{#{B!2?OeZlScaG*czZ(75;i(9`6-{PNN#TUvI(wmv5hNm81^; z^K`_TXt>Nvh8m1W z(9x?b*9zc-6fj&2VK4!0w`PI9AIxG2oo$^I0y7f{#5)fB_K;}=se|*ctB%$y5U+Ny zS49ABI6S6ci-DYH$|aZp0nWBBCMZXswL`NXX_bKfB*}h0Zte$Qlpr~rQWWgIw`B>4 zJpx|Oh4weNUw9PtdPSyw^t|mZ(nLoCj}$LUkbQr7;QqiI5ZjjDRiAbm-O$KTK$Wb6 ze-AisX&21Fc|@#-f8Oz8sB7%j7TU}C`lWmf50@zQj?tykUz(K4h9?jd>)o@fL7MbMX zl11zHwQs(%I{`scVilu3^jNMcX))5z<|}@NMjaqn;M`CTZG*|87Wi@J3yU_>fjW_+ z!V(jaP$*lK9d-_-0Uq)1>E?hH^8*JVgntAFp>BA~y)I{#Rl8AhOd-JKWC5e$1imH6 zyaUPWFBGZ3WS_g`4U8O!vV)d}?_fF|whLq-xYkMbP^Y>c7Y4iAym=FqmSz-o6=L=% z(hemF{buXhQGqq?i{-@D@(Ewpes^c-{90O15xr!R`6mB4P|A-~yP(OS>hy4B7)+O- z>P5~i>|s;r)Ir8mfQrKG`RS@fY+sr;;3P#0F23H3JP!(o^3Lx~4fG2V_;0}J6|rds z6C-5M5cD^s(5YlD!cd%^kb6%Mdq=>*1!RvZA?mKKhPkameZpPjIHzITM~<~Z2z-Zs zXM&5tzD29d>M^*(bs^jVSaeB(dZz~>2j`nrb;Mc_8QKI^aOb96FyKP5ep3q!{VHM9 zQ7)K5E(Qyoc0oG@-mP1oDjjz~6>Yad4KBEd#WBRg0Vy#I*7B-By>ZY#)~A!IrW-0ct& zqEG+MV6`UTgZGCbyj@!`s^M5+2k$_{3mUP=f&1|RG`b)&k`Nma_!5%f|Bf`PB1UjX zTMk@e-H6%RZ7M1CJ*4rj&hzRDkm#XcVGqL~&Kuz1f-XGozJpGZ6lh`uBa-JtZ2G?7 zo0A}(!wGR5;sm&08*nqABxGe$IMTk^8U)XViZ7Qw-e!8GadP@AIksZu3zV0CS|@p( zyn#wl_}AoN){4c~VZ0iP1891MvU0_*gKr3Kz7)JesD2l=J5-`+pFWX8oRd1Y9EarP z8MPM%tUGYpcw|YOG%GXiU8v1#9p;hqb|LWvlCA@if~kyIQEN3{9!8UfQ6kc1qR72s z#n4Cnk$s&;U%q_dfXOZ3jV}uOIuD~F7BO=yQZxvr&N@3W>mKZD+J!z&MC;oo*r!tJ zU||{!_HW;(fkl~z2CJ7^0DLw=7X^P91!hW40HskU4jVIteng`y$l4qOTrU?mPCg2G|< z{8)tE>8NP6`s;t;b!Tf3LG5fnplJJXcKb|d5Z5wHe|OB8)yeME4fNT4dHNQZ=E|c$ z19%{|Y$wqAlZp7zNnfCpeDj9dwLjyXg{X+>!qAA*>v`>O1nSaPtjjdcDULW1I9|}e zC=XVr1(i7}SyAWnVE{>zT>UEyHZ{L(QX>jqg{f>AK0%rUfDlw+@rkQmR@8X&=J{(( zCX$D)gp9$#t zq17ZR^V0`Y2jz?{7ejKnPEyz0$07of6Ta@I(=k763e3euold~Wx6k(Dj_0=@3va&j^^|3l3d;zg1E`KZQ6)URD4iw=Xl7VNww`(8*D zIL&OmlpS{w3**Rfb&PCjy=;%l&H@$~ggA;Y_F;Bv>NB{PQ97dfXIGZKz~?uQv_HMd zJkbZ8Be-`gOU?r@*ZWrKf;@2A+zcItzE!#e`U~Kb*I|j+8etSFr$+yNuvCM&U@2-c zIPDphatG+qH<3HfK1-k^GC>G~G!+XT%;LaiK24MCDuw>HPQfD?P~ND4GUGo-tFOau zVBdobc0(N1VDtqdpn#!sPa$JTEJGVi1cA>Vy$zG)y%UR*H{0F-zhr_ev>rVfHiV{8e z1EP1`)eh)Egioj7%`JzRRe=cT%<;v4K3|BL5zwDPMJGrjZ;B+2>vjtbbYu2|bu`k~ zizo>o2R-fFt$m}+81V!cjeh!_J=5-Sn1W&3eOFcrDYDL*#$Cn5Ro2Xj&pJ|QQf^7S zeYAKhWc-OG(S=BAsjIZ;x)*SefyueBFgoM)C4>2s`$R#M zzOl2EF$;zL+0OIv0!E4DS81H*A39rNW7Fa*qw;k??l2FvLn;&-7$m$AkVs(_Y7~C) z^KE{S?S`#rDg0iw%anKUq}w%5^P9}yDHfV!i|Lv5AHPpAUl$Eb+{UIQhRH?}Qc}Od zZD6EE3>=Ax*GJ%w_+aD&LS-Cin6^M{kb$BoEn8r6A79muyAw^U^Xq%>UuWLlQsYnE z`6BR-Kfmh}od#IeI!Jv$9z+Q4&NSrY9-s)b+Mbn6PWJPa(An-{c*Sz-u;a?r1v8(o zmOP#ESDE!Jxmb(cpSTFb+wj2Osf*(bf} zcwb-K$5DYoC0bRVN75!&W4^U~uo-YzSinJ5{w}7LrCXL3z@~k^UbU|cy_#}x^=<9$ zrb4G?1cSzHXjGR1PvTD+ryFOd!GHfckUA}Xem;_tl0u-Ff;|&dQNfGF$>h_BF5foN zRNZw~O#C)BEKm=}l_-6f&w3rq_a_JQ^;Rcpl8TBrU_xWy2Pz7RD~ycStDSF|?0Zo+ zSexA@jBCTO*$>sp@2PUrKr2mG&m$BSS+9lsH|PVZ7W5R3VBD@zVnzs7rR62g;N9i` z|KkQr3@#USxZl}sdP8I!ZMKl(dmZ*SJ16P*%3HKLwjA&rp%g9p?dH3t`GnwHu>iJ$ zI#7XueO7`vsiPN!?y0#s16z(Kjg5^kX-Lw{i~-Uuu_kza0>Y)dm#Fwd!g&6v4A)6j z-e=*zZEs+?mnWQjX1#n+Q8>F5RmMF`h^sDQA$}5btiu+gUZ8&+oGZ>oN}x^C2$FaP z%_3jO{KiYnrKHelX=yd~XQroNa%5#r5~h@lY}!UNA2$KMba@yP18JXduZ+L1L}(y2bVK@&@=qs|lYcj-UCHp)8q% zex7y_@W-zm=)Sy;4oNE>AuxVIWLVQS_ zu7$V!fYQ?1Y#)r&am`q;u~~l(t4-DtvkX1nAXNC=$S7Mqarfsc$(;*-)8$?1BCP2r zLntUp)xg0T2JRud3*P-l8ER{yKNf5;&G63@1`iB2T7Vd%u@6%nknwSwdwbOI`=FKm zHYsTb_$hd_8RtUBZW{~@c?HJ|;uQ+~geRAlVrFc7k2NxG%e4^?M<8E9U4;04%}8tM zli2B3xvBi1ml0WyfbWnER%-BTKadKQTFf?5&6OLEUmUAn7x$j?`0F)>eQCd zO?B<()&w4`37OsZnsdo<{C!75;ib)hey%t{4P5Y^K-+HNdhp$cH$5PWV%PhL0Wawq zCT2VDDLAx-B_?)&zKBr3$+rJ=VkBVH4?T7Cub~9ap-Z{vH=~@b(fz9jlb;Viwjah* z!w*{16ruS_FmZ@~_8kn|tlCuZXzNf3rrUS_{yy)nr0uosxs}I3yK?~& z*e|nA2tk+#KWkAj>G1Sr)_}Z4@s{%ZyTv7Z`rzV>wjWHKK_4JESd0Ho!cI0`&Gz;6 z{YF1>i?<4mG4WUaUpQ&of8Jg48k3;t8i~Z(ZB@dio&9r{nbu-hb$@D1JI1u%C4Y%{ z!mOpDTNZu|MPm%SJ*Yz@DXFQ)pN>G}Er3hI1qndjtTCVZ)XNsyiLu=Ow9;}Ve1BKy z8N-amRo|;}BhMdVPmy-eFIK@6G?Zly_s{Jo(U||@)?Z`HTX*eN2U$U8`UvJTmBR!! z#ND|6dCSt$5;5PKKroo!9J8Nz4Hsp0BeAGR%12-Ri+3m9uPfEH2n-mSeh}Mk$&Cp( zm0Q+`jy2%W*AVgd1|x@9$ZRiK{%|_du0skz_GvD8>6kQ+c-d>N?$EJjHg>kcm5-Kc$@KJgcj# z*5-O_F)%OV`Gv2C3ue2AEo%nq*@20L!7AeSU)z@$bvM6!cf7mtL_`FgX4mM)D>{#B z_yO;s!~6Btv}jmZ*aNNa98j2~K^ME2ID5qSC(#sj|6p%R;mJdu&8i!u8rPY$OF5(^ zB-5IHe~b6`Pm^p6Ya{6<28We+TE*Xk=g)!z5>(Ny)Ilk^)|Zoi5>~6NE(u}L;0uk1 zp_uO^>wz3=RQQCDHTG-m?KVSp7Lcdj;yd#A}8A*7t-@;wIP4I@fPJBw#;75#r;a zkZ|Fab`d_%m+{r9!+epN>%!w0Cmt?8U)kvv$D`&v^`&ldkH>X*=-es365|d~(!aK| z5oR{K294zVurR*3=&&UKA7k|M^Al^j zg&kU1a%5UowibM}SI!)GIKQp8iWOAXFqCL~iD-KIl^W^-d=JXpQMFPAX8UhfYMry> zw@=1dJaLc@BapvxYYGB-)5Js)xbWtKrAUoCyh2o&B!`tL)fuiU!F&mRwpK5J0!K?)4W-Acn&yf*@lN6ah2keb z>A*gMJ?^0;HLvE2Ytma>Q{&{{2biV5H~xYb#%eQiC1+HIl{X4mpnJ+FY(PGix|6Sh zdH)Q!!~_zsz5~(vEdqk(OIZB1kOJkYGl)SCb12_y<2wul*P?9GcW#aD2sIlp2H(A& z!O!IkJu~>cXb0Q+KABgDRYfS>!6Y^uZlK$@Zao6$7UPi;MwmK-LBQexJ{HL{ezP|U zhkndnUFps=F}|(D?y%dG%;9`==g_U(lZTJlno+y)7UUlJBy=7UTmURVE$9=1ta}a1dZz&m(&jR4mjz+6Bc z`*mVSVvNA{0&r75FR#nv4l|gbGVKK8h@cOeFTvw{^UohjE-rki29swXVrY*V{LQ>S zT8S|iTmLC_^5c;v=~?L^Wm1liCtL(n!KEpNgjJn>xZ)+_Nnir62QDrMx-oJJX{`-R z3JnVhd8tsqrw6FZc1P-pUp7B+oqq#1G5V3-pYVhskpQ~XvRn&7;q~pN*1qoA2sk6e z8AA8P3Lo-%5Nv=cyAgaMlGB0dKFg~va+rov_@Sb_e5;MUb93BzgYY9v$FXQF#*MJN zs3s>|bETBgEt`j^C2ge>wP}(2ozBfyA|LS<0s_TyXan*<&>mw-Q0fM5kLU3Bm!Jn1 zf2(gay`Iet&-DbGxQe)GzE^F?<&X~YaN#VI)FsU{jQ!u+O}%|}i-X8*c?P%TyWCu6 zKxHTaVjSQC)E34(R-=@lHWAX@xQyj?Ly~oJIl;8hMs3>BaOyFN)L0|bV)qjIgHKQh zI0J45?!LspMf{wYAoBoB6J}m?0+42A#fz<{{9x|q%v$EQLq%qMO>FJ225bf)+`27a zZm#&sdhc*Ghq`r^Z&?Rj#d3t})vZ`qMtE?mh@`yg!ByvCVq^>gNB?NBjeZJh^W+&^ zI-)N$6z{d2(1|}@!t|N_-rtl&m6FnXQurn^z5vy^n^X=zQsf;89~0SnAf50XVmz)E%Y8#T!w4*MeMy_zhmw9 zF+OREtuD(VKwgo@A-gU|5GwyQOqd|%wQXL6|GO=(!S=F6&&u|?2&wmxV5PZDR^Klh zA>wIUTmI^GIhWy@xBg@limP@T<7120C`85Zl5X?&ZEeaBA#Oc$kM3)$f98f(BO(-4!Yp z%;Us=P;dPhb=6nT{$qBlwssy5og8kxDJvM00B+!3X=yZ2W>lLBGS%A`kP^3wAE$$o8ptpuf&^T-E6-pdB5Rw zv3jGxirkff$+USQ)}QY=Q7A4FA6%#=LsS1eCh}_k*gP&R#b|T$4j;D_tv6hn>in7S z-9l+~^^kp;p+p0|;>}Puy|%YsfRs)-=Xng=Yu#YOh0LF|{V`IoyFw%C*=I5*;XvGq z^}?|6^R;>lN&^xbo1$c;Z*95~am#exkVa4-2^i4@iXrgYzMug4n`gMMZ}T^qmnA-8 zo}bseYRpf5$~VD7pn+3fH9?mIvPwKKv~@m!xw_22{m~;7+<0h|w`tvEsB!FmIVz^b z({xVU{qZ?(u&tZihvHhWr0&q$Rt7#RLLfcXb0T?URUwePE>NpMUchz|#E(YZsc)s@ z)4+kz2nv#-VC-C?<2<3Z%a$n6u65T%MJ_kTuV*T&Y*ySjHT184@65z%Wb}X4a^$|Q?gIJV3x6GW52~ae z$SJsD8jl(@Dusycjhxpr<~m*NTDuBNjEUEFW0a7`@Gmc8Jc!=>^rKN*WEG0^I!+o3Wo$z<4%y+GGvQ+MW7z${g%oxUs`tW#rL}H3IBUf zU(+7vF$a?Ey`P#glW*2K#lXmUG-jr)%lE5Z1 z_js86;2B0JZG-FYJEhz3(n(@|?~{ST_vHz}^9swg;Qi)DO5VOdbC9~R##st!0;w-=1m=Z`3vDY`mMzZ5tCQPEl^n zPPL*w@ZEsGT^^GzifQ!B+~2o3LCIY#@GCZXJ*3sw(b2yfxI=OT-tG^{Lw$Wi97qiJ zy~}p#yP&tw$txVG_Kzm(8xQwEsf<>IIVCwD_Eqb)R-IsrFU>ec=u~a z4O4u3MdF0vegFN_D{nb;2J?>;!B_m!Z9m_^vfr0K_TJ4&yu4q)Vs*VN@^r+W8DYiOLqaBRY2*8ilFC0lVfODm@sSu$K$Og$My1s#ork?85tREv7D`o4isFS z9cEt~=Mz-2-=TV!qR zBd|8RFj(!%2V}7>G?^7yj15nE{p`9WfXyo6MAx=*$!Oqh;T;Su%<9q)Jx5uMNA(1y zo8&06ee>E&yT9gb6tHR0Au#9}8HtOCT&}Jj8W09@oCqK!eSLj`h}Dk4!(E(_qP10( z@soqgSHULefmVHJ8lP&ieD5PL<+&?|9r{J=JbYsbLmJ3qw~Q;`^oN|9+8df2o%U8+ zfO0o4`FoE-_gcV}D1k(cV=JrorvdBfe_35y53;A5@>C<0Vciab`b--2zuVE(0v!iQ z2ILkL?rEZtJq#pcVV#GZDY~?3IX}~2*mCmdNu8J~vHzo*DPYh--GyO8hm_wsJUiVN zO4ftOR5DB8%ZqO4?C=Ud!qRDEUNtMyUM)d?_-7%Czo&qL`Avof>M<-!DU_}tmxfjp z+topA=OZD(J^0dA(6EA_e3x+io7Vsb`QFdiAYgyM>aO-csXt*JpdYc$G4U$vME;3# z>hmHQIrjc2yhoQkV5%{UsuQub<-iZ18p*#(>QMVh8P598zPnI+>NtNI9xFAEP1Kn> zX!JR7vm`)ujy>~yYMwRwSK0_0`&n<5vpwo2G4~@0iEE$@Xy%Ha9ol3}DpYN9AecFAAj zslm!g3{)uFn+;eqtE*wRUK+SW$c z#uQk{!mKLa*&Fpr?k-}*W>ArTWuA#y6O;1nHUl>de6rOA<J0q(D<6OgDv*vn0gC#04bo%Nc1HQicpF>7tYq z&-rfjZoK`GrI640=Zuut8X6sEoii@S~dHeq~+QyLq*dcNH6ym<2r7emTn9LpZLPJdOUo;!cyZ5ZAOP_7X>;mlR7e7R6 zSJz`2vCh7C8LgWKklmFNV_&XtrA#$Y$gR9Hantx+X`Ei&93D39J18UFPZI{9A<_Zn zK^3k$J30aZf_eXopM+pOd)#7QIx(cYI(vHoF5gcv(!NX+3Yucc(mU925+Kq~hR+0M5vWq{d;30_t9|Mx0QW z+0~a#zFd)@Wf!?tP<;xz$LA(p zd*_O;CtD$B%%STcZ9Qa;8qhM@4XLPqZXkz*^y!RSFSbH~?g!a#s`P*+@n`*IEi#}I zbV;vRGm zL3Mr|BX!OBu7i8Kqy=>vA<0uDwF z-wx&1$*(PFVo$4D=EI5?urZH~f>=v-bEl!21w}o2_eXO{Wbvys-(%C|PF(ZvZWNA| z3+1LVns)Dius}If@NA15W&W`w^$o8|$e)7mb`ObXu@|MeUH-B_(=lqYIrRR}hb8HU z*r8{O(Q1>E{D9{F6-@6DY%-M0APh{b2!0_iqG!alCD+Nz|GUiPf)5^2PmRZ_Ff~p; zWmI?N@NdbIw_2CFXvrY-vvj0mXH|f+tj0p4&CvBGFR??SZ*6uz;d} z+Hp}Pkz11o9gmAL*7cww4xN6CT+`IJ(F`!BN(bNoN-C-gF*{ug#b7F~%NAo%4s$?> zkUI=UsmsC+dGPehWq8dnMVxMg2MU%Y5afZT^6%jx8weI56c!c_<>_1kkmg5Aiy!FA z*npblcV`3=qxh^s$e+xf|!g+ zzw(D-7UPg`4G8OBXKsW`Pycs_S3U%EM4 zdGfq6>ZPp+Jnca=P=5#x132CRNE9+4LO`~f0^@G7wX0$wR=ox%WEbakFj38eX?37s zm4%`30FksM@I}Mq!&@FWG;%PbMiwC>LG^P0IAuAYh!A$!+}vVnLK3;mi9k0x3Bnj| zUS2kx`pZDRhMEh6L&rA)iotTNbH{lv`Zd>tMPZN)_{3o=xT9>3aIMwljUn!n#^lF+ z{1^9~)!8prK1UbK^~HsA^9YJ`gnR`o?9a*o7L;5tLp;#O=PG0@EWG39ONV|0Gd;T^ zNU%@6TA#03SJxqOW{BtT<%x<^v=tj~A~1MgP6H7J&kMTkH^Eg|5sX&NjRgr9!RFKe=C%nKP?yp3FBJei6chIGwd;w0_HS5!e}d$zqT@}pm! z!QJerzm36daA=~(tmTwNtZnp(q9z(V4U44+J2*VuU`hA&U2_1U23R6i(Dc+c&IJqG zAkh~*N#3@Iq&z6g%BBH|z+ipT@b~pi%6puiSnfQcBm4dA&PP{z*udxjA*We^3KRx? z3ZN9K{jT9HUX8jsFov-Rw8;~R_MkDg1u+2N#`7aK$2hPT0qo>jLG*Y4#7jKICc}JD z?70(XIkLLazCchhNe=0v0MX^m-N~P2yyKdbkhoXoJMI{2J1tQWlN8>G1%aA`gG1Tl z43U&{1Ae9+|b3QCYeAz}`JC6wimEt8E&2$5Ha0ekAu@b??~00w3x4o**y3anf&tJ^qtkT-L2dik z8w0lq1?t*!wzO(tD_f= z0e?ogVF+XzN8ncA<>~pPWa%0hE=xj!2#G1`^3|(0VD|%&rEoY~s{(edY07?p!6$boog1)0NUw>X)>*uxl^ zA5Bd=%UQWV9^9FE=O+<5_sY^x!Ag`X(6aNRT%VO)(acMAhLh^ymPyMuuU8BD!=N~$ zm61^m>WjE&n6I9$oN*hnMFXHmhduzf=MU%r+!q)yY8ELLE)15K-$fA;68_G8kp$a{ z4OD5sf)jFEk%P)@0gSZKCSfuGj4Y1pP8MgkT~u&8*;PZ50SIf4B_x_j76JnT8hU%f zfqj6_++OSpfLTtVHv`Zb{N^TSFFc8Q65})!OPOlO;_(Tt;@C^@f(feU8f;P~@l7{o*KOFKClh2Ah=4Ou6|p`Aop zP7Vf9C+a}H3o?;gw{O?Oq8ENGeb=^B2_K z!4z&{n002|ue)L|W!Xg$MxTY}=5l+l6OE6CVDpl)Ny0Zt8C|+3MyrM|USR;bDY!Ba z@`3XN1D%1Q1khFqd3hs{zXPW13u+aB1SQT+Pb~R3O>{o5&?wqIFN>```^M9<{RA7u zJ&e?xZ)t|rQd8n)Cipc)QvNC;D9uG*Odxz)hfhzE-nQufD(Tc`o8z`DVC=eEn(P2Z0{9ck$KxcYu~#KU1auSir1b&HM)q7J{0Z zHHc2oqK&9O5S3dm)adVv`vS-w4G_fGEOZz^a_->dgcRKD@KE5YWM*5$rwepXN_wGs z_OZhz+ga&6rOv}JRQmMHPn&(T*Yb=tX6!6brl>7<`gZ>*ymWVdW24jSIu7^i>C2!7 z7l7!G3`hniqWIkEL-c?~UC2E`>t}uw{XKB}ds4N1ReWu9r5=i*aok#IXxy=^kw zn5#1$8FHQaeqNFL3k0D;%|K~2$L}I_c~n;dOV-^Kn#TiJpIY+F zeC}-A&^zAu0qWRTt-&Yb$e>V^LFljEYqu`E1Xv1#OfVjB5F9eHPNO7OZ|DO+ zWNCqS>@eo{IvCuPtL_rr{PpHEiF4?_<1vo(0m16WZm5&KfDi|xOd(J^J18) z_?^M_O$rt%u#zWez4?4TG%AvyuLM0Y=O#k+fIxfktPi_7c|QWQfgG zq$BD|e6|$=Bi@a+!mGai*3_srjhesU_H*{MD>AKlEK@#D7{>41to_mP7}!7mP-9UM zYyFiILcmBMaT5gbxIBOW)@vL1s>qQxYXsGsjHcr|t(tGwry&9??x{eni4C)DJbV3o zj~^mi7?CR)?vSy6igA0^wx4@OEJLmIIq5D>%_64e4{r?ymJ^F>6PFU_bOwnwAKZAP zYr>nnu&Q^`LO&QITRD=&gvCW?Wc3m|G#*0AJao~NRooeK+%<=gJ$M^9vcvH1%A*}g zIkBAQ7BM1+B2sx^Z1o5`bfmEHG%z871Tr(YigdZ+Y>o@MOp5XSLOV(vPDCh`tToXJ zOI}PC?i%^YN?rP7Ol6t4K`henX!o&b%A&$QR2{Y;N|oNs32RvpgNj~%{pj0YonlSL zQ=bOnVBcih>ooI0uf#ZOzVM}j%I@_ZSd2}tC6pWXg2WJ0?mor#27p>yuj1(VN4Y~f zA12O?d|Mc@JLMHfvq-ivcTdF3cnnf6CawkGqx)Kke(1iTU$y5RVnylm+q1 z!)UUGaWmcVhRyG?W07x$q8wQxkDh1HnrRR==LZ$}bshyRa7@ z#Pj#mm2=j{h}SG={r`UFn_8I)OgbVvf(r?KQw2ea`0*Y==~qH>O6umuWK(ex(50{5 z|2e%(AFyJ1??$Q8Lj%H|FJD+eu{rzV!1Y^j4Ky$|!FUSbnkdd>?S$;BNk>0kiq;*p z-$Hx(Fx>Bh^gTMJnDnx?wK&=($`nJZb(4z=In<+jF6$k8HF!_rH*M@Y7((>%WaBsO zIvKuj4`nI9@`{E7`veFYgj>rGO$Z+jJhoabDEQEuW9;(uDPO+-8Y~>QrQxI4%NTfQ z!K^l;bZy&yAtBMu`uMgi{Iw*gJud(%j^JjX*JXB|HTtqwG5)VH<Bj6AHRF@E z6ch(P3W*~!FIuF2KH^}BE4+D<_b_mXkLlv()1*V?2a!iUAQ7W=aocDR+-|-v6T>EY z!@}S9_EpxFT#w0e!309@D)d1H0{ zw;V;4ELPM%YgV0Q=xr|<+2IGTrk<4@^OTfl4&U`Se~z11YB<_h?ZHpCC{Soy)_vmc;N>)(0FXpM0WSG%c`1I-4ox|eFFkq1&oMHE5fGU+Pd3@JOL-CM z`Nb);kGrOvAc8iBgcyT}!xyr2m@v~Ius_<6p_Jz9@Bam0Td^h_Y+BVeLmUC3h-8~J zwzknXZ{-J)rW{0wFQsjKu`BM8S$!U^X|TJ3DDTzjJO&&dL zcYv4|sh>c>L}2hMf)#;K@)68f&pc~WVP@N9dxg+&qpTKD+*lj33*3#E846jB*s^6s z%F4lO-!4#u-DrRMKv71WAE1fj|z zl$~&a{%mg#f}SkJd|gq9j7T|>u9SAODVQt`GBCKgMz_kL=k^DLmnN9W19G{SAPBPE z7#A4WgFA|Ur;Qx|A|H06j?Ldn@>@_uo+KY5nLvuewW_G***+R|w+A}{1At@#0Z1^E zgHGCU*c~eIIt`Gab~9TP00b_2#r2sB5WW#AZ;!Dtct;I~pmY+20s*Nq&_yW(v>FAJ z4=u+pBMA&RgQ5V~dZMd4EySw^_zPr7GliXk70G)bD+ktNvqzd4X>@bPe-1x-onh`* z+6hsCt*vyd>K|&VvHIVbM#lT&XohA2@+RLK5%f_p5XjaGMWA2ARf;>sdgB^eKITfK zyb`fy1<413&4Zd%mM&`cJrgJ9HQ-qeQb9WnHFgweJ`gA}(e2O}sZ;xNw4?#3IO{Iw zwO^M3%gv24S4j9{*bLB7Ab4pPa$*8}HXSl>eE$A;xNz8)7G~nB!fH*0Nb~?>;koCL>AcCEjA$I#P`7sou;2DeYakx`(h~G9mP$i@{590QD4xoPAbA1g@f@V!?V-VocIxu zAj6=IAJ#x3!g!J<6$X31)voMHr4FKZx=R9#r$07ac>z!SCARveMAP4NGWKd;kb$c` z>8AG2akJ^2Q_QVhD=zX+u$yTtH-xH1*yGyy&yIJ{z8*MlRPNja3G#P@KG;sEN{E42 z3#0|=g*k6ibX*67dGD)f<}|ZRLV($e82rmALUkVr+2M603P?kn-~}sNTgrR)E`Y`! z>VgA6c`)T@D7LY*#<4QoV+RC$rknns?hTb1HaNU;5Czx&st(G;bB7KN4rY%)`Wy)Q z@334c?jiQQ^<^{Si4WDXt$JK_%gIkiPo}7${oX5Ui}oB33mxgYcB|#}>t1y(B-)1DOdtWH z*k)GQu`xOfp*9n8MlzrUD+dOsCUFbxpU=irn0947~E*}Iy)~4tF3WKy`Pv&lyLJbAHRPW&u^El>(p#M`>LcuUGAUP}f zfT>PFr#v9iidm}PTw35MpCeM)k80F>xXN+n`I; zEzta?n*78UR}An`D3x#Dy&K@;knS!)K)R&6ySvZ50Nw7h=bJh6{W)tK z2l0K^de)P7T-S9s($pi=3OFkOl*{ZG)WrF#!yy$?4uX3Goq(E!3T3BZ5vqU^z^PNG z?pv?xf+5HQ4VvF%htPI7#Hn&-$=EIK)2r7hL2yAX*YGW5IaEn%r)u*+h#NE*KCoGd z$a7uxs(ap>k)t^3qu6*U$oI^n+W2o@I`eL3on%Mmqdgyzae<`OHIwVB0SZT#*f6 zy#dmxI%m+8egkMA^!LAlxhDaBC$fXgglY+bJ&Y!m&J}!d!C*ARuPTGr39RT{K!lb7 zE51?Ipr`^IW1}~3>beIao}in}cD`1kyX;jmM0DzjqZ^;^qO!_u^1FBwt4S_W%VWS7gDX| z(ZeKb!r(31p)PpZY&1gR@kSuZ8`*Xm_0`?LT z@rMKeQri;DqF)HU!@iUGyqzVD3EMROi>c2le}TClGvoMkwr`I^??+CA*^|0faKmvY z0DuEH4_R1Qm!S0LGN3645is|%Gwk@B!Y3`m?WBvl--N<2j6vuaXk(5djC&TvCYbTt z`G;rB1*LRtq40V^VPQ2G5Kv%ubaT4^K=x`#jDpC}4KfbU%t6%_>y>ZQe| zdsR;_nA@=4B|iJ=e5MWIyd6cAI=CvUU-JC`U%~KQ$~%uDa6~B<&68X?=yzDPZ(v{z zU|pO&J!7E^pzp2c@1mnA4>@>dvXCMsKWG5noDHycK+}ZhW5p+k8=5M{En&S%(g@&= z)O9IrRI-N|dv^>Sg^Xlny?{@oGxjMYRlO~ch?yaEw-9KanYvxxKyO@x>{T;l#ek7` zJ?I{wxUXL^Iy=5r58#u@6C0w{X`5*G!JtOkfgIatn22Yb_8d$m`#}0Po(@@wz>5ULr z;MeMJ2PjXC&}?QZo&+-=(1sseT(Md$Yt-9GJh^?Mz{OM~T+k>7C_x1T-YsX-s!*H2 zO9L7IJ0QNosGgy%LN3nVyK&jV*Ks_m^!h|zH-)l~g>gS8pcAYZ&MJu+et1`Z3tYn* z$TK66JuLP`6lf_#K=3R&Hr8Zu@Uc*y8#y$5xL%dcNU<-ySH9Mhm5qCAv!fMI;~JfH z91JP5_3y16<0Ko-XGq&qfmL-i2~D{?I5?QaWc-LWCMOSFcM(Pd2L9BjaE4Z2-Kz; zPgz|FNTwRw&b=bC?hAw}Z&h5r{Z87MF}IRfdMJ-51h%3e;qFXDo_&jg1d!2qIozYKHJ2!Tj#QA-ckNznI@qJrB2gb76Tb z0hpBMZ(sHzjynnnIAha5T#m>^s|1J7+wP9X?gMX1fI~x+>#q5tupHPv7POSkR%1oW z969`UhdH9l*8qH0s28S=%Y~Xh*aW28q4&K&#eNeApK@D+L)%D*9l3_!oa)#201%Ei zTPb}NlNJFk5E2gXm*HCd`xjNL5l%A*>)W-IQyizAZd$die0RY)zLWceC56G8`7Yn0Ei$mBu&=JU9iAM)Lp2H@XbC>)M^y zbG7z8z1msJy&Fy}BqW|G1y{q?4ICUp_H7Wl9N-QBO4}>j6UM004QNu5UG`uE!{1xx z_-4<7eg<$+S@94|TbA5D1M2`oWEba4-^pQ$A33<}i`9TKhv+!;{|T76VOW~ZDFwKD zR}Wj;1A@Xa05@i0?+KllPkLLB!9hiCu>8xdZ*|KUedmb*a>zuBJqM5=4+gI>aoyDE zj>dNy*Dh?L$vx{|zuwcRpwbc#JboKR8p4;0w9e5G(L;iIfv!;`o;e9M;}hLS=5bJ$ zC4{qM^i@V@i-L=;7$EsF?#HKL=&S9gs8hqac!*DRwA?p5XW?5k_k8a^kU5~aXl#lE1*8vj*^s#UgJimpf9;6@E19JlL4&^rYHnv$vUoxf0wRw1lqo1wd(C~@LrJXsh~r^`GvLQs`v+blP_A4 z)da$&&GQHCEA#PJf8P9tAmx5uIvlrs9Y)*}juDM=w|WK*f=c#VA6%6C^rN-n?Y%P$ zWfjfID1@d67q(v8UhkHbp$e}1g_!3byeVU)H*LzLyM+`QC4(Bgg8g43-Eab;Y~agt z<+LpRY81=rn#B~4*!4N;F2Ns2wO$4%+dFM3jo)9Fh?bYALKgCp{w=#0ssP|wBcYLlUcwPI= z&TXN&flC?EuAzu258Z_W2`*ASi4Wj_(WmR-1kct3o!AlB_ZmMFIf6a%wUDl52O2GQ zF3>N|T)=+>xI1w4BH*Bg_!-qqE)a3R?1_MQF<_aRfX0Bx8O{*{Cn6S7h!z$WgJWYA zsjthyd~IwW2U#be01!ely(ZvZBhY-#kFL3NW~OqaDqWLmiCA|uT!@y7Ee2P*uG{Xd zewf~v&=G5l85B95yfaK~4Wl~RA$A9k5TTv-i%Dz)eXDfeWmQF<-O{|;Xlwu3xswvv z#YPEi%PCJ!gOLcv<`oDo+3jy>08pUL+kfPf>zj0M2l0LX&{DsW1`cQ1r;+z55X2GS9yx2>M) z*7*6{pLonK`2IFY_|AkYW1B=?|a8UhvWRl`(}Vh7p|-rDPL`M^SA{}^sk9BbNm=hhyx0>#DQIF;!y=) zR^ZBv0Z?NI?C8_ifYAwpYoM_8IE>Sl#cr1cY9J|Z%=a%pa)#At_$P^)`+osd2HRY*Ra`n=%iM83@8nQa=(5d;XSkum$b>Hnahxq}2VkV`q07w1{}VA{A1ee?sy-Ch?# z5sj8cDou#J;?7>Y!BKt)Q?M60eTiBOqBJ9j#Sh{{2rd!|xGX_9`2mmvP=F3X1A1TW zItv$9NummLGbBdU+4KzzJacl)vzb^!Mj9KJB*BsSSpga`F26|VzJ||PSiCuzYc*iZ zGRsSjc${#KI<{eeI7`(sm8_AZbmP0m+eedzl@53zXO~sRT9YhG%sBu7>Fg$`UWVnA zXI`WJip-tIr`nnSc_b{|Tj1^j9@P?R(rYz^qaoTjpkJs2fe>E4k$*sZkXUxX)}Q*m zICF6A#=fVmM{*8>tkJD^4H8TUI<_}tb}QH5Bv_qTl6*TSF5Ee4hj|U;Iwhlw6Rl%t z?wKaJ1SFi)h#axhU01NOEq0fmNFjnPf7BxmMSeOSc8TBdFYoje10Dd;%JbkK0va+#3_3+`to+U8g0mTrSBrGzqxni>02BJ7F?(X&Z@&KY(z0F2#wt;y9-G-v#+l^W*RyGM;Y@Xc@}DVLR0Z#9`C z=qpCzBI_S27n|^U2$)ousVEExkw#{}KzW^LgFF$SpuXx2z@&>4i#UPuyZy2ZDE0_6 zoW#@BRRsneFl;9;5fcjmumGF{oXn2Cn^s-8Z3cgnK5ASfMCP}e7LFpBDT-0%A>%uRs#y? zYKpc&wVK813Rn6Z$Uh2PNpLCg5py` zO)7*h=DwKz($1pO**TqWo9ze05lBcs(2%09bUHPp6wAeWG$2pELN?rBBd$C!O>Yw9 z^8p^#iO0Kh&{KNwig<*V`;ah`{y;j**b6%q98G$oVIBna1`a+#s)qUd>md@NfJhz^ zT?aXZ2-w~rv*rgd8jY+xfVGOUFP%bI4eA+Rq3+w#QWY7vbuNiapueXK;hNe0q9EAv zRv_#H=;QZn4Fq_2PQZgrOG_ifBwsG*Q!M|aL6^f;f?iKr|L_gPbw30l5is(#wcZq* zkD~syMKcoy^6$>h;rl|*V`r$qVC#D;hycS_*c#N5&kfJ3HvTeuiQk=m1w!O!VtvXG zu1z3V6?p(b`=v-MkKy_e^-7Zst-Iv2spd|Xj+?xp!>?Rb;<>uQrW?*bU_;%m{VfF+ zL+bA^>TZA(0Xh~`uyol?KLBBD6mokgU{nKV?8=;@P2A8#a^puPA>s<>jv_82ugt4l4%1_4UOJD;LWViO`1yKxVSBFP9F>fu*X&XwxlU)8ji5c(- zomS(wgGAJDc_IyBRN3YihJ31kjnX}x&C z4)o2}ty2jIRs^OB?i{8{bN_vzn{o2(^cmO0>z&~20=cBdF!JR_%~POA^dbT`$S?40 zM*ibYTElyerjxhTNt_On*hRGSPlId>r%f*BA-)&p@h;|?#wRAo8eC4hQLRM)mS6}t zr|DC_aYT6f>&$xFn&)$-(w`wR0Dgi6TKS3O|4!)6Xg7v016U#{Xd0r*JG(#Wi6pkh zEErG#dZXL=VMX}yF36(%@zkAZTs;KUYriJw?(6M+1^{)J2f9U`s{2JP=`3u8Nf3ZJ~sM$Z_X)0CTshHyEFgg$bF&a z7-SuKS1YF(1Bo8#s}<<0e8Z66Zv@+oe9le#uSC`xoc22NRv|Ds@ADzxoOz{l=A}*VX0*W*ZNHa%hn_PyZ=qefk*}n&wEflw)3RUkKdV>j z_%Nf(=_h@OmB7@;F+iEcg8C!k`kte*4ul|n(Dc{SUZ1|nt*LMx!T_9|RnyIf#bX<{ z*o`?&ur^ON#R^y|8K~!!Fh<{$FU^BA;2<9 z?{;g^V-)01czN->PQ)CO?Um`v*0~=&@h9^DjgRtPAra933N^QCA1cmQbBBx%`N7*i zbN3gQMw%2W?&YeOR>@AA>D$({3RE-{D>I@nD?aAL3k|5h^)+n4+QWEX+j_}GEKMdQo`slx~Uz1SlVK`+K+5F%sWte7SfU`4Z zx&r5;ZgZ@WFJ5KSZk0B(%Pc0_43WUrMHFlfuWA#Ib#>sAhJvmYz^5p~3|MM^q)Msl zm;5qkdtw=`AkCYd#Eofh4mvCRq~frj{;d4@KBRP4n3?_Vx!Kg;ssdxoQu|_8fz;sc zfk=SC<(&fV+I*7y$Ik`3T_9T&X24zxpa*HlBth_I3V*aV&g`Y8TyxK49Jx0-5)Vnc z{@{58rN{!Ww9bX9BpjBGr8}Gk5+G})dMJGdP4zkfnp2vHxTaDaPv0O6j>(fv7A$A5Cxhvu=TW=aRHl>m;eIy%y>pInu?eWm~sEx|4 z)4nUC8T**h%*iyiLHXMv1?U{> z#q3gn*v`lL-gHEp6q* z&Yuj$J(gYu*})Ss+_zERdWi`@$mnFCWNB-~kHPmJ!jS0-#7IC#NYmh66e6jcq^F2e z$E(hK>y8k)53jtFknD5QSM*D2G#{+jH-DZS4V(vYOM^858If&2^H-#>!E^zm-Ixf8 zRbZ=Fmk>NDpSg3ZoUvbfPN-)Zpgjl+1uklFC?kdstY^%|Y?WtW+n_6WHO#vKFQ}n; zyKhZM&c+#FA#NVj=HQR*z)UU>iKP0gA=i` zEA^i%kxbC<3+GqNi10Zy$ehZR-Qh;|%0NVgW5^oaF7Vli&%(*nyt1pA^BnDi zkO(}yDj+5U_(L+tt99BAJ#1wPR)e|nir7P`V(6^Q3+ku9YwMM$CF8T++n4*vfB1^@ zd>xIk>!El*PRZJAw`ea0{pSt+17EDhR9`X>;i+7zs5C*q-T-}9>FLt(H8vUj!8?YK zFmLYwy(->Wm=2&G3C-7eFruKODiGztaIYvYFP~%~Hy?d8X*wHY9_<0baP0FD)vYUO z85#751{6NeAM+r363mWY@A?9et)rP)B7L1XWmb3~<}EnJo*9mFHX@Qo;C_DE)iX3t z>k+D3Xf}x;xS6Zce7~-e0d_(6&0R-SC~0C#ea4bd@|FO!_sw^SGkAPG1UTg4pO3+&g3m8s zB@yY(EZCwOBh9up2fa94h$kNkLSmr(Iefi_ZvY*+^?Tj(>oX!eK1)5Rmq5zHis@`P z#2B^xsTJ&3+Kv)>h}k0e{PQLA5NFSY80~EW+L7~~2C<0-T1eK4|9ZrqRU>ZmwBp7J z2#1Z&VceMI6>r~%DEMSYCOgRaxXM2G(sf9^Jhry5&AwN=1aB=WXn!LfeMs6nn-h%D zHgl-8hjIBojcim-OCPIyIlgdFt-kqIi#-vJcv&^XsRF(!LNn1V2!odg5Ved~tF-`C zV*2GB+K?tn7HL=WcsPlc$2>^z^AXPyChXHsaIOL&x%am< zT_3@-ITY456Xqy*bVlZ8_aCMMK@Xx`d14=AFzzH&l!Z2aY#QyR6Hi(Xp4_A{?O|6! zCII#OKUOo3E{J5Q?d0jy4Vb#TIYHTYk*W6oQiyYojea1|6X!&+%zAWXXo%NEW4hQX6(3_t;Jv2ZOTAam>0LupQ+Dd zr;#PoWwLZ;#q1-ZtwTNaHHtf!qz-1%M?2w@S}!70BZzR0sfl1nJCC84TaHylp;&T= z_!j%xjwBh84dC<-Rl4TrNM;ZXSef24PgAwWhizn7^|vrY&o!2c4FSs;F6y(qsx9T= zt?$9hhf9rpm_qO>F}En+u-I=xXVxKie0K+kC5%VPbx61nja{AuAH0o(%1rg85gLm) zBUU-$Sr*9p0<< zf0)j}&IC;~a1^V6Y+=SX2U?|~0NT<5Eq?Ti#7dC2NB9^Bo5VyMR(;x2(uRu{G!@?B zh-M8}QOO`8Ecza1!3BY(kOaQA8Dfe^K!T~Pl&1N@x$`2;J6iAaG%b|8t{5EdQ$f~? zV-Kn3bj0STvU2mR4;TBVOKTd-PSvW)e=vzmK!sI8`0pTVt)mFBJ7*V{*KP4H%~#n^ zTkVNoHRe)JKZ!oUrmJ%XJ;1(;>GH3+k?-e- z1qz#1iBj)SX1zK2(%qf~(pHHd-u`@gAwP6C8hg~EAM&*q1HtZ{A3Ol*=?51}$ zT%IM~x0Dq;6HPVI-#&|4_c(}5I^E*49GAq=$)=_+oAlZL3$xxqv;BsZ=dZk^eu{k~ z*&@E(cBX}XiYqOHu~8jga_;y#zJ8GVd8->a>ET?MYR)7qCT+;$1!U%_U?)!G%HUvcZ;uDpdHrwnAcKo4C}}8~Yjp}&{ZKcjIN+cc zHrl_wL^3E#Z(_Z&lWHVBugABGf#yz^V{Ug*N3ptSZg5QOyXp9PKSAnpS8va{?Af*_ zbU9cw@6|jf`m;AKIeI(nnPFe@Y}Y7-^g^wBa7D{F4Ak_i6y8yrni%w`vb?e7 zGGSXHER?*lk-fJ4*t3y7r}c`#!GLX&{$f)i*Zd3zxlcdbeT~#BPySRtMQ`ARSkaD+ zsaA&1S2Y?hGZZ`?e@m%!{>7Fl>BxL?15jg3>^Z&2MI@9UNlypRmEePPuDAY%<5Qu;)A(AVd1G0yBJTH*-h4y$q$DQN4kl>%uA%{3;<0 zX0h<$EN(X&pb+Ux70b&cS~uI;AhKNJt3ZSmU<-qG5#%hQ5Z$D8`Zi0C9bOI8}7FRuu zj-CN%51?cNzSqz&6#+uPrRxcC8)xhjJtZNJf+iOKqO(9Olw`czl~={hI+Jt`?mDplKM(~(0Ex%d^DbM)YtofTRYK0{Mf zVl#o935|PE{3axnAu$PNF4X@vDkuvCLo}UqU?3Mp)JEqD$MoPsRy(B z!rmw35C=!;_@d4RgOi6c>{~RY$#_QSsc&J|aG7ORNd=|v30wbdoOc-FfL8MXshM~; zlWWa;f!CEWHpNUT@zeUEG?sY^V%EXKaM8d;lu;&IRK$6jc1>)W1V~SsV%hc@rah;0RMkX z4ChX4>!_13JDIsi3+n)0UZJhW+j?`(ap*{6hrJAlx1BjXBPU0v1HW76$>1Zfx}W8+BRyTbt&bxk3( zGtPPOJWHMJXYrrL4aIagy!XnRyV?$Sm!rACBn(k~L-RgUJQ!T*9FXf%B_RUkOC+-G zic6ymG;q0Mo3F5()Jgtt1Vm_?I;gXUw%atX#F|q$+$s~^x8T~onoQdN&wNU=1j#In z;G!Z95GBZ&^>lYv1AzsE;t6VEs6`;Zi-Xb!pkN<^(g!elF(Cml0%d7_G&XtyH*aM; z$N&-eP_Uk31ccRBQ2v0F3L=V#9uD|6u>U?FToSlW*d~b=R#Xj8D$AJ9r^^lAR_Mf% z{up4u`p+Ub3){*W7GSg-CLrn3V7 znVmfQ0QsdB1F`mo?qt~<+WJ7oC@3TceBb*WWjv3esLx>;1=^$9eEpYnMgBLb7?4W4#4bpv3 z>+mcj-XUQfV7d$Wevq2ILQH(&k)h#z&{4h#*}jB&fKo3lE`|fRRa$S~#$%vo*UqCC zP`N`xLtb+?mo;Q@ZFz!R$xa#$$b(F8j@v&w3MFv#_}^Lqo30CZU5JD!kf~vK5!@}J z`33nLSaK>LNDo|tP!MVXYMUpLxPys`mOBw@9rrQ;_ayqoQ4owm61WHm9#%BO5KfhX zloBGOjHpvli3BTw@(Mz-2C6yXR?9c%o~0FY1}<;br``PyZy9EH0@L39*(o5A2*m)f z<3K17+E5FE8H+&tg7g#!OPwSmBSUfSEvr&e^0R??s?SN zix&}o6T*3}Br;IV`VQnO5Fk;48$h3afLXt^)}aUmpu`7LBtJRr1xbq8SK-eJ<6g8d zj~Gg&{%5E3DtZ0C#Ds*YRNc;{lRampTFzrhkn{Dv`_4GdS9kH~5XqxBR-b~S>-Qmx z4hf6ov5=VhwAGFezJ4|uEuk0BwN&)iDFzq*J;=>pu72F<&T~d&;Hj!OUL9vKcu|CW z0l>KZdop>kMZ;n8OHr=G%x`F5_68koh<5P}djkb?qx477g1*_ zT^VzQk}V8Ib{dc-z`pm-j{J$(9S*Q9;b+>ntGFzkZ)!QYFc&PEnsWg{^e_~8JRtk0 zkdB**B%@_dh%B@;&6dU~1IPN}qC#)x^np2hM+n9#_n> zR@#4G;ouQCmuZ$n>ct{ElU*ocoz;hoY^%(NcFoa|xhsjBPQpPML)T0j?J-N=PK%09 zyal1azh(xxC4$;Yldiq^eq}iRKIt>t4|6!Y;w20JiMqjJVm}J>QRuScR??rxLTh@M zd!v4V4DF`RkMDmc8)XXQd7L|gqtMO7O&_xb8ot+Gt6i?K&AR^w&;SRCc;exQd`&bw zB&@W^c7-}DD{NU`T5&jbC4vOppQGL=3c@PN^t4V+${X^cySXB9^4D-k5779~+5Xvq z`8knDrfyl*Ooww&zaxg+&6-iii72k2=_wT?@N#@rQ$a8Ar{RTtF8$VMeMObE9FzS% zrp&uo#i##uGbFbDDGNyo?hfNj$C6yTtZ{`b*va7A!+(3-Cgy3=)9B6`FvbCPq7&IO zIQ!<~c8HTip4pv$Z-<7o?b8k5)7RE|q%Ip$dYE}^Vg`$h#sAk+k1ZZ z?hu;YJWsavT~zR&*`*628qoZVAt$XjEE}Zi)^~7-1_Wmws{LavlAji$c*GMe)s=5` zndV}VLzn89SXY1MJX7zXC4F>)D}(eVPjqKz#vIB$wb z_cga^BZtM$u4%b$e9_Cb+WPkp!azgbfj^%#ptM2s<7cZm1cO{h*nJ`8%73j5?y^IO zoB3^Ee63MMN~dpJk#8vGWnOuu%{E72`|IK^2SQ0W>KOR@1K^Lz#p57kysl9AV|Z^U zkp=s)uK4Yg&c>Lay;m)1<;DvIFV^pAA)xu=i&_;7O)u`LvbIyW3s@SEumCM;^*Q@~ zz0*(VU!f@tm=NO3m@(fv2B$*5VXGsZ5n%*5{4pom3=4Y}5K2g2FJSF9GMJ-tGale+ z3o)TL?`JzV&8aFR_UA#Dk07g0_KK6MhHZxuxd?=1KH{J<&dErwL}-+wKwa6hb}Q@t zfnObZmfe{^PrCbAf0mLnwi)uww*{v1o|%a%=6-7kGnq6_5m#}8i$<5U>C&$DlddyO zLux0*kFa>~%|o~j$dE$9K+3y3pHz)KWa<@{Ln!9SxcQ0D6-U9%GKxDte&7hjoOpH& zY=J&}>IZ%3ouZ$U%s25+ZL;f{gSwyKYmJ78IHS3{@8>>R+0rerjfoTgeXYw|=V3G{ z8^3`L_so(e(uw7B?Q4dawR@CCm+u#_{e1tf?Zny+j?kZ&H`qW>tP3_IkYhjsl&%{e zGKQPfhP_)eJjU{q`SiW@OU*fe3ES@%p&e@@MEiGuE4-j_%VEJFaqn&W`Y!7wC=MVX zy|bVx?-?9@v#gi%lI?|On?Fi#e4VlX+jq{pC!zCxahdIHm~yOtFc}mVYTsv*=@>Di zYf);xl$&`nnEiFB@-68H_oDuGp0hi$^5=go%vgc;s)@Yko7xg7_)6ld%_VAwPR~WdS`zvpVYie_1*f_hz3Woe3|}G**~A=(e*g|_&w$jHTY~UOJ{S|ygf8$ zA$aTb3CADJG%JU?lgIsZm<#lh1^K;Fs*+H&!MV_^spfFGefDM-Kd4}Jis9W`!P4(M z`|O^7`>2yR13(_phM*Zxn7MkEdJ0$O70uI)Z8QMP;boU?csejrnEb9|7XT-dM=&O7t>InMl~2yi(a0m(vn z5)^xXF@~S*^6O{uGZRAv3ZJh8<*oBA82k{)SULh(BlEZ)+0)Z^2c~`G^1gD9wdlKP zOWs%ryT(bVzTvQW3rgK=H=v^j6xx&ios?;oFyv=Z=(H7!eGRUt!nPj;>RP5ugNQWnx$7azGj5<+s=M_-I5wS#?2Za~R*2Ut7_@ZM{w)l%(gtD-R9{ zK`OxkFQq0+4_pg_!lg4Ha`vOE>noH+O#>(HgwP=fPPqpbN174P5^Pe}u~Apq(4XhO zm*@}a)&4N1GMKP#I37^QmV$IC8tz@G(p;kvq}ohZjsY1&HYg}5-%n0X68Ds>wg}oR zRp8kyS5qN{lOV*>62*rFd^^R`>O%yAE~saaGtFm_d3t{dd_012!!pijtB_+WpIPZZ zmtXW_W^^G(4$}WileE_*5 zdZ+eux^fOa((YI;9N*wTD?F6@Ut7G2K5&ROmLF!Koz1iehH z1lo49eFXsk309i}7By0G1TdNtn_qw?27Q<@X9CPn&=$|j2J~F5*)zDNG#C~Vu=8)G_er^ z5o)NtfCiewmC9*|umtWs1tAz~kGTQM2@=RWX6TRAPApBz9nLW#q;`+{w&5H#K(i(K zdp-awv=%b8GAChm&}8 z0J17SE1`-*Ve05vU~5!gwa;n17NE$C;O4Ozp|~@6U(N_@aSk|l ziLyB!gM))Tob51wfxij*s9V5Hn*`U)t_l%>y?nV8IlRSF$L9-w{SbVR%ht70vzN6z z9_`ZcD2%@ng>J;kO_wZRc~@&&_OLw zbO&%;q4Jx^-u4>6A19!IdAV}hB18=dw&)IDN%tc%rzs!OeyvUrIe}1SfR=HvBXBjj zjQP4)#EssK>t9w3A0Dnu?onv)ILz6?<(fO-W{a2D*@D;Tmv!GtQ&Tg0jlw%uFrla|wuwHnyvScgmpKc?m{2{#8;9 z=)GbL;@~I{iORp;ia1+$6DmrD94PGai@x33gX1;%o6_Kwe{9s~COGqe2EU?Ac!bz6|7Jr20#Qalt__uuA{*NXlN70r%7WJP4*|fI6w!LceWo8i?~jC~RqY zxh8u6qGV7!5h7BwcDr`F8!9!M__xu0)oQ~F#jq*(`k~Wt8k@( ztq@ehd8>X&3@l)(0E`W6l%?*I=CA4YoIW(txBQsT$#I+B7#03c9L&omk~%f|(H!jc zQ0f*$8J!^_xW2xw3pjfqQQ%u!TZ39G2-4rUdGlt^2&n2UZfu~J0(3eqE>70tz;4z| z5B4%+Ai&*+TmrD6GxR}(t;RJ#_lwRFb>ZHM5vuY{Ja3+N^1;5UM*EM6ABKB!q~HE| z9Yy4IKx&Tyf=A;Z)F7RMFn~+!4-)l`qfBdGfL@PC^+1FP1#+XroHk$JcuizNULF+T z0jaN+wY9=(XRxxvY7AwM-Xnslvd`DoYp(vJjJZ6z(9rbCZ-39FY`yH=Tf;SM-GjRe zCytm%$P5~#0Bq6en!dge2wQ3NOpK570wpGW9gB#`4G0WF5dR0QVNuR4N_aR(8xlKM z&*wS8Qy&-(J~|>yQ{F3Dy#m@bl>iBM_&+C7FxF2KsRAk(tl0}b=k`0IE?zV{NN=|s z!>+Tu)N&>K8TwgEDg(!VnsycEQFPN5@Sh(9)vr#sxx)Dix(r_)nrgQj{a*x^lz$4| z76T|PRCl|NvJE=Z631O_ZywosA82vj$xj|pSZFeJvW>q+a^y#s*RIO{2AgD~W6HNJ z`m_+i<(3=706QZA@YTUCC8%NqSr1JM+>$3Dl|HTiZJ84(aXFe0*&XI3gfQFxgr5kn zkyrfMN;rpT;Ufi=W(IJ$P_KkRXV~IYsl$Q6LPNPue#gG2eKwD}z*&NN?z5L$Tb;Af zV*?Fen6kuwzw)ASC=TOclem?ep6JdCQQ5huPoxq{w>Um(#!p6k|E_%N>78ec5zqK9 zxKKi=F1xN-^-H#@-8*~v$+q%cI(<5G3me(#eQX;t)=A-8P#qh&!fS@^q@vhfyEVV} z+wt=WN-5yhnc4p}I8c(&snzmL@!J<_Z-b&9X8xm(qi#_#JVLQ8O@)SKjqT7I8zsk3 zV`X|*C~xhtt*rWxDgr18{rIC}ZYiZFW=ppOB^fQ(&;(i}X{-`fkG74?B^v+C4>(@kL#^jOjC1(0IGi;lUT+t~5eyU#6e1iKl`aAf4TFq{B z`m9*R-1bs1t{xk$K;ZVH_i`a2`g-VWT)xF$jOQli={4<+Z=QOd;gQ4bS#5=4gQZCg`rlr1zK znN-)R@bPy0ZTI>2S_K^e#qq~qoFcsT2xqM|PtXeLU_lLTt4uK((SQ~Mn|&&+Y87z> zkKe;~-zR3gE5vyzP9J^AVVUpbsknD;4+3+iW#x+lW7!DX#ltR|8t9?-UvKG)`o?Sj znRNeAyqW6;=J7i_JZs2{L`My_Cmk@!6BV;1O^e_P+ot;6&9PehSV7*$!8^?$Zal1a z+$x8?A&g7mpQ>vb+M-3V_`Ua+ohr2n#iHI2DR5FH5m2aUC@Au-oIGw$$Z$&7Bb=3O z4JTi_p-3>4Te^2SpFu!X?p~XAf-ym!44{J#Hn2@26e{Xl32%qAH z@aOfr{&z*h!?wg7C)3Gp9Y5v831sL7e}A~MU8Ui4L!i+V%cmr#r=EFxTb_DrPKRs5 zjt^r-;UmSV;}@^_5EOp$W$D0y?IY=~yibV}300AVzWPxg%>_gETS7zy^@eNA9FFfU zR^5a`yA9&iB0BZO46H9RG`k&>Mqkv6=VLm`2$tsvkY@e!;d4tkQjcz!u~La%eKj9I zi8=jSjK5SBgG4s#7cz^fzP67swCJL&MPl3kK3QgMKR=$-6A(Lh)T!|K`TEY*H7{^vT20F+_>Feh=+wQn1D^QHVjh22L5=H~vtrdkvL<2^_Y_}Re9k#z zrY*%C{d9TJN3Q5wRe)d?VL->FKeM6b&QNj(N$4|al#w}ktaPV1uErs@&d2cV;z6= z)(NEXU$UmqNjOZNn`-AycgXz2jrr$4jjllESZ9r|&-S#F;@GsDu!L2P_gIdk8Sw#l@Atm4e>YX6 zR>zREKmJ0gF!BYl%5TKN(zasWtE(KsF9#aSnFfEOX*E-b&#O_dDtzBy6KAy3JMPFq z^-VYu-|n+brP>vJiHg}*uv(t4{BW{i|JsBy ze&dBkx-rAG{I_z!u9JM(lQ%G>sJEO1X+y_2IgdXa7Y~ye=T=jd@WQH&M!|iymF{x3 z&F+ljumkJu{AFEEMtnAO9vK^jQI zI4|BzaXc6fx7}gBHD?#yv)!7`3bQVz&9VvScKY+=bqDxgFJqHv1J3+)lMcLZ2Ud~F zRe%21>>cbBIMrQGKON*`nt#V$>-a>9dEBl}OgI9buEgCiC6;N9I{qc9piJ`5PKH7i zJURJirJy=V2>-khs&pQP@6R{PoX-5&FHxy%aMB)M4t)`5$M1kb&0fU(GZ|4z=Fr=J zuKyn%aZ55oy4+9rQJ6_@)>T$Sd zK2%Og8>wk%Xa{*wT~g?|Quls{T`}r*is|d?fBN*P1$=TrH~W=(W*l7Hn^4OHB4MJS zN!tR|32L-5;TsMrNE`5Qabv*R2Zvf1A_@{VHib|oMy$EK1*$xbjf|++{)Q+-q!X+o zhi9We{%nWZ_Ke_z*}|Paxw*a2)lCF;rM&7cXazBV%&l-R%X6sr@*7}at3aHb`GBWz zYr+dz&>k)@r9xa?U7_Gk8|XF(!`A=+5y)y1bK>MlWVV2gPSB=AtO)h}`(obM`1qj9 zDS{)Tn3^1o5A!^)pa73889b#ah&r@axm=~%PmuuI&Vj^o#GQE+*qGW);g2z}usT4x zlL~4>*lrFvJ*~8dP(nU9t!tesp5H-3^^=Rsb2+(Q;S@q-3ox{1kz7SN?C#pAX=o&X zJYKv)Q9j^p!XZW=<^2YVoRV#tzUvppi;_1fY`+67${&aPYKY$xRQG*n2I3*A2s*&B>Zdh{M5RvfA3*oOGcIZGy1^@BodawY3hgb3b`_yaIg9 z4FP~{K(i%5r(g|q@NRQ($d6QccEHw=RPP$`#AzB}IqfEm9I+6jn}LF#O+a?d0=SJV zp^mzG4CT^GDa41Vt*i6(^b~!H74?kGWZZ3edHGXeN3Z#St>h>ZQji*|1VRE#!oj`)yoE3zeNxjiGH{5965uHv`9+{J`6@*r3C5KA;X@ffhJx~R$H2k9 zxsDJ_^h_u*2h}*90b1n+tkN~m(YnRNwC-O?NKBjvfzmk8k*lezdjVLAH^V>AK_3l- zs=jy*NRVrI2V{A<9&&O|NRuh>I=ozGepQ%``JGpBqob$CAtshnPkB2Gf&l`pF~Y3{ z3&ja>akp%tKrbPyaWwepiRZ4~#0Ft?{a~mzrDq!&7M22)oNF2zMR8rfu{$YfEfzng zTb6)7?8eC7hksODt*~+Gm2>yc=6?Urj%2=hPzcW+9e!wRglUO1iI4WEN%0W(;{%k9 zOtDQKsl_1L%raEFP*YXa1nBpN>^x9OYfDq%LpINLwez@ln-uq#@zm7RzRNJ`S6k5U zCi}YW!XIqU-lHGjZ!U1J#@p9Cyq!)^iH81${h1cB9I#VDq@5d%?9625%E@m5 z3gTj7pL_fI+LC0MNmz}4s*}NUUji|I6if(E&EQ!2d9|jdCf%j0z&r)&GV15$<$Z^N zv4Xv`R?Y5P8_2M5SAD2ZM(m3ltnEf#0Rgcv%>i)4Yiw>V>2p(<0m|ACs3bn{FqY#N zhi&4@l`FrYRyZ^z0Xn`rO~uKysAzl`&SQX(6=4$--*v5sgr4b6yw_+6g?fdc9DG1f z5EPjq&xG1VJ)8sHy?5~dx+Eqfc{0%d) z5y~+BnC;DLg(9iVkbA1mx7F8A)`E&cQxFgDDzeUjikL~?fs>JTK>ZckA(C_dP?)~SP`cJuV~l+H8$1{I(@^A7fR zgkeXk12u!B2Ym(R%y4Xu1B{UAV5`wyNK-QoSPmJ<$O&=o?AiN}FrnYsSYSrP#^>kf z#{n&QuVc%96!u=GDjsohZ!c94Mb&gON*qxJXj)}sV1=6{7lDoSTCueZ0J0$4jQ@ z`_ss(%bSBhAw@NmS|w6R-qVnRI`=-Iq5AGfRr00vbtX7bEAdrAt>;-=L9ipJ11bun z0M(GjsjD}?u1=^mQ%l0f*H;zvtabM;P4jPkVKIt?y3cowLny{z=tAxHEloP)&2b8V zoG<|B_CP@P*5}`)peTnFO(2wcBT{h#?7IWJ6sWtpOT!+JCUtilAdK+Xe%lRs34pxn z*kLHJ-Mu?&COVZ(0Oy8QOSDUMW21TQNF*#xbn zzssP`S6c;PYFO=w5N%HYWz&atySbEAwdJv4cJTlKjuQ>z1Z7!Cz+N(fSn6VhD(6WlnDh6b?V6W7t!-_bEQ-u6<`WR8YF&_6JsrF zjg5^nm42MS{C~PT_pqMxZI3qwGlSXoks_m9CQYtQcT+0UOh`3~=psca6-ktClFM#4 zqhutcGIZ6I(M2R>HbwMPberxdp&}!psLtzSpM9P^|DWeM&pDpQAH?tX{eC{5wbuLn zUhA`#!Xj(gu#yK6VR%|M!j}$?K+z3S(va;O24DiNpmrb(zk# z56v%KwD7-kIsJW0)b+b9-|hLrB9QgT^{Y-ze*DCz%hTeC{r% z9>WV}F&pM{c^%7ByI%gpJ%^*e{IX!uq)Gh)0}aRM~znpGNyZ#yx zWH_Q(4#oDoSQSmsv&avb6zHEy=-A$7H#j)xQHx|x&u82GsGM6HY1Vt|=FLh{9ysov zP{o7tx@&0UlNzJ#d6tW886baXm^r~f5yy^0|6CAC2I2`qcN9NQ#};Ks4VkXL91Z*8 z=;Ok$u(WXh*%66XLZwEf>V+-UvsH7izPIC5L0^8VlgSc~wE@+a7uP(tyZf=!EfZ_& zXxgxQGkj*gLy;Z#LmFs5Wi&pc>EuE$L)@e#KaJ1Pn`-u3y+Ndio<>GSY2XIi0`D{; z*4%9yAE_7^ILPaGSLV7^DH`**HF)tpI?l}2*Du<))XIzL6^V?zQeL?5VnXQ38Qcd< zXNBD%i|+N=$$UOR^Ys1u>q8eUz%YW{Fs?D5eRdf5NFwG8DLQ;uMndRlsiU%ao60^I zh;2ZGeg2TFPq)OPam2QXb{~xheem#M0@dPqo~`yIB(3OP%Z#iv29<;Al`(#$A&SMv zj2joF$XGP|>Z*_rY^}7h@$$+bzxuq*$Kgp?gtoH!dK+c{vko~e0bTRI(bb(hefrh- zmtJ2Ii5VMd%7m*c*W@RC`>h}|`8Kui+%BuHCzhW{z0|a@jxTS_tdK}*2o0XIHyte@ zftCutwWD3=`2{<2+a6MclJ|=qRsZoU)MjXUt-7E5vx}~{7%k71%*@PrV(kUn5avx5 zKJ>QH-j{K{UaCh`RZ6^a-~4rP!t27-5q5`UL#E_;r>-5F7;)tr_r`niEu+%)r%c~w z4U~bDtf4@DHBQ}wFk0}O25rK);l{I!fj$7pQ<7j;s@Gq>etki7yI|^+c)+3#fz{uVcfCKNg`&zO2iVg49R_owFhvPA4?LWN%UY(`pajmj>7Z9q+e}r}yA++=pF61gDHMM&p zuEoVo6_{ft-jE(ljpFw*HEOH=F0fiZYQsU*N7_B$FVQBj_fYWrYf~5bRSFCS=4|dJ z&fjZ)SmzL|dD*u|YjbU;YGgSbw#u1)W=6ALpMOHj8x|j+<+1Q7eI3A$CI1F31?2ea z= z@o-B)i^WUx`|#X+0ack~q)EWg9_}?5cFGZu#5DTr-)R0nnV`gizKKR!s=xl8QM^hE z7Todk_m@LUQD;E!krOA}q+zBC0?ml=W@1a&e~XSCmsdl-wIjz!Dkk61S%9sr7sso! z?wlum4o$f@BtaH%g^XvZMtIxpV%T*Gx{P>GfrlPk3ynp}=?Vyxl<epM5UF>|YE` z>ek19B5(hrdhVV%ZVa+~+1Ho#WW&NZ;ZUiFa~_z&b#HTQ%ZD*ZYC+^w_q>E2PnxBu zX!+{v^pTxrQdgfLi%Xfi0P$&~=NR<1zdwzRZw(AjF&dw>3?b%7iKE5x<;&9^a`Drf zu7j~Y#MtdScOHXhab#|7{Z(c?kOd%?CC06EW#h1JI-Yl>%qHYv;Op+$Feu|AN-_sj z{Mc^+r3SEpELCp5Q0S1@;@5Ui?Ieoho{ejB3NBt$*3ht|Q+X@m@7fJc2`x!2Bc+-Y zgy8L*&VwyCF zq25!SRc8(r78Y(fR)@L>M$EC<$%_yWIJe)1ycR9e=FFdOW-$Cd2RxFD?DB+1%>PMF z!}VtrrPcAle(YjI;%OJX?d?DEVu`%aQ)<03o@}u29157{~#Ip~6W z_wIFP9w5^~GsLHHSM0E&&|={Gc%fPkeCL>xcZqY0YR)-0ppXPGM7Y^ ztqz**)k1X^YGs~VRjE=3H9_X6XYCywDGb-^;@$Jk5;qSkrs3_ft><;JwLk3$LtSdR zw8P_=}_NOp$KcrYlpO$sG7fm_D+kb`YZ%B9pqix9BnN zNT8)NXU{dy;U&hD6p}v>KlqEnqEyPd+!*E%V-Q@V=teY)OcMA9rsy*yn82{hd2}ee>xICzMBqqi^TvbGr_fJ;@XV?4k zX3WYt)aP$$86~H`>!MjXAjOS(+pLOM4L3*G`L-LS)zOHg<>fv2kD8h_%hU+N3%u;L zOYxe~Kz=!=aN!r={g&~6toUV7J+s$-?{1@oCtr<mUq(j4XY_6H_p2FGx zvW&j6MBlaX1|l2qGqYj) zRO!7rNS#-)lS|z=STe=cs{#TF&`s8~+qe=`?h>&*?DO#pksEs(z)}~6y4%|oQ5CUs z>*J$Fj$9TAk(vM0)*k5UeBL@!m1^BH+1c5zprSU%;YUT4(SIK&=cu>;Ip&1~y6&e< zmFtRj*^p?|I_Hx}0i&izgC)+ZjwDMeJ9xXk{?g6gL5Q@*~O*d zI_!LHg+3`LWfPK7$9NB5NHrDiLI_5CyazOjf~gWw>Z`Ydy)V>yfjMIq`DY_1GOc7j ze-dzB5ERMgc@R z=Uh(UGJ>%0`FE)(kbq(fccd58Y##`^mDwN5h$?>jomEihUA zp|?(WpX*b6Uw7MRA}!@sv3PHrsazFYsEq6)C5E*InVX!QnE-5z(lf_WUA8Ip9g(++ zp&WhqJema?@?2;G%HHZPFrLm>&!W3x$Ixviz6%{{O=u~M2#}WAmT_?eK<6xSG^`1v3_Z+)jIxt<9KgeP9^_+%dw!rzB;XnYybF1E~UG%&f5CpKmF94<`RgX=`icq zrN2ok#_GGG$u!@KBjjab12Tb2*7A6-NJ*uW=n1jEoH{-%x#pj#-$so?7q&L1bFVs; zW)-uxc0GQ4<`V_K#gI3V&eot!#Duo7Ta|+EU)}5Iq!8GxidS60gv*t%leEVcFK+y8 zpHsqBPGAiWxUz>Ty8CbDEOa}=QPi@ML26pV!O;mC@Q&A60QR_-H<01m(-HvQm64N6 z!&17?!$a%^Xlc0Ul_((2e|)*5>E7G_@~Ta9C_31qcJ$=QEE*FdY<0ojM11KRr}?x& z&W58Qomz@@t47Zz`n**wDl88U<9zlU=((e98 zlVWqqwu-dGNxi@|L?Bzh{%T|yUmJPfRFbm7xENGE{ zy&$1yDZRiz<+)r@Uxg5*!JP0c>+^;%=!T-8%Z&Xzi!QP(lG_65OfU)}E1~1};`Go! zU9pJZCC@zxPXn#PgAPQJsDP=}v32I2Bc!&zzqKr&3Fvyk0#X!2S zq|L`4sMr@;w+6jAiJQu@viCP)QP0;e1)K{xQWE#gDx~%SW;|&iV8=#tF5qci0XXw& zrjsS7q_}gmw(r=HQ#y`lFWg1Pos$_q{`e{Q!$#m?`;Q)WcW36e1eieGiuUc_UqjGa zDY=UVBuWTg>;AZZ|NcDGa!&nhC8Z^l4q$OVpF8K7roT}3E6_L9$2DxIIB+62iz8Q# zihbzaRci*sK5+2h>TTOzn6-tDlS}x3yV|P|8xaOjTt*Or*s}~ zOY&Fb$G?qS1set~|ImpjSsQo~&P^zc}YKQtE0%6DfGKuxg=1A5d7H9Ch?)GC4qj zoX6|Esx)g;aVW~SCidr6<(#YSYEHOBbZ{xc9V);L zi40=mQ_==$Pi9a#a5X|4u{mS^y{c%Nv^P)v;n)9mk-YU9y>Vzg literal 0 HcmV?d00001