From 0e03067fd9aeb4f7db401eb7f1fbe0c362ab2ec3 Mon Sep 17 00:00:00 2001 From: red Date: Sat, 20 Apr 2024 12:59:04 +0200 Subject: [PATCH] Year 2018: Day 05 --- CHANGELOG.md | 4 +++ Cargo.toml | 2 +- NOTES_2018.md | 4 +++ README.md | 2 +- benches/year_2018.rs | 19 +++++++++++- inputs/year_2018/day_05_input | 1 + src/year_2018.rs | 9 ++++++ src/year_2018/day_05.rs | 55 +++++++++++++++++++++++++++++++++++ 8 files changed, 93 insertions(+), 3 deletions(-) create mode 100644 inputs/year_2018/day_05_input create mode 100644 src/year_2018/day_05.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 97baab9..101436c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,10 @@ Of note: - The changelog 2015.5.2 has been rewritten from each commit content. - This file may be amended entirely in the future to adhere to the [GNU Changelog style](https://www.gnu.org/prep/standards/html_node/Style-of-Change-Logs.html#Style-of-Change-Logs) +## [2018.5.1] +### Added +- Solved [exercice for 2018, day 05](src/year_2018/05.rs). + ## [2018.4.1] ### Added - Solved [exercice for 2018, day 04](src/year_2018/04.rs). diff --git a/Cargo.toml b/Cargo.toml index b28f51b..29d89e6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "advent-rs" -version = "2018.4.1" +version = "2018.5.1" edition = "2021" authors = ["Arnaud 'red' Rouyer"] readme = "README.md" diff --git a/NOTES_2018.md b/NOTES_2018.md index 14194b1..f0588b4 100644 --- a/NOTES_2018.md +++ b/NOTES_2018.md @@ -14,3 +14,7 @@ Not much we haven't seen last year. ## Day 04: Repose Record There's something about this "find the most used record" type of exercises that I dislike. + +## Day 05: Alchemical Reduction + +As a programmer, your MUST have used, at least once, the command [`man ascii`](https://man.archlinux.org/man/core/man-pages/ascii.7.en), if only to find the integer value of a specific number. But were you to look specifically at the hexadecimal table, something may have caught your attention: uppercase letters, and their equivalent lowercase values, are all separated by 32 characters. Now, isn't that a nice number that plays VERY WELL with bit masks? Here's a little [playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=d9a88346debfc3c2470c6b1527202f30) to help you! diff --git a/README.md b/README.md index a27bb06..972550d 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ I'm also adding notes that may be useful if you're (like me) discovering Rust: - [2015, complete!](NOTES_2015.md) - [2016, complete!](NOTES_2016.md) - [2017, complete!](NOTES_2017.md) -- [2018, up to day 04](NOTES_2018.md) +- [2018, up to day 05](NOTES_2018.md) # Regarding style rules I'm gonna use a mix of what `cargo fmt` does, with some stuff that feels more natural to me. diff --git a/benches/year_2018.rs b/benches/year_2018.rs index 9713c22..47685bb 100644 --- a/benches/year_2018.rs +++ b/benches/year_2018.rs @@ -2,6 +2,7 @@ use advent_rs::year_2018::day_01; use advent_rs::year_2018::day_02; use advent_rs::year_2018::day_03; use advent_rs::year_2018::day_04; +use advent_rs::year_2018::day_05; use criterion::{black_box, criterion_group, criterion_main, Criterion}; fn year_2018_day_01(c: &mut Criterion) { @@ -64,11 +65,27 @@ fn year_2018_day_04(c: &mut Criterion) { g2018_day_04.finish(); } +fn year_2018_day_05(c: &mut Criterion) { + let input = include_str!("../inputs/year_2018/day_05_input"); + assert_eq!(day_05::day_05_v1(input), 11_298); + assert_eq!(day_05::day_05_v2(input), 5_148); + + let mut g2018_day_05 = c.benchmark_group("year_2018::day_05"); + g2018_day_05.bench_function("year_2018::day_05_v1", |b| { + b.iter(|| day_05::day_05_v1(black_box(input))) + }); + g2018_day_05.bench_function("year_2018::day_05_v2", |b| { + b.iter(|| day_05::day_05_v2(black_box(input))) + }); + g2018_day_05.finish(); +} + criterion_group!( benches, year_2018_day_01, year_2018_day_02, year_2018_day_03, - year_2018_day_04 + year_2018_day_04, + year_2018_day_05 ); criterion_main!(benches); diff --git a/inputs/year_2018/day_05_input b/inputs/year_2018/day_05_input new file mode 100644 index 0000000..66282e8 --- /dev/null +++ b/inputs/year_2018/day_05_input @@ -0,0 +1 @@ +abBAvaDCpPbBlLcsSnNEecZrxXLlRlLUuzCdAmOoSsuUQQqTtRMmrBbqLlqZzQQqhHtbTtBlLTfFOvUuVXxoMaAJQHBbhJjqMDUuoOdVnNvKkmYBbyCcVvjlHhhHLrKBbkRBbBbuUoOBpPRbcCBrQqRRrrGgYWwoOwWqUuQybVvsDlLdcCiIShQqHVWwUnNSsTtMmUuAasXXxxlyYLShSsHHhWIiFEaAlLTBbmMwWteOoHhiIPpfQqRrFPoObBpsIlLiSIiyYoOfmMZzqNnPpDdQwEeOoNWkKtAaTwnEfFrRlXxuUZzIiEvVHThHtVvhOoeoOzZtTNnLSsCoOhHWbBfFwJjwWhHZOozKkcCqQjJchHaAVYyeEtDXxdTQqvVqTtQDdVvQEEeeMmqCfFcvNgGnebBURrXcjJCyYxUvVuaAnNEbBeEeDlgZzGGgGgbBLdurXxRjJwWJjjLlTEetcAfFFdDfpiIPKkaRpPrUoOLloOXxuHyYyYdDhvKkOoVWwigFfGVQqlLAamMQqYyZrRkKzGLmMljnNJLliIgqEeWwsSQNnvEJjUjbBJBbpPRmMuUriIOoaAOounEeNXLlvVTtAiGgQqmMIGgavVkYypPYGgyAhHAsSaaKxCcqQlLzVvZGbBdDWwgAaCcnBmMfKkFVGQqgVKkvUyYwWZzQqaAhHrRuZzbBjJIfGqQGggGgOGyMaAYAayjNnJmSnxXNZVvywWvuUVYsSyYhHHhHuUUuhvmMVzDdeEbQFfqbXxnQqNBMBNleEchHCLnbzZmirRrRwjJkKWIockUuKHJjhqQqVvQQqHhmiIMCkKkKkDdKOBuUJjUukKnNwTCczZfsiISuheEHBbUFzPpFfZzEeciIcCcCCkKFfqDduUnNxXQbBTBbPHhptexXSsLmKkIiMQqlErRZBbeELwWnBbNUuwkKnNWVbBlLWwvVDXKkxJvVjXxdNnaAvoOBbaARuvAayIiYOoVKkuUYUuwQqYTuKkUkKNnbQqBtypkKPaAuUNpPnGgPpDdkKWcDdzZmMChHgcCGCBbOomMcKOoksnNSyzTtZQsSuUqHhYQqdoOAalkJcCoOjKBbyaAYvhHVLIIZzCqQcOozZHhiiVKpPbBwWNnkvDirRpPLYycClzeEZiIILaAIJjJjiqpPHhQlipPWwaAAaIvVGgNvXxVaAnKkNVvnZzvVnIiNsSGYyghHOojByMmYbbBpWAgGawBbzPCcpBbZmMJUcCuDdrRVvVvwWJbWwBjjaAPkSsKwWnNiWuUqBbvNnVgGeLlWwJjEGgkKvVqQIidDNnTtOoAaQIYyBfFbIiSsipPgbiImOoUuMunXxGVvgZztMZzmeiIEbBDdtjJoOIAaiowbBWpPOiIFfSslLjJunwWqIitTQSsnZzNPptTNUfOoFTrREAaeeESXxTtBOznYyNZYyoCHlLhcsJjvGgVoOsSLstTgGoBbOSNkKnlSSsNUunOoPpjJqrRXxTtQyAaGgYqQrRvVltjJYyvVTLGJewWEnNjuDdUkhHKdDvVwWiIyYfnJVvKkjNrRWwhXxHqgoOszZyYbBSiIGrRbBgfFGgGbBzZnOoNtTRtTLcClMmruUZzoOUuQZRrzFBAHhaNWwWAOoaMdDqkeoOOoEfFMDdhWxXMmwHVvDdOoyYRrEKkEXxlDdLeiIIidvCcVDeEoOeowWHDdYysSvVSuUspPpPhJNnCOodDpPcUyMmmMYSsaAfFwWaAdDKsSkuYyUdDuFQqfhLEefFDFfbcCBLFkKfXxldkKQqkoOXxEeKiIEAMghHtTGHhmPbCcBpCcIidwEeWWwFfPpxXYyGXxCGgcBbnNAaAagmikKIMqQIiDEeLlZzSpwWPgNkKKkLrRklLyeuUEYBbKlSsQqToOtjJBIibppPPMmYyiILxXwqQWIlLxCcJjEWHhweXhqwWLlQqQaAqQjJzMmZWZBYyyYbBstTJjHUuUVvuhSdjJFQqYysSfrRbBeEKkDTtPptpPDFfdTYSsytTPohHOpgGbYyfFlLUYyQMmGgEeqXMmxuzAaAiIxXtTDdpjrRuUJPpPCcMmslRhHrxZzHINnzZtTiQPIipqBKyYkuUbmMzWwZeeEESsSshsSkKGgKkuUZzQqTOtToGgneEWwnWAawNGgNtKjIKkLgxXGlgFCcffFGAVTrHCBbBbqQcnTtNuUlLuUaCcMmPpQqtTAYWwtTlEqQcCUtTuepVOovdDOoPLyhlfFzZRmMraAyYKkNpEePUuqQnQqDRrzZkKhmMrZzRxXHkKkxXVvKCNnRDdrBbZqgGQyYzcWZzEejJHNnhwvgFaAfBegGEbGcUJjuCAayYyWwrRYwWjJPplLBHSshbiDdOolLBJjJLlBhHjJbeELXxZEezlJoOKkGgwmMWbBGTWwhHtUhHeEuZyYzSsbBgPpZeEWwbBSoOdZzDTzZpPtKkLljJsqQbBlLWoOMmLlwWVvwDPpuUdxNnxXaANnbBmMyYXcCPpSNnWQqwhSsLPplHxYyXAadDGgIANnaibRjJryVkOonNQpPUuqICcCcioONnOoKJpPvVvxPpCcEeUuXxXbuhhHHUuzXxZUBVZMmfCciIFjJjMcCyYmoOJziIYyjnNIEeiDdGdPpDLZzcCJjlgSsyOqpPSsQkKgGcCWwqyYQYMbdzZXxMmDBkKwWEeqQqNnjmMmMZFfZzfFnNzyJjYwWmMjJhHJSsZzezZpPaPvVpeuUElwWkfFKXxBbvtZzTzZVBbLEbBCcegGjJHhAbyYBOoTtnNXBCcXxAUuafPjJoOaMmeDdEGgzSJjscRrCayYYykecvYyVCEgGmbBMoOKAaAaZzPBbDdNyJjFfYnpHyFfZzYiIOoFfloIzZvVJjePSspERrgNnGlLigGiILNFofFOTtpUzZuPfMmzZjJqQpPtTtTInQCcqxXuUsSmHhMBVvbXWwxrpPRbBqQnMmNukKHhmCLlcMOoUQqqOVvGgoHhQNwWUUuOETtEeTPptDuqccCFfCQQqdmMDdDSsolVvLzZxXrRBXcCxJjqkKZcCzKkQgGPplLwbOonCjJhHWwcNcRrIiCMmeaAEoUuBbOwWMlLbUuewJjWfFeEyYhHEyYJjkKnFAafNMJjmFfBTxUuXoOCcUuSsyiIAaUuKkuUYxFkKBbfBbjaAJwWXUuyXxYybRrXxyYIvVfFEecCMIizZXxXxgMtTRrmjTtwWJrRgbBDduiIUQBbqRrnepPeEEYywWRrWwIBYybvVxXLnNlQsDddDSqAaDcCdFfeaALleHhEhHWwhFfunlLPpNUPSqQspNZFflLAmMgGjJaLloxlLXnIiNCcsSLjYbIiByJlOUCTtEeBPpwWbbBBxUuXuUqejJfFEpxnNAYxXBbJeEmMjQDdqpPQfFquezZEPpvVUusSKJjknNUmMyeEIRrVviaBcCQKkOoBbBbdDqQHfFLmnNMlYyaAGpuUPLlrHhRPpgrRKeJjyYRrkQWwBbqQEuSsSsrROoHMmyYqcgidDIrRGIQqiCMmmMpPwsEeQqUupPgGXxSWhHWuUsSisSIzJoOPmhHKkMTtQGgDdqTzZQDhHWwdfWwFLDdDdHSsqQOQPpGgqofFTtZVDwWQqAHhafepPENnUFfOoulTtLYObOEePpkKoZzBHUXqtTkKQilLfFkKCcIrRHkBbRyYJjvaRrvVyYAVcCYyzZiIrmcEQCCccqvVXxeXvVrzZRiQqKkouBIifFbUOMwWdDtTJjYPpWwNnyXxmTpZzvYtIiTwWTtyqbxXBQqQArZzQEeqRamThHXgJtTUFfFfuOouUsApPcaAZLlKkzWweKkEjvVJCziIRrZpPuTtnNGiIzZgbBTPpLlcCgGNJjkKHhKknkKGgiFaaAQvVIGgXxKkvVoOxmVvVjJBbvFfEZivVIzDSKKkVvdqMXDuUdxmRiiKkIIrhHCcojYyiIJYmMALlAaRAarHhjJRsSryKkYIvLletTTmMipPItELUuGgwyYYysSWAahqQHleXMmAxuSsIiUXVyYUEQlLAacCqBuUbqQuUuUFfQZzTReErYytWNnwlLQWwqHhoOlLRpPrZeEMWwmgGMmRrvVsUuAaVvSSsVvNnJkqQKjvdSsDVQqPWsuUSpPLpPlatTjJOGtTgoAILQqJjdDNngWwdDFfstTSGyYASXqQgGXxxiIYysSfstTSlLUuFZzwTtalLACcWRrDCcLOoPdDZkKTsSDTmzZMxXoODdSstiIEevVtqQPURrupoOvVDdyYZZzkKnWwIgGiYhOowlLDdFsSFNnfuUKkvVGKBbZzkgDdGfFcqvVQkKXygPpGZayYATtHhqQQWwNnXBbtTxqyWsSwBbYWApPthokKOBbYyHIiCcUuTRrCTwWwDdWBbtAeEoynNYqQOaZSZzagGAstTbBlLErRCcePoOJoOjlLplLnNoONnkKxaAXqxXQTtKksfFSUTghHQqFfBNntTEeqoOYLlysuULlPyqQYpvVuqQUSbvBbVnUuSDdrRsEwWeGzZRrgbBorMmQqRSxXSTCFfAymxXMpqBbvBbobDdcCBOojmKkmTtMaVvuUAWwwWMhHvsSFfdcCDiIZzucCKhFfoTtaBbhHAOgEeXrRxTtGTVFfvGgtKUdDukzSsZrrugGUSVvsYOoyRrMmQqFsoOIiPpmyYpwWulUtUufctfFCckKTaAPNnxfFXfFKuUSskMmvyBboOTrRtEeKkmbMhgGHzZmoOJapyYjJxhHCZzpPTVvgGxMAaKknNaoOAZzmMKHhhHkzgGZyYpPWwMUuJjrRvVQquEnAMmaqqQJjOoutTUkKqQrbBWwRinNoOcCIUfFuVviORroaBbAIERreoqQeqQEYJjNnyEeOzZGgxXBtjfjJFJTbFayeEBbYUuFvVcCVkKvGFTthguWdMmpyLlcCYyYNnbTtBYyHlVvszxXZnwWwWNFfiHttfFTlLaACepPIiECKknNPpueEpPMmTcrRCtkKmMuJjxccCaAtTihLifLlFwNnWkaViIcUuQqCvWwdDIvVirRuULlVcCpXqQfFnNxjJxXPDdjhHTtJjJVvvPWwpeynNZRsSCcwWrraAhHKkIiwWRNnaDEeJjdARXxdDnaCcfFXXuUxFuWJjeEnNwzZgGURtTGgMQVQqVvvEeXjJRrxqSWKkweRrEFffFIrAaEzxXvVvuCcHCpUcCtTuuUUwWqFfleELQMctTHhLlgXMAxXSsDyPlxXLCEeerRoZzOEcUuDdpZzUuDsSdAagtTkKSiIxXsgVLlvTeErRtGVvYyVAavzZtJjTGYMCcBbmRrAhHaeqQEJjcCKkJjTtAVIiSsvBuAqQaReErnNkZzAaOorRDdYSGgsyYfLKkXxDdkKlGgyYFaAkJjiIKNjgwWGJRrpPneEhsSBlLbIiITtijJHNnowWAaOQqAaBGgErRMmebUuBnhRrKkWwHsSZzwHhgGekyeEmMOzZowwWSsWToOwBbWmlLPoIfFKQqkdDbBuUBbOoDzZrRvVBbLJbBZGggcChHoTtUuVvOunNYyKkGgdDmMxxiIAzZMmTyYBbAaOoGgfrRFbBgsStTBdDkKWwAaYTtuUDdHdQMmURMXeIiIHhiLPtLQqlBGglaAKkmMLymBbMYbjbtTBCwGgWCctxpPBbXsgOoGSNnBbtTqEpRrPIiGglLeOobxXuUBERwWFfrRGmIimbBmdcCQoOqDMpPBbBKkbxXpPmMUuPpMLQqlkJNFfLlnJsSjcCpMmKCcKkkQqAakVvVTtFAafvpPQQqmbZzBpFfbBEecCIUuwvVXsSuUnNAaiIukKUNAaXxWwSsHhyRrQPSsvVGglLbBHcCheUIilpzZPkKIiLpQXxqUulCmKkDvVARgGBbrkKRrmqhwrMmpuUgzZLRryYiIlvVBVvbTtGUuzjJSXpPxUuIXximHhAaJdaAcCikKIXxBbPpTGgtDOoJfBoJjZVeEnNIiqQlUTtuLClLRbChHchQqcCjtKkTubBUHhoOoORrWwHFfdDAahJHqEeIiGGBbMmdmMgGDUueSeEsEawbIiQqEOcGgCkoOgGKoDdGQqhVvHeEEuUehIqQSsQqRrFaAfrRANFHhYyuUuUDOoPxXbBQwWqyBbYtTpOUfFLGglFfQqDAaAaHQqNnsPpSzZhtTDdQkKzFfZLlJMmUXxcCSjJSsDUMmroOpPZzoOOoHhNnOwUueFfEvIntZzTftTFrRHHVvIihhmDdWwSsBsSVUKkRrtTqQEtTaYyTtAjOGsSaAIhHjZzbBlaLQUufFqjpPCcJdDiIcClALwWmMDdiImvVYSLlTuxXUFfqQmLlSsiIKkLXxZkKgGspPIiSBbzDdiIDbBBbmToOtMuUcXpPomMzZOMmSNnqQMmfFsSsxaGgnNfFAnNXUuirRnCYyOowkKWcCcNjJPEepjJGwGgRrxgtTEMmXfFHhxexHhNnXBLtTAEeacWTFBbqQKkfTTtjJtTtOovVNgGLfFlyyYYXxeEvVRBbndDLHhLlJfFNSNnsJMmLljmMumeENMaAIizcCSsZwWmrVvyYgGoOlVvFZzfhHLROMrCUucCcnNvVYyWwuUfFhHGgOeEoBDdFfUDDdhHrRFfduFfanOCcoopsSTtGOonNgaAMWSmlLzZMwWswokKOISzZsCcrRizZhpPWIbSsBBWZzwWpXeECcQXTtxzZCcqkKkbBANBbnEPgGcqQCxXpFjJEefrRUyYuADdayYlLXxNegGEnfFeKknoLlONgRrFeEfGPZzOoyYaZzRrAjJpTtSdYymRrNneERrXJjNnxfvVzOoZkKMetTEmgpPRrhfcuUgbmMDiYyIyNpQwWiISsOXYyxWRiIxOxXJsYDnDdyYfFNgGnNEepvxXgGniIGOoeEgEVvuUeATtPpPpxiIrRXEwxXrRNnBbWgGBbRAaryRYaAWTRlLrNnwcCdfUuFvVQLmTNXqBbJUuZJjndDNcIiBbCdzZlLsSbLlBaAYyaoOnQqjrqQiXmMxNXxNnEefFnKkIdDuFkKVvDdfUaAnAjJaNJjRxXXGpPKkgFfqQRrxFAaQqNmMvVnMmUufcCWwEwWAhiIHZzaEeSsFzZDeEdfaAOAaoeMmzZFlMmbyYFSsWpeqQRrVviIMmYdDyEEeIFqPpQfFftTihHheEseEqtTgGaAXCeEzZcxQaAcCosSOodDyRrAaZznNLlqQYqAaQfFAafZzLlhHVvyHGglLhmkKyYMmXLJzZjyONnWtTMDpPdzZBbTtQGgzZCcBTRrzZtbqlWjJwBbUHPphGPpgpPpLQqlgJjaAsSGnNpMNnmyFqQUufFRmMiSsdNnqeSdDBblCIiVDPpfFfOonfYyEeFzPOYnNyuNGgJMcXxCeEKkRKkAeeEznNZESoXgycPwkKEeWTIitoRrrRDPpyYddnJLOofFllLAfFvVatTanNfFnzZNdDLuUPpxMmJjEMmOolLSrsSRsbwMSyiqcCEfFMmzZnaAeEFDEcdCqQBqQkBmLltTPgGyYDOHbmMBhNnHdDhCBzxgGYSypPKdiIdDiiIIiqQCcqBACcalLXxXaAzZqVyYvqQmsBbHtThHgGhzZFfSOtTHDhvVpPIMmZbzZBaAHkKhXxJXxtpPTLljVgGBWwgiIGBSvVnhMmHNDGgzSsZdhZIizmUuMmIsSfgcCCLlpIQqiCcfFXeEZrbBRMnNFfKyYkbBmbBuUjlLdDJHhDTttTEsSCcirRIwWRouUOGgpPaArIinpPNkVvKCcwgsSTEetGmlLcCtmMTfFMbxXBnNJJjAakKjWfvVssSSEeJjytTDdPpdwyYQqQhHdDXJjxJMmGwWPpgNnQqjqLZzYydDlxXMKxXSaAdDfEeFtkBbBuUlezZEUxXPoOpuwsStTbhSsUuGgppIzZnNiIUujJaAxXwWdDSsHwTlLoTtzZFfKSskoOTVSsSsLBMmVvDeEsSRrXSrRxXHhsqUuUqtvamMqQuUCyYhHVvKkwWZzFfGgCRGgrNQqnPpmYyPpRzZrDxhHHhFfXJjwWHhvCxXbOoWwBFGxXKOSsXxiILwyYmMWxAaXCeEgGfFsaADdeEgzZcOwMmWmMxXqQWwqmMQyCcpquaAoKkOnNUQPpEJjeAXbPpKkiIxXpPDcCSsdkdDChHZYyoOzWwWwcKNzVvZwWnBxnNsSfRBbrmMUwbBWuKcxXAaTZztCkiIedTtgGvVCmIELKkTtlnNwWeLjJCclQrEeSsBisoOSKhHkIYyYWwwWTtyXEWGgIiTDiIdwzZAaWhBbyYzzZgeEvVGgGpiIrRPoHJjdDhqQeEOZHaASdDsbRruUBuAWwaWLlwYKkyyhTdkKDfaAYyqQFPGuUBbZzZxXzLlcCOMmoXADADdrRvVszIiZSemkOGYEeqQdDpFfLWwlpPzdDNbBBlsATtDduUTtOoifFITglLqQGtlAaKkLXQMWNnrUuuUxXRvVzuUfASkKsElLeSvVsgGTnYLlQiHnhXxluULdgxXGiIRrWwlxblLSpZzkDdKGgPpOoPjICKbBNnqQyYrRWweEIiRrsShYFfzZwOVMmvgGoWFfaZzAWwykGjJgKgGlLHqueEUaAMmEtTmfFfWZzjJwwsSWPHjJhhPprRJjZBbluUhyYLBxhoOALQqlhHQTtUJjUdDtkKTQquiWwIuxXWAZzqQarRaAwzZuiNnaiDdacgGgRrPpcFfbBJjjJrUFfHCchoQqOVvuRNnbwWletTqQEaAjXuiSseEIvsSdDfFsFjJXxIMmibMmBBcPpyiIiILlKCxXfCcdDIcQqSNFiIMQcCqWPEmMVJjkSsKvKkFrRWwaAGgyYyYuUWhHwLlZzinNpFfuEeUjJaAWwVviIRvVqQlLdlLMmjqQQqJIfmMgKsCkCcZmMzKknKkNpPdDZzRrKkDeEJPSSaZzbBFfAaJjFfnNvjgpPGJprhUkVvsSAJjaQpPpPdPpZGgWwzUugzZGEewCcNnTtTtFdLlPqQpyoOCcjJjzZJYcjTtJCvVDBbgGhwnNTrRGgtvVxXUmEegaAFqQSsfwIUpOompmCcMPrIiBtTShpPtmMYfZzjlLAahpmMPiMxTSuZHhlLPnoOaLlANpHtTFHlLhfvVQLlgeoOTtrReEEGqsSQHyRqGgNnGKhHhHkPprReEljJJjWDdwGgZzBHxMQqzZIihrRHJjuUCrzZAaRVIifVvuUcsSCoEeFMsSEoOnNekRVypPYZnNbXxXxuMXxmWrRwjJEeRrXIkuRhHHhBbrUKjTtJFfQqmaAwsSBNnbJjnNFdDfFpHuSsUJjtsCKkIuiIHbthHThqQqQYyKkZTtkKtcynNYUzqQkKZWwxUbBuQqcKkCoMtTwJjDdCjWoOlLwWrwWqgGQZfYySsWTaAOOoIiHhobmQqMEtdDtTiIuUZzTuBbqJhHjhuUcYyCHqeEQGgQqRrrRUuOqQonZLlLZkKzSswWtOoWUrkOozZoyYORrfTtIrRkOouAIxXkKxWbBVEKDdmMYLlyqQkOtTtTjpcCSXeEIjJsHhUzdmMDZDdyYslLSOdrRMtTmDwWNGgOoKkFOofLlNgqRrQFfuQqUGQFfLAaCclqqQMmGgOoDdCcYxolStTseNnEdDhHVGnNPpgvNpPnLLvVlYBbOolLygQqDvVHhIicjJCwnwOosLnNlFefFdaADWoOPvVpZzRrzZrYyRsSdCDAaDducCoOUJjKkAwWaJFfeDdErQumNPCpUfFpPuROorzKNnkZPaAXxKqeFFfflLEbBVZjJFJjfPHhhdDuyYsqzyhXSAahHmAFfLOoWwlQqCcQZoVYyvOhHzEequmMXGRoaipbiIQrvVRqrRdvRTTtHhCmMUudDKfFMmpPpqRhRpPWbBwKocCjFfJtTDvlLVchHNnEnIiIiGKkkuPpUzZKeEPaAptlVvOoLoOFflqQLdHlLOosSWFvMmkKGIhmMHiggGuLnNVkKmJvFfVjhHMMmSWwkRhweEygHhAzYyeEZHhsSQqaOgwWGgGtTiIJxcsLlSpQNnKkYymaANnPpMqYndDNiIyPCIiPpzZXyRrxlOozZuUXyuUYcwvyYXgKgGkGuUnDiIctTCcAaCsSpPsjJSLAvVKkUUAaukiIKuidDFMPCNnzjEpPesSJHhZjJEgFWyfjjJiIJbLlWnpPNCffFFiIcIEeQqzZooOOilysSYDXOoxgluJMmjOMDdmuOJjaXxjuUeEAaGgJdDvsKkSXgFKVvkfkKWwYyLfpvVdUuBbDPHhRuMZzmUdkKGgDyMmYktTKrFGgAgGaIiNlLNnnrAkKQNXsStTynNYwWYxXDRaAwoSsxlLXjnNJzZkKDersDQqKkdOvUuQtMmXxJjRBIibuXxTnJiIqQjjJweMsiPYRrywWdfFcCgGQqxeZZulLUFwWtvVaAcYQrRZzlaALQqhHkKsSlLMmMkjkKJeEtzPzuNnRcCdCkSjapfFPzZYyAtOKkmMoVveEOoTAansYxXbgGiRztrRDdrRTwlJjLPsSZzpKkMPCkKccEesSCmkKnNaDjaAJdPpxXPHHhGOdxXliIdDLpjJPpuUPfniqKxXkTIitsSZzQFdsSgGZzEiAapnNtlLlLQcCgMmGtAaIaqQAzZawCGgcPpWHhAFfiTtidDgCcGOolYyvePpUNEeMmngGfFhzAaFfGqQgOwERrWwRrMmYyOCcDsYyIuuUuUUYyQqHcPCcfFIGhkKqBMaHjJBbWDwWdoOdsSDlLNmsdLTVvtivVSsOusSJjUFBAadbbAaNfFeLlEgjzdRLvVwXxKwWkzZvsnNwWSZzvvViIDbBbBipPxXCceqQJKSKksCUtTrqfFEeZzEetTVvLcCllGEeMpPnFkKfPAagtTQTDdfmiIQyvVSaGgTUuNIcVvCiITtDdpPQDdMcmMcCCEvVtxXOoUuLlQqTpPoPpOpBRrnNkwPpxLTiTtIiPpItdDgNnGwCcStCwWcOKRsXxrEeRSXxBXPsSMkKvVpzLGDbBGXxgdhzsEerRPRWsoOSNwWEhHeMfdDFmGfFhHCfFOFfoOuSsgOkKhZiIzWweEzFuUfcuUCAMmakWRraDdAwcCFDdfnNxNeUuJjmMsSeQFfqvVvsSKkXxyMmMmtTPoOKVvYcCPpwfjJFFfmwWkzpPaADuAKkOoYrRymavXuAaUzuUZxIbBuUoOhRIirHgrcTWojryYDXyYTgGtPpAoSsoQCcgpPsbBSbBppTFfLlCAOQqoLlPpfFrRaEeAsSlLcdCaADuUTEeTtVvtqQtwWuiIoODdGmiIhuDJjnlLNmMTpiIRjJBQqTtbGQqGgBDKkfyAKkIBbXnNxwFfIiMmwfwAyYbESseFfBoBlLbOLEeCiRhHUKkHyYhCceEGxXggGNnucCKkRrhHnhCCEeIiAaUuIirRchdlLOHjJHhHhGNWwxaPppPKkaEeFfvmMVbKMlLgGNaqfQERvVrLROorlwgzZIInXIlbPpqQBOEkKeWwAZtTpPRrzZhoruUPLnNlgGLFIiAaBJOojxmzwWSsBSsJOZbEeyYBGgPVhiIHrlLYEeyXnfAzyYnNrxjJXfIiKifFIAaRrkRroOzZFGIAqQlLaKdDkjJoOiaiItpPUaAuTifFIsSUNbctwqQHhWLyYIIiuUIiildJjYyeBbOoXlLucfFyPpkKkpEjaAJdLoOBcBbSAkKaMlwXxWRkKtTNnGgkvVWuUwKGzMmGgZQqlLQQqMmEeKkYKkEVmWwNnszziIZMoiIKwdOOooALlgTkcYopPAZzPEeUZoOvYfFyrqQDdxXdDQzZgGCJjlrRLZGgdCcEDdrrRQqqQqpPSsLlBfMmFKkSsICbBcpPkeVvEOoQqWwbBXHcChxzZBbDFfCKkcHhLIilNJCEWhHweUhnNVQgMmGvVMmRQoBjHlLhUuPFzZfYybWHkAageBbyYdKkHEoOehDGgLfOHoORrMryYIithsaZzdkKHMmBbZzFfoqQOFskAaFNnfKceXxyYEmOwJjURriIBWwbovsqpPbBRrQJjEehHvGgvwQqWVEJmhovVsPvNwWnNnLNnRrZLlWRYjYyJRrynmjsSdXFDfFuUjJwWfQYTtJfFjQqyLuFdXxDQGgzZwCcRrcuUGnNHwlLWcDGqQdDmhHMFHbeEBkKZzyTtrPpSxXKksRosSqMMmmCHovpZziIKktyYTPVaAHqlaAqQNnSRrsJJFfiIaAuUjCcJRugGRxWwVVRTAgZxvMmVtQqxXQlcCLNFyyYTtqQIitTCBbKkQIioZuUeEoQAaqGgsSSNnRrsVkKSKEedUuqxADdyzYCKkkmMKLloueDdhtTRroOmVvvcHhklLhHuLFfXsjJgGFfShHRjJhrRHcCrNngfqQLlmJjCcnNrgXXxRHBUMfFmSbBsuIogZPNEleoOELTsFfivVgynNRrYGRfkGgGtTgKpJJjjPzeEZFFbBUNnufpycCMmYhjAoOawWJoQqTNntHLXHhxlNnEehUyCcwWkcJYDdaAntTeEjTtJNQqWgFVvfTcCItTYyGgKnNgImTtzwWZrRZzSrpPRNkGgwWKBbmLlMxoOJnvEeyYoOCclLGgMmNHhWwGEoOGgzZHhxXsSIjSstTcWwBysgGSJooBbOAGJtlLCnvppUulHFklLEeXKkvVPuhHUdRrOHuonHfZbByYOoEeCccCLrJjRlzQIimxPpXUuNpPLldDkkKiIgwWGKnzlLGZzHhhGTcAaCtfFgHHEBbebBrRhWwVtTqyACcdDOsSybBYocxXkKCQqtTTtMmIakKerRtyYTEQqjJNFOoORVvxXvVwWoAjJaODddAaDYYKPpiIeoOyYOWwoEkTCmYoQwWlBbxWwZfFfFQqxXoOxaAZuIirRDdeaATtEgGEeNnRxilyYYsrIsGgtoOTqBWwbOPpoQyUpPuBbvVYwWTpPtSHhxXxXOljMAvzXFfEZtHhzZqSsQcbNgHhGnKVHNKQqkpPtCNOjJojJJwjtTcCSfFaAsrNcCPPpDdpFfwBbpkcdDCHhXHBVvbMmnNxkfFxGgXImOrMoOiwkKZlAfoOCkpPHhbuUBKQHiIhEsYmMYyqHZzSyYmNnFDdeECcYzZXxyEeMmqvzhHFfodDXxrRBgGEDhTvLmMlVGYygtLeUuZPpNnVgGvhHgJXfBLCcwRrrRMtTLlLFfliIMmCczrReEZXXEvVZzOoetTUuMmZzuOdDoVvbBPpxIlviVvgxXyUufFmMKkJtQRzZTRIiQwoOLwiIWxUOmeEMSsrRokQWwqVEIDFZiIzyYMmkKcOoCdDfSslJjgGPqQpwWEeVMmvFGgnNUumqQLOoPpDdAtTBbmuUjJLyYnNIiDOLlhHNjJywRrWYGgngfFpuWwRyYcYyKPpBUBbdDAaQqUuumMhDdpPHggqQKkQqKkkKSQNuUDgvViIjXfFbIiaAfvucmMCxpPXfvEexXDdXvVbcnUuulLyYvVVvNnAaUgSxXsSTkKtTDHNnfFbYyvxyOMvZzVCSsKkLGgKXlLSsYTGgqQUHhutrRruqXxjJPSVTtyrRQkKqYnkKPpNvXXeEEeSseyYvVEWTtwBbEevVtTekKEAaQqwqQdDvzOWzkKZRKAUxeMWbSsBmwPpjxXJXxXxKksSvbQsWwWbetfFMKkIEeABsBFfPOoyhSsHYPpyqQYeWwEdDBHOQqoIPpiGgCjJLlmVpPvMVvyYLzZxuMedDMmgGTlLFfTrROVzOoctTkKCGbuUEexvitfFZzTuUVQqHKuoKkvmzUuAwWvVaWgGKbBzGgxDdXOoZzvtlhdDVplDcXxSNneLVwWvnkfGEegGviIVvzZwWYxIbqQXIiLYyIncCmMQhpPHAwYrRIinTtvVNqUhHhcKkrbBDdfCsmSbKkBcdDCscJjjiIIYycCUuqQXzZxGJCctTjyYehkojJOvAaVHhAfFaEekSsLPplvVTkKaAIQNlLmMqDtfZzuOopiNOWiOmMuUoIDtTdyfSsNnvEoOGgIOoiiZPpGzZgEqLvagGdDbBvVAzZJjwWyYaaAXfFFfxFfuUuEpPTgGLlRLliEeIrVvIiaDhXxHdJjAoHtTbBgGEHCxXfFlLyYcYyuUthHkGpPuvVmMiIUkYnMkKEoOgGeNnBNNcWKkwqQIrARfFpDdiIMmpFfPmMMXtmMvpeEPVCAUdDNnLlwkrRKJStTFfsafdUuXxTtNnbjJhHvVgGZCjUuDUuaAdvzZVjaPlthZwWzZaAzZLjUuuNXDNndXEeQuUqApPGhHpDdQqEoOGVvgLlePpYyiIaCcApJDdjgAaYyPpdOmrOQtTXxIimfFUIiaRrAihHIGMTRxXrtIiTtmfFWwTnNteZMmZsSzNnuUrcCRMmXMXxQwWNnZzDdLlpxyYXyNnAaTtJjJOXxortkkrRTvVadcCDAWwrRMeEuUrRtKkcqQCkoOiIiItTDHhEWwEeRravVNuvVvVXxyYUWzZjxLnqQEAaQJEZzUuNneLnHKAoTkXxLlgGKtasSoOgGAbBBpTIiOtDEeIbBiRRBiIbRJHhHhqCzZoeEnNOoOeEeSsEkSllKkLqQRrRXtTWiIwxlLrLEicnZzNOpPoCVBbFAahGhfFkdkPxXpPWWysfIFfTtsSjJPyfmMfYyFPfeGUVOwWDkdbXxzZBJxXKkjHgGhEeHwWDnNvzZYSbBtTfVVvrDdRKUukTmMlpPLZMmqQoOztIilnGTtrRgWnNYoBbGUJjhHugOAoAVvgGaACPqQpQGjyTttJFfjJjVqQdDvoHhOMmrLCeJjBQJfFCcIdQKuUZzkHhrEwpPLwNnWxlShHbAaAtixDVvxOonNXxnNUuIiPpIstTSiiIWwMaTFftAJjunNwWUJdiYSshbXxBwWySsYrhwXpPxgUdDILCcpJjPQkKqSRrcCsSsTQqtCzoOBHYyvVADgGdQdhHBbDEAaeFfBbGalLZEjJcaAmMPxSeYzxaKjJkAXqMJlLJjZlEjOKkxXCcohHtEbBeTWjJoOaWwziIUFyYHhdDYxXmMwWOZRrSszVmFXrjfvoOJjkEtTyzZYwjvVEuUbBoRrehIiLBbvVzZziIZoNUurRUfFyatSnNSsTUXwHFbrRJFfZzQkKEeqsSKRrrgGRRcCrbTtBkWvqoSasqcLlpPCsYylLhqgGHHSshhQHhGgXalLKkJsSzZLlxjLrRnNDXxqkTtKxSsfzMmZsSFPUaiBbpPNFfhsJyVvZsSMTtaAcCwlLbFfBbBWXuiuoHOgiIMmSsGoSnNnNdDsOoYczfFZCZPpYFeEihHfBVCczZDdOovbTDdtdGTtgmCSVvscdWJXPpEofzsSZFsSrwymMQqbGgwjJjJLiIwWMKkmfXsSxgGpbLgasTtSLRrlLlXnNEfaAKkzZyIiwWvuObBoOoToDdZzGNnIigGpPgGlLgKkEsfRtKjenNdlLxQKkifFWKvkvhHVUAXGgKkCDdIikhHKCtnuTtfXxFdNWCaBsHhdRZyeAadakKnNaGVPhHJMBgGfoaETIiiGgjmqQjUVvxXVpPlnmMNnMmwpKkFfPzzsFfbHMmhHFTjJFhHshHJwWTZzNsSngXCglLRYyrNyvGDdUQhjJVwWuHypPUXxmMgbBXxRrGZzwCEecwcYRrXxlrRPhMeEmXxHdDtYaAwJBmVDdMmiYGSsEBeEbjjApdDesSyYEokiIKJRQOmbBPcugPDSsdpGUmhzYGeEaAgOoyOeSIhDaAcrkKkoOsSHeEhLWzZwlPOmaCpPcFdDfLljiIPGgpJMxLlnYNndDCcRcXxlfgGYabOgFUuWXfFfFFgGiyAymMLlYOHIiNnsymLGNkYyKnsGgqPBhmMYyHUuqTtaSsNnegWrRcCwfPuWASlsSqtTULVsLyYlUTtGnmMZzMAgGKkCcuzleELYtTmOjAlleELwWLTPjWsjhHyYFwWGgppwWkstTrRRCcKkrcCSmMKhdyyYfFMmfdAaQZpvZzjRryNnrfFOvVvYQqyVnmHOaFAafPaAuUpAZzkiIKkIiykWPpUJEjJgFfgGWwGsGjGgIisjJeEeLDdQqfFlkQnNEyYKCcCLIozZOtXXgGxcmGzXRptCGSvVIizZdDDdyMwWcCepPxuCcZcCFNSDKDxLdDlXdsSvVsSoOpjmsQnNqrIidDzZyvhwtTFxhHsDdTtGMmXSsoyJaAjcPZqIiKNvVjIcrUiaBbwIdDVtTvXxLlMmiWHhAObBoHhNjDdAJjAajmMsjJCcSIiJHjbBWMmeEIiTtlLsSwJjyVCcbFLRrnNiDdbButdDvVYyRPwWJjpBKcNnCAahPgDjJdkKGRuhPfFYypDdHeyYEUpKHhfFqQbzZZVvBtFHdoJjAIinNEPprkaAKAWwamMReZGgVvvuUVHhzZBbpLlByJgONsWwnOoCwTGlsSDdFfSsMcuUCbBwWkzZwiuiIsSsSOZzpPMmJfHQGtNnTCwyYzUkcCxgIimoOgGPZlcxirQDjgmMsSGuUbBeEumajRrJFMRWcgGlOlLnnrgPAeSsEZCnEzMBAdmEeiGhzKBbeoOweEZOeUuYPmioOIHYsXQqAaKiIsCxXcCcdNxXjsStygiMaEebBAmeEFfkKIMjzUujJtTMmYaILqQaAlaSkGdDgkMmKdDKVUfEIcCcCbRIirtCcGgyYJjrRfriyYLgGlIJjdDRxtybBbZzCoIuJEzZwlLGgEoqBoMmTUmDdMuoODfFMmIiEesUuPWwpSdoOfNnTZNnefFEztqbBVrXxqVziozZOFlLfwWIFfdVOovDyDxNYuPprfmMSIhHrRJzZjmMTtNnrTbBvVtzkIDCpPUuJIijhHJRrgGsUBmMFptTrRZuCcnNJfqiLiICzZcEelccCADVvnNdkJTNnqPLlveEloOWwqQSsLUuVbBYfqQqebtTGggrRfKkFkKeIiEAaGRYyHwJjxWwWwyobrRrWxXPpwRSsgGzRxkKQqNeIiEeEzAptKkCcVvwKNnkWjJHOoFfwWmZZzbbBjvVgihkzZuUaAKRglLGoAcbwauUUuAqJwRrWjQvKtTIHhqIgGNDCtThJZzjHCcpXqDxXDdnoUREwlLWhzZDdfFZzNpPKgGMQqlPjfVvLlFFNndBCIicbHwWhZzxXVliILRrLhHCOooOCMfXLlQqxIGpPABwjJoTlLkfFMmPOosSOwnpOoPwhOotYyfFljQXxDdjfFJdyHhCAjqYXxrHkKhsnyaiIQGgJkcCOoeaAmMEpPOTqQtXiCuUclDAkBVvzZbuwWOZKkovzZTXbBikpPRsGrRWTtdDxmgGllLqrLJjKrRRrxXxLWgDmREuHhUZzGzELwWwTPpkUWwmMurRPEsSBDdLSItHLpnNbBPaAcCIiLMXUtVkKvPzUuaAUuEkfFqBbhaAHQVyAamMyYNnQdBagGTVmkFfKKkEtTlEerRiBbuUhTLlNPTrpNKQqRrJPpjWNnpPwkwWBbEYZrRstTSzBbOovuayYAsRBjSoOFkDdmHHhhtxoKkOXxrRfFXgDdspPyYgGUsjJSWgqjYKaAViIeVIFlLjJAzZqQgroOLlHXcCDeESxXQqdwHhqEeQcLlWwyfFHhlMmUuLHhlsZzbYjJycfHhFCXxfJNLzZOPwnQDVwUYyBzRrZbhHYleVvGRrkusdDdDlLmMyfSEorbBRXxuUzQxXVpyYJMJjnmMNdDNnfFVTtxdDdZPddDZWwbYyRrDdVvBzlLLlfViTtGgJObBgGvJcLcDdkkwIcCdDwWifvVFQYkKkBgGBbTpJjWwTtlLpPmNnZwWzSTBbTtQrRIbYyQOHusSUNnpMmaAkKPlLKeEkIiWwFrvVRfkKGlLjJMOHFDbQqBCcdIiIXxifhobGFIisSfXiIxTBWwwyFfYWbGgDUuhlLHdMmmMjLKEwagGwWSgPpUuEeeEyYIiyYvYyBSWCcwXxxAaXJjUbQeHhEPpCKkeEWqQiCcaGgrRiqQIAIwikeRMuXFfxUXeHhdCjJcyKqQkYyhHxXUqQumDsSQqdjdGgDGEUuoOjQVvuUpNLhoOrRpagRrjpPIiqaAAASsaaOoLlGggGmdoxoKgCxXAnvYgxNnzyWDdwYXTDMcCxXmdtFfVNcCmAIrRkxXKXdDqxXRKNnOoghLlqQfVbBzHEMwWMaAhDoOdQutTUBbRGaAadDQqzhlLYaAyuUpJXxWgqzLVJGMmYyQwWyDdBbYzrFfRbBKSsIHpPhslIiLRZzjJuYPNkGgWXTtHIiyZkDdWwkUwWjLlJkXIZxrsiIFsnKktFfTtTNjJjQqeFfqQdlYqQyzeFfadoOsUuPRrqQrbsSFFfflLsvBJnhHRpCQdfFDhBIibKMmkapftbBGgzZTlrfEZrzZGULEeBbOPpoilLIlwWWhpywWPtBzgGZnNYyUNtDdYyYYyGgJQqrigVvGQHhGgtEemIXxigXuvVUjUSsAaZHhzfFdgGTtBtTrKkXCKYHuUAacHaAHJuUueoUPeEUufFpCcuUEeuOEUVvueZrvjhHJQqVGJVLSPlLFfamAVeEIigyYHUcaAyjJiIVxXJXsSGgpPHwYqmVWwPZjJtiIiIfUmMIBNmMmPpckUpPuEoOnNwmnoOFUuSOxuDbiIBdUZXcCQqQPkzZdPDdHnnrRkvCcdcPwWljRphHvVbBIeENAqsGjxXqeqQRPpTtkYCcAakKoxgQqhAaHpLMmRyRrVUDoRjJKkzcYkUdDZzMmuUwsHhiIiIJjlznLlyEDbBnLPpXLrgJjOKryvKILlbeOwnNBldUpbTZzDoOoTQcCOtToOhIPpidDHhmMnzZZzHhDDtTdDLTmJjcbOoRtlOUWwPtTlLyYMmXDFfJGkPpoaQbaEejsRWwMmYInNiTtyKkanMTUJKbQaOoPpcZxIbBbBiXRDdzkdDBbKvLPpgGaqFVtTGiMmqQfnvtTvGaUuzQRwtTAvmnNSMmcCDuFqOopPQfaARIpEhZzZzrRDUuJjdHBHGiINshIiXxHrxnEfFKDXwzsSpYjJrHvVfFqATkSzZsVvKtlLidDuPpUIUuEcTtsSxXORpnFhMPsuiESKiIfblSslLweZzEwWbfFBbYdDTkInxXIiWBbXsxfnNNnfFFcCdDeVSsAyYHzGgsQCcHLpJxXpbmrNcCZzlCVAkOeEdDGYebpPZzQHhqeoqQjJOwgPpYHhqiLlaAIQCsKDduvsSsUzDdMvuAWzDdlLyJjwCHAjoOZIulLCcyMbIiEBEGhHaAaPKkDHyDrRdhHjJbdDLlWwBfaAfRrFqMmWwgGxXhHsdeEDwWJzZjFfwmctRrUuTrjggGYhGYyHkKWElDCmOQPgiKnvtTQSSLlfmlNvVuNQqwRbJoOJjJsSKRrBbFlPSiyqHuUPYypJjhtcWwCPpaQzZYfzZswnMwuvVlXyYpbBQfCSFNXxPFfHzeEZVRrWwvhcKZzkkeIFfoXQqipbBdIvfDdFVgRrMmviIjKkZzJMmEtUuIhhNnHMmHhJgGkucCPodEpyYrLqQBbTtJYgSUIYEeyEMppTiICZBbIsSVntgFalUzZuckmLxuopdDBDEaHreEkjJTtKnSsOSsNnohHJkKXxoAjJaxXWbRdDGLuUeTVGgYqqQlLYyQMHvjJGwpNnLlmPYypTyYSsWwBXxEJIsNpPnlfQkKCDdDbBvLHvVeeEMmzZitnMmVvrrfFRnaAiVJtYyUnrxiIXwhxXHajJBCMxXIiWwZQqXoZCInWoPpYLljtbFfiIzYySNnhYZMtJeUjDTtdqxUiImjldIilLDLJgCINTLFhwlZZzzfxwwCjJaHhFnqhnMcBbCdesSXSsxHhEDrRmAKHhkPQJdFfDRxkNoquuLoOeEgKYyOLvkvVZaIRDdyixPpSsXvVXTvVXIfFFUVvQqclEFfxOUOMmovVudkzZApLlPuUyweEmMHCzZBbcoHhomzoOZkKJjMSsMubBMmTwCUXDdwoboagGUuDElPpxXhHbrRJjJfQpWbzMmZyYBGhIZtTOoEgSiIsBGLlFfLDdJAEeQqhDdxmiOsFOeEsSuUxwWnNXdDWeEdUlGBFgXAtDrPzgMmGeLlEetrRZzmMSsTqMmzdFtbAqKNGjOCqQYyuXxQAcsFQqglLoCCcfFfLlyYPHWwWhksNnuXxUEyYPpPMFDHAmMahSwImHWPpKkBHhbuomlLURnNfEHoRwgGgWwSsWwHhGAKwWjJkyvyYVQZgYyLXVvEVLLAixYaACRrkXthnciBefFHhNnNnwXvoHZYyiejJVKWwrNnKoYNOzPRryCcDdCeEXiVvgGIkEexXlLQyYKwIcCThHvLsSlwzZatTGtTGgNdoStTmvVWUwZUGvkKuUVgCcKkaAMXmiIwWbBLBDnNgmLllJjaFXsSNnxIYytotVVocPzraXQqCLSDNwibBpiUurZMmRxjJFfpPZHhMmEaHfYIrRUnNbBucCiMBbNlAaJRWwrjtWIiIqQCvVvVfFvzZVQKdDPuUHVfiWwXxIBhjJzhKkaOdIpgCKkcSsXQHUTNnuUtRndWMwzZVxXOwboOQWyYbDRbGkGBbwYyWqLlJRrqQjDZbBTtvswuaAkGIxBbsTwvVWNnLwXjxUyHpPhNtTnfCJpsPiRGrIiRZjNnJvVOLlCcOSlLsVvCJjxhHVvoOZJIDnwWNQVQqbSUSsVfBhHrQAaJHCchPgJjGEVrrIVvwWdCcSWfgGJjVfFdJlmMLXxyYcFlLEJjJVvJHgLnuNmUFZztDhsSrSsGUuXbBjXrRxpKCckNhmgSwsSXxStTJJqqQQjBwiIWVveEfFZRmMruUYyLlaZzEeUYyjOnNhnNHEqkYPpLTtOolbBbBEfFBbZvVvVXwEemmCiNzoOZzZBcSsSjJYIlLhvbBSHaTcnULkbBXxbWVvCyEfGVvVhnrXotTOmVvNIravVxdjJAaYRrskYvVotVvdDHPpiENDdBmnNpiOgGontWwYgGZzygqyYuUQGRjJQSZwsOoIiIYaJoOlLSsjAkaAKfWAawmYyMtTXAJDdBSHYyXlRrzrRulRHtgSHqbESsVvyYVvCcnNlYyOjRPeqQEsauUxCcwmrUlvOGfFTtMiQqIRHzZvuUVzvJjluUfFLrRkoXufFmKkMUYEeyPIiMhHycCyRrYAcXxFfCFfOvVoCpPccXxCBxPZuUQqzRQqrXkUdoAaOtTiIlCsWNFJmqyIAJuUkQBgdDGdDpNnHhPdgGCcFwgbteERrXxgGQqZqOhiCKklbrRBRZzwYyUudDvVWbdDcCfuNTFfMcCmMsiIrinLEOolLkESsehEeRbYvfrfVvURrZzAAyMmcOyYDMiIgGQbBFfsnVjJvAurRFLeNijDJAappcLcClwWOsVMrIMGKkGgczZHATvPpVtahcWKdCtwBhbZbPweXxEWdDFHLvfFBbFPFmUuRvVMmxlLJjDXZeEzZzoOqizYZzyZwnNiIYKkyOzNWwhHKkBsJjoOLlsdDLkrpPegZYacyCcRrxXYXBdIitJnNmPpSqUVlVzOaqQHhdQqDRoORJEejfFrQoOAaQcyYCRupPCKvVkXUaqQjFcqQXVgGGgeEKUukoEbsSPpzZLpALluUHWwWwnHMVdDXlaMmopCcoFFjgsjYyzXXNfwEeDtTQqIiRrSslGgVvFtWXLlqiIxXJjPfFpGELluUgGJtzZAaVvPiKMmetTqsyHhYYZulLwKIiLlwBJjoLpzhHqQWqKVvocCORrYEYwWSiIqeEkKhcwfPhTtEjJLllTUutTgjkiGQUubnFfrGgKepJlJjfLFzzxInuUSqaIiAQaAIcxSsXVsSEtYOCcoeDjwXxMtBnOhTnNpPqKkscCVcbSYyMiMIAkZSWwMJUlLGeHhlyClLjpPJsrXYEeyzPHYBIivQBHTZzhZzLKkJjaxaXAvgkByPpYmMbnNozZSspCtnSyCqQkKzZiGxXCiIbpqrdbBDRJjEJRuaalTtLFfAsSdDtoTtnNOrZzZjaljNoOnmHMmKfFkubQlqpFKkAnNmqvFWldpoeEOPSnNrYChHVvJJhLqJzjJWZlLZvVSuUzZOYnNVvyhHBbwehaAvVmQnoJjVZrRzaAMmGusgIHhXrgxedDElfFFfekKAzZBVvbEiIekvVUuRDWFxXfjJwSfFsCzNlLswAaDjenNgMmGrRfyVxlbBDdbfeEFuGUugoWJIiUuPuEayYCcJjNAqoFdDfXZzJuJjUjoOMlLPJjtTpyYwcfYJbBAeuBbUEWsweEWzCxxXkKfvVlvVLLihHiIutbBuanCXtuIowlaiIMmmWkeBZIhHiRZeRhHrJxhFfLTtEeTYytdHvAaubzZeEZzBASZHDNjJvZzdVvIiOcCHhohUirnNRcCFhOJhOlLlLVvcHhNnDduJdiIbBXwrRWwBQAaAjJwWpbZrODdgrRrRrRXjLliWjGgJsooYSiDdMmQIiyYpLxVMrRysQyLlZaaAhHANCBHSsLlYyYAaphHPbBNwWSUgWjHhgEeLtytOoIyYNDdkspFfeEknvNnAUEeEQqaMmULlqFJnNagGAohpzrOHhxXSHhsNUVfPJQNneTYyxgkJjNSOhfSsfTtwVvWBLlJQbxXPpzFtUfisSWgirXgWwYyGbvVPpPVvpPdrrbnNEwnfiYyNuUwVvKSfAaEeDxXofFIJmMjJjkWcRnjqbHlLvVhLfFOobqpbBDdOmMfNjOKkPrRpxjsGrUYGgejngFtFfSybTdrXCpsqbAaKBbJkCSsXhMomMOmwWHgGGtTtgGdSphMmfGcGNguUwWGaOVvFfFZLCQxcqTXkKDdxAwWmMzhlSFMllLLUcDrSgEAJjaVlEeThzZHtfPAyYYTffFjofzZMmZzTtkBbVubnBYdQJadYzSQxgeEzNEgMzHiAhVuBbVvUNnDdnsxXCuUwxcgRrKiqQmmCcWWwwdbNnBIrRNnHDvVdTjJmzxCAaMFcxXCNfyKhHoXEvyYVUueOoFfXzZkFfHwddOoORLAWwalORrYoiwkTwZZzzWJjZHhbBCcMlBLhHyowshHSEetAatxJjESWvfuEQSsJjJORGuzZTIithluUGtoRqQrOTDVuJWwiQhWNnwWiaAIjGralLARrRgGQqPqQyIifciGSsgGgteRMmrENXxGttRrGPpEeMhHwWgnNMmGNnJzZiSsEfFZVvJBukFsxTnFJjeEWFAmpIVDdvDXhtTJjnmIiSyTtHhRrYtyJxzZIzYaahHuUZXuUzXyohFrBbQqkbVbBJXzvVZeudLehHEKMmKBbYUClaxQeEqseOoJqoOQmziIfnywgZzjJjJPTFlLlLJcrkvVKABnJjxXanrrllLLNnVvOovahbBeRixXRLYlEqTyYIkWJSVvKJlLktBnaaGdrlICcRHerlLXxYVyyfFYYxGuUZVIhHYPtTXxBAabJVGHKZzgiJTtgdHhvXUNHcxbIsEeoaeSrHrNsdvCuUUusCcSAaPpcCGnMmWwkKEfFNnYyCuEVECCJvVjxXqwWzhwWMmqLjJlkMbmGgzZcLzZzZlCGqBqQQZhSsgGyZzYHkKptTTFQcCJPwWEeAahstjJkHhgoOWcZwWzgkqPpQrYFWwzqzYzZXhdktTxXiIKDWqFIXcFfmMCxiFpkMoOgGSsBMSaXmVwWxVKDBxcPYTupZSsDIjJopJNnbBDdjrRpXWKHGgLSKxTiIymcaACmMtvSmVPpIGiuDBbdScCVjQgHuOMIiewWRiIaAopINJQqajMDMFnwFAaxZCrRQQqrjJclkRrsTbmIhiCXxRrXKkxxBllIiSAaQKfBZzbzjJWJjGOAaPppEhHGYauQPukgNbBEQEeqeVPAaGgkTtvVveIityWhHpOGLFfoBbumJUujBVSgEeGrQJjIiHAauULOOooAIVNkKuKkQCzoOJuFcAfwygGDNrpPihVULNYfpEiIMvWNnwFmgmMdJjazZWPvSslYWpGDdYZmMYGgUEdCcylLYrSujoOTAQCUBnNbaAhUEeuLlCcCKGChgzZJpMxwhHAzFNnnNyYecCPrneOrlFOAafrRRscnNhEpjJPXSeEkanZzfUuKEBRrKXxKyYRaypPKFfgtjqmMQsXxWFTtfSsPRrxEXVvxevhHVRXxNnFEeitTYIiyvVIWsJQOoqGdUtTYxXIOoTySNnsNnTfXkWfFwpPJjNCYLlyajOFlLjjQqRrJrRZkcFfTdjpFfLfGxHxDhQNnJpPHLbkUOOoFfdEayYSMmMRrDasWtNnIGvRrUuVBjJDdayOodAWwMIWNRaYyAdPvRrneRrMyYdtFmMCcFSJYyCghQoOqlbLGgyWMAkeQqEbBVnNFARUuByNutTUMmCtTGgvVArqQqMOchkyFtaFfiOtIHpELWPpKCCOwWDyWhHdCNJjQoUaJjyXZrfFIqQiZrRKOnzgGhBbOiOQyYwWsgGuYqQAaqQfFGgrWUAPpauzVPlLtWogpFqpXbkvOgZYygsSqQyYJIVAkLWwKWJOrmLUFfYpPFTTlLZzJJgoORVPyoMllUuknNzZBtuKkGnzbZmvVIitEeZzXxIsSNAapPraEeNHHwKkBiCookfURDdrpUuPsSgSdQspzZPioOsPYHyYJSnuEmMzZtSLwyYSsZzCcZzjmGgmlXNnSzbPQScEeWwWqfTtNbBZJyqgQCcFYDKkIKqQkocmjkdhoEIQSSqDdvpgbnWwNARrEeEeaIiJSlLPsCMDCcnNkKkRvPjpzZzAyQqiJGVmoOaQqulLUFFfgGCcfoOVvvgGsSVGmHbByNOUZusitRrOqQXBFUtHhdVvWQqwVVJhUTaCCpAapPXYyHxeEBXxDybGcelhEgGxXmMVLlyjJuhJoOuUiAFSDQunTtsSpIWOowPptTWnqlRWAtBOobushnyTTLBcCbOjJYTteTtVQpPlfxXYGgklSCSbBsczFxxJIijyUdDzanwSFfQqWWbvIopsSPrfFJnNYseEStGkKgcgDXxpXxdsfLlFSDPXMDdmxdGChgGHtTTwWyjROiIiHhVBwAaIiHNUunhwsWNAZudDYhHXXfZsLIinRrNlLKyFLoOqvAaEMmDdzZyAZzaoIYyilXLAalxtTttYNHSUBbTawrLQNnSsPpTtNSBbswiPNURrqdsfaIjHUYCcveHWwLECNngBYdlLMqnNQmbvFgGfVXhxPccAtuHjXxvzZrRvDTufbxoTISUzuoxXnYhMzZDdgvVsSFfQqAMvgSsuUjIhHYaZPJpVruUKbrRBdmCkKzZccSpsYyjBGPTtMmwWPpbBVQXxssqyYiiIeQqOHDKJMCOiaAxXlLdzSsZyfCcqGQYjznAaFQwceECCsqpBHhZlLsxLMMJhWwEeHWwWlsTFflLeaAUNuUsjhypSISqDsGuFlLZQqzKOOcIbaAWhHhhktTKnsSARCcaAzZniTaAMzBZNgUTbFfRJjrKUuLLmQqimMWwIOLlYpvruUGjjttfyulMRojwklfFKGgQqavijGzGoVKSsBbBxPQfEePtTGOwFfTpvTtZwVvRcCyUSqoIoBbHAaZNgniINGogGtpPTfFkzkKwWRzxYvaAaAVAuOiIqQqncDtTwYdLlrRwWocckwlePhiTorRIgGVvATfFfYKHtnNTCsSoVveGgeEEmQRatTcNgGnlLxXyYnYJjhHbQqzZrafrRvKamXxGgeEwYlBZKkzLPpHGcSWwsjsfflLTDoOmENVpDrHhnwiOomuUaDYYyAMmbBbgiTwSAdmsOrdoODRIioAerZzRDDBOobdwWoGguKBWwlhGgjCcpPqHBbdXhCOocLlXwWgFlPoOJDtjJCKzjlmMLJfFJfoJAmqQMVvcnKxFtYtBbiyuDgjSwfNnrXpUuhQqHqnNQaAaAdDwvVSJTGGfBbFgEeHhkysSDdYXxIiXxYFfArAauVvUksShMmJjHkbekxXFFfNIiLOolleELnOPpoNAAKSssxeHCSrbBFofraAgGRLcCRoENbBRpPpEfZasCcSWXicCXxImPjzZGHNXxXxzZncnNgkcLlaAHOoucqaKknNMmeEAaKktyYoOJUsRDeuyzygPwyLRrVKkpwVvTtzZADGMfEmMevzZFfVWVvZzwUEeuSsXxVmePaAUuFynvVluvHIRndYWFaCwWGoOmMgfUjlMmLeEZcqUnKkrRviaXxlhqRsvbMSEesUOlgKkoPYycIiCweEYTEVKNnIivVpvnVvGHhKUpqdpkKYyPDUAygwWePbBogMmwZFkqMmsLLbXCccIVvHiMBtSKLCoONnRxXqrRczXfsSbBWNfmdmJAjniPOozZOTtrEmdpPDoUhGqaAJvsUIgzzUuZZiTtvMjJsVaATVDdVvvMYAatXzHEehZkslIMmihuUkiIwxPPOidtTYyzPUtyRrpCXbdkvuUXZzvMxAsmbmCaAcKPfIJbBgGjioOfOoQiPpvAaVAaIwHJjxyZQgGZfyRKGtTCTtwoOGwSuUsYyWKasShHLlATSMmhHeaAEHpjqftPxXWwzNGgnqbQgMBmKQUuHZGgQmJjMcYycevbBjLlEeNlLnJeUceMBbaAGgMoOmmNgxOoXAacXxVDzZSndDRhXxbMmoOBoORJjsEAOSiBXChnuxVDGjIGkhvVgvjAabBpyivrrRRzgYyXjJpPkKvyREqQhlLriLRDgKkAANbTdDKjkMmsSWwstTjwKittTtMtTRrmTQKkeNnLylrIqQrEUuHLUulAVRHhRNANbaLjJlRCRrjftVvDKkdpGWJjYNFQqZMjEHhSXALcuykklDUExjvuUCctODXxdhTtcCHoTBKRfHOYvVWwxZxzOoAAyHhCcZiXjYTKksqyYNnwWFsSwBbWwWfQOoMwWNHNnbBxdiPkKMalLfwfNtXSfKUbjvVzeIjGgBZzbxXAacCmCqaAEgPpGeeEQcmMRrgvGgrRVTyYoOTgdDneEaATeEICFYIipgJwqQHvVqIjUvdjJgEeLHmMrPpRUpPCJjcglLrojqeUFVwsSseZyYzXTuUkKTIisUuSWOYlbLmzueEUtKBUuTOoUutbKkWIOoOyorUjJDduoXxDDWhpPKxHWwhxSsOkYFnAzZafmcXZMtPOSsophiDMMYyIvVVzZCcvkgGGCcgGCXWcvVSNPpvzZXxHaIhZmGenZGXqsZyDAjqDybNBUUutTvPpOoKFOqQJyYFtyRrOovXJjSsxVxRryYHhbZzBXaprRkKFLvoJjOeGDdASuUsashHSsTtRdCumfcCsLHZIpPiKkatDUudQoOTaAtCXqclzfSsoYyAngZzCMmgvVFHPsDKCmMckEeTrRgxwWzhHZcrRKjBbZzksSAFfaBnNQSPcxRDtTtBYsPpTfLlGNCKkcJEyuRNngSJkKXPpomMJnFFfogGeEPQlLBlPpkKHhBQJNrCwKiOBbUuWwdFqQskWnIFNWemMBRRDpBzZtTxkKRdDIGwaAIFuTfZoOBqjGgbbBFFHosnKGkKXtEqKLgGkKlxXCckjSJjsMmeEpFvunvVVFfvoRZPdDBbHGZzgOjsSfQhHuuUAkKMmetTuRraVIiNKPKkSKniIiTYTlGnNJwGusnNnyGgLlPpeEhOoSsmMbKkKkEecnCOoQqcKQqmMkzuUYqqQSYrRmvXlPQdDqniINqIsyOOSAawjJIFfVvJRrTtxGWwDdhHoRzBuUPAaaqbIiWxFfDRrjUsSepCcPECoHjzZcCoEeHfIuwWHhHVvDxXVjJndhaVvAKdDkzaAsasSUVsShuUDSQqsmMRrlHXjRrEzrzbEKwMAezZEjJaALCrRcUuWOiUyKkYTxcJjgbBGNAPpUTUIlFcChHXOoPpcnsSNZSwfdDXxFaUujyFCCJAajcWmfFxcCxhHXPpCcOYyQaaAntTaAAeEXxYDdyDdDdeUcCbqQBpjCcwOUkKBQDdqLXvYFQqEJdWSHhcCnZcdrqQKldDLzZnNaELqQMmPpXtTGWwRKCckxiGSUgxndDNXvJjONqxXMvVHQqEWtTYyoPRrpXxYLlyszHhzwWOoeEwZEeiIjxXQlHjjcVvyRsgGRDdAapvVPrXxTtGgYyDLwfVQSsMafPQrRLqBUhMIiFkKfJLWwLlpPAJzRNnTGgSsJKkjswWSFEefqQeEAUjJrjeCwWcQPhHnNBcgIcYOoLlsxXNhHTcPBbOnNfFZzKGVaxAXAaAlHthbzZqVbyhpZLlxRJHTthjSFfaAsSfFEejPpJDdcyYYLmMfFEgujmszKFfaimImsBLlvVCoOvSQLUulfFtHxXoNbTmWJdEEeHhyTevhHjfFJCiBbsNiXwWZZpPflzZNLlnVTtvFLjPEkRNBqgIDdKDdJGtLeXxJjHpxXFWCHQLlsmbBbkKBMyeyCcQiIqkQYywZPlObWkuoppPPOUWUJKkjDdzyxXyYKkSQECckIYypTtTjXocCOxCcehHgQxwTfDdLlJjkVvKzZeElLFfLRrdWFCcnxxZOoXxJSCcTMmtGJffkKBbOPJjCcXxOALwWxIivmhNWwhTHhtiIdDkKaPloOWwBeXBfFbxOVvvxCfQqJjJAbBuxRrcPpjsSJDbBwqQCcWdUrqqFGgfrqQAoZvOiIoLpPmMPpvuCcQvVsPpMGaAgJjuUjTDbxpPwrRIiWCAyzqQGKkERNnKlSUAauSbwWBoDdwKkWObBbnZZzyYoUHhuWIxXQxNndXrUuMfpfPpLlVlhfKxXkpOoBzBHbWTclRsSrLDPEGgepkpWwPwiIYyMmCCgmiRmvwWSKkeEoLlCNnPhHPjdJInElfUamMNSqJjmZzdoCZzJjYaaZzuFRFVyBrUuHyYdDKezZlkKNPpMmXxIRSoOvVmtnJjUFdDBrWwLsScIHoQzuUTBrpPRGWfDbqWwKBbjiqQFfIQqaiYmMQMjfnwBbSMAamcLHdyYDhgGDuKxIiUSsuwWpXpPbaYmmMUgGuEejnNlLJpEVveYuUyiIGgxOKtTVZdJjDhAaCcrmgoVLuRMWSsvVXAVvSpeErJoiAaAaILKRrkeCClLfFoOmLlMccBNnQhsGThrLUZLMmxxXhsbJjjpPaxFyiSWvVzsDkKdqrTPpNIPMbMmneIhTOyKuUSyOoSsFAafDXARWwcFfCinMxyYIiqKkQRNHvgIiFeYcwBtTKlmMtTEeuNCtAhsfFVSsHiysCbnIyYcMMWxQqTtJjgGzeEeZzyNnKvVQeoBmMbJuHhACzZRrcApcKkCPHhaukKUzbjsWBbsGYyMHnfFPvVJxgRHZzdTffFuZUuzMnlLUNlGhjjZzAaDdTtefCrRjDvtTFwsgGDiLlRuUaARvepjqRbFvusSsbmMBBvqdMmiGgjzFfXcoozlLgrIpSsSCcPjcPmMXxpFSsYuoOBwWbXJxWwWlNnlLtSXigdDKkKSssSUWZzSxXVMmgGzdIiQwWgKgBNnIirdwWBwqkKBWovlLUuDdWmwHhDSMmAasNruhqxLlGyYEePiDcCoAHPpZHbfFiIRrKmMZzkFJjvhpuRryYUkqKkcisSwqQTLnmyVvFuUhAebBzjJXrRtdyuRyYrUTtYGgzZDmvVMTrzRlLIQqzoOZPIWjJshHSndsSrRsFPloOLpfDdlPpdDcNnxlLARZpCRrOEPlLpNnedCchHkQQqqKSsDvcZuUzCvDdTOTifALMaAGdblMxZzmurRwuUuUWzGgWuwMsOPpJjDoYSsycCOslLSnZiOoIuUzgAWVtNniQqWkBlLbqGgKdDgbBJjpPGnNxjJcYpZogGnyOkRkvEIzLlhOoOVxrRWonNOLlEbICNHTxKzZQqcyXIallRFfrvexlMmGzqYaWIEeitTwAaHhWrOheFpPWwruMOUaAwhMicCWskvVKympPaAMTtYCcdeDYCrnNRcRrydEfmpaAFfPhHpeSKEoOtTehfFHHHgSsGhDdwhpFIuUicOGfSCaqUcoJgnkQaBTfTtDZQsStTbJjBEVvMmZEepRJjdTaxOoGfbSsgLyYuDxXwofSqAaQhHoIMXDeEdHsSWwajlgbberREBrRLlOoGeziuUHgbHhBwPyYkKYygGqFjBEecCLedfFrRgGAOBOWxulLcWtUmMlLmoDddEeDpmMPOXSsxOxXOWwTthSsWYaKDoUuXegGeEaxDdXpBbPZzALuUCufixtxqUuVvQtZzTRrItTYytTJQqjYrWwiVSsvAzKVlZzoPpkUuGlUUyYQOZDdznKDsSdtnNnNTXShHsMmrjqGgCcdDpRrRrYyaEedDNHQNfAcWJjWNnXFLWBbHflKktaHhVjJzZPMmpvAnqQiqQbBcWwGMcCuXQJuEjTmbBzyIiHsZXxBOotUfFuTCcfFBbOoTJDdyOwNVTtviczOxzIibBQHhNnqmAamueEUMcbJdDjpPAWxXRNuRkKrTjvItTZzaAAaNdDUuUufFIiiIRNTIEhlWwVdcqFGgLiICSscSiTtjebdDNEentvZDdOozVMPWGggdDWwVeEhmJjyvVTtvSstElgWwnAdDcCaNrBwOjAaQqHhNRhAedbstTxXSPsSOBJfFGFfgjbUXbBlMKnNVvCcFfCGgmrRMLAfGTWwNvBblLizctPPmeqhHLlHhQiuuUsGyjlRPeewWEDOsSpUKjQqyYhYyXxPpHFfHiwWTwWesSVGiHhRrDPIxOiEKCeEpIivVJWoOwjnfYyTbBtGgRriIcCsHBDdbhcFQqqPXxxLjTtJlLwWUWmXuUxNbBWSFyqUumMAsmLlMSqQTKkNZznApBbPaNnQYIDdspLEefkoOgGjojJOoxXOlLjnNBrWnUagGAnLMFssqxXuUVNcCrRkIGNnqQpqoMcdTtLewhgaAHjdDJgGyGJRCMWyYQJjqIioOhHSQFleEuUOoLjJRrYhdpAgehHbeBNnmJjYHhAaUnNizrRpPJahcWYZwOoWwasCcSUVmmMmMZBbuSVUkSYycTZztyqQGWZzEBEygFfoKqQaSsvcLZIiznRCcMBVvPjPlbBhNnvbBVhHqSSssrRSZhavmqQqKIiKkrRxXhHkQMEbBdzHhZQqWUuwfPpFDXDdSxMmwNiKBbpPtuUyBzZbRrBhHJjWiILBFFfkQqOosejJIeEUSpmHfBbNProCeiIaQpPhRyPZbBWxsTtSRrdkeNXRSnrGgRghbpdzZDPOoeEyYePirUdsMagGAVvVaWrqZAUEFfeuTgGtgoOVVNFIgTtZzANnavFffQAgaApPyZEezYsSkXxKaAGEelaAVneENZrQqzaACALQqeElzvVARrUpPuaZlJjLqvVPpcCBiIkpPjutmNAPprSJEeAtTBjJqMmAOzXxZKgwWAajBbdxpCcCcWGgwFfuoLTrzZBgGCMtsScrqQRClsEeSddNjJbBHoNnrRqtOdtBPuaADuULbYyWoJjETtBiWwkWwVYNnHWwhRBbkoJjpPXiInNdDxGRlxRrFflJjNcCdGgeYgGyYCcNJjZLSWLltTuKylLCZzZWwdDrPpOduvYrlPHhGgGXOyKrJjEQJgTtcCSQeEaAfFpPaniPrGgJLLlpeECDVKkKNNPphpDKpqxzXQqosfNMOoWnvVNezZKCMnXtTxbiRMmruqQBbCcGgFTzYypvMQHYyhBbyWKkoOhVvsSxdDjwWvYCuhGvakKMAsSlLpzZslvjAVvuUVWwvKkagwWRTtMmpPzEEeOomMUkKjhlLhXNnxqaAQChykjJcxRLlbDuJxGMTqIRjyYyTpPdDnubzZBbTpYgGeEPJjHwuuUgRIiPpzeSsFRMmLFPAHWuULlwqcPpPnNZzUursSyYPpNjbVlLSBRphHSDAEZcCfFjJLDEjJpPJRrSfCcaASvVRXzixKNnuIQqOwWDdpPohHiKKzTtYhxwKnpyULlEerSikpPZVvHhqRrgjvfFiIlZQGWwsSwjPlLEeHZAgruAaUqiIHeESsmRrNnmeWwhgGxXZWcCwzZHhUuvFLpPlHGkiIIiYyrQtTTthHZzxiaMnLlvxjJiGsSgvVTtIZGgXGyVNKkkKacGoOkOXOjJDBbMOmMmMoZzQJGAPHrRlgGnuUgGPhHqJegdDdDJlmMLuUdDMoOYpKkPDExAamyYrEReErWwxXtTKIcqBLluiIJjsbVpPwWBbNnJjAaZzJjGnoONEesAWeklJtCcgBmgZzpPsuUvVgLlyYGSwWwWLlwWhoqBiHhqtsMPtHtThvVbOoKOoymMqJOojjzZJWyOoYIiTtEeKKvVClCAajVcUuCbBojIiIOovFDpRrzDXPpvhHUuKuUodDGGXxggUuOFfkmjNKknPvqZxyYdDbcYyCaEeABSsXORresFkMmKTtjJoOYvVQqSUgGVmMvKUuRrgELyxXulLWvddDqNEeWyeEYpolnyYZdDzjFYkKyNnBSEeLYQqNHhBqQZzrRbnCWDsdGgTtxhoORGafivyYpPEvkydDJFfQGwIiuzZqQUuGgSGTVvMKSscCfshYyHJnNbrGgScCUVGgyeyYnPaARtpntHlLILzXxyYBbDdZenNkeEKFfYygGMvdDtAbDVvSsqXTtxXaAjWwJJLljlLxYhHvUuKeNnRcvVCWwrZtTpTuxmNnluUlhTislJjbepKtKUupPkWlewWZsSgrROoyYerxXLdDkKlMJjdGgGwKklXcluULCklRzdDZQUuLbBMXRgGdDrwgSrkKKxJjXMmIxkKdDtVOzoUqQKeEdDadHhLIxFfosQqSKjfFqnNAYNSsSRgGywWQJacYDqJLVvBbjJTHWCNncNWEeopGgKEetOHeEhoOWbwWagiFmkLlKPpccDdqSsQlvCmzZMcDaeEqQAfJpxXLmTtkIinHexXruONdQSsxPBbRrIicdGwWgaARoHhOaArBSsbsSHhPpnMmiQvvjTtJVVikMmDdRrfFVbBWBAaiIyfjJFNnYCaOgGrHSsIGJnNEkKeBzgGMhMmTbZzBnNPtTCcbBzZoUuOaZAanTtXxXrZBOYoIMmiOqAatTMmtTQXJNnjoOWwWcChrWwbBBGgEQqQFdkKLlDypLlQtYyjKEeaCIQFjnNUzPUHhuGgfbuSjSsjJBDdbCcEemMcdiKriIRZRisFRUpPyRtTrnRroOXrRPpdwWFfYHhZvQRAaQqvQTzZBbtFferRJjEFOoUmMxQqdDXutObFfKkQOeWeEgGgGOolYyMmpPiILWDdgGaAyYoOwejUElLYeEyethHTmMYyiOLJjlcBYKrRkiITXFBbxXTBkKGJjgiedDwWFuuUVvvVvmMEesAiAyZZeEzzZJIimGYTJhHcCnDSkxAanNSyUuhrRMpyECcbBjJozWtTEOoAakZHgPpIMFfDaJjQVvVvqhHiIpPPpbmZAaeeENhuwWUVvjJHYyRzZrczKkapVvGRNNEeuUoLeEvVCwEeKkrmfAyYMCcUgPpGJsfFSdrRqRQqIXCLzpOolLsSMkKpPXcJjCKuCcZPpKOokgoOGWcwWgqUCcuhFjplLPJjoUEeIWKmLgeLlEDddDYytWPpwfFFwWfALlMmaSsWcNRryYSnyYoGXxqQjYblLPbBzGZzglLEeaYyODhfTtTCcbsSzBkPpxXPDdmMLlvVaAkKrYypHAakzZbaArSsTUJjIBZeZfFzmxXMEPmMGbBgpzblfIoOfFiBvrRYJhiOFfoIaTxQjJqXtDdJZzmMnQqIuUPpuQqRCiBbJviIuUVEeKknkQzpFfCYOwWxBbVvggGSjJXfmMWHVYPpZzUuRKkSMJPrRAPpaFfnNLlkdGgsnftTzUXEmCcYdDDdZzsgSspPcqQTPQqrhHxZgMCxxXbBTilVOovcdDkSJjseqKEYkKySUuJgSNnejuIgGiPpnNHhgGDdwKYKFfocbVvOoBCjdDJhMNXIixoRlLYUuJnNVkKxXPRrnNIYyizZzZzqDCcOvNnVovVFYDyYkKlLHDdwXxXxWPPfJjJSwJptMNnmaRrJoMyZUamNguSvlukKQLsawUpFGEYyAQdDcCLiIwWlbpQSglMYnaANmMShqQHhoaYeEIfxwfGoRrBAyhHzZFLXwLWwlWxCryUuGgNlLXicCIzeEZlLmyYAtTPpMgGoTtpKRCdHPpiXxsEoTtZHMTlLtRHhrunNUCVvvuUVpdDtTvVMjJJjoqmMrjOXIixPVvQqPpTXxtaJHhmMPpJrRewWaASMmAxXaJjsgKkdDyICZzcVveEGgvdSsDkuLlUKMbjWyMmTpwWFfjJLuXyVvGgYgdDGdDxUrRXxyCWtTWuYzfFZEezZhMmIiSsUvHqUuugVYZznGcxGtjuUSftPpfhByYSZuUZxXWNLvuJWwZzMJIkKPNnDdpJjDdHuUlLhAgGpPoOaFfhHteFfAOyxXBbLlYFbYqQgGWwymlfPpexXcCEFLWwLljpvghHAADEYZzzrDSbZIizIiAcbTtBoWVvVvwOwnGgrRbBvVDEcCeUZzNTaAccxVvauKcCnNcCxXVkweiIEIrRqXDrREeEJBDdbkTrFSAaeRrKkgGOwWtUulLegGEnNUVSPeEpaAsYFebBEexAWwGweELbBlrRhHrRoKBbuUkOWRqQbiQqIBdDrSslBPFlpPWBNnYWRvVSsOdZzDRrexoOLljVvwDbBVfFvMDTtFJjIfymMqQzyAahOkKUPpwWIUxpPiIGgmEezLlcCYxXjsSSHncCIAFfbBupBbCcXQdlJaeETtAPpKkXjGgAxGgHtTGVvPpgPsSEehHJjpMmSSKksCcAaQSAsOUVvudDLlQfFVwjBMmfhWxEAaFfBIibekKLlplLmMPutsTcCAaAYPpBbunOiIwWlHEUuOUufFmMeJDdWeKVFdDJRxfZzMXxvoDdBCcYybWwxXHuuUUhdDhjJHyfuZTtAwJeFfLOooOztTjksSKUvuUVuAavVmQgGZyDdQqDdKkPpxXMmEsXpCezAgOovCkKcFPpWwlSeEsLcCfVqahbZJjcldDiubBGWHrXxRyYEeRHRryzZIbBEeDjDdmXXxkKdXVbBvIrRTakKBsZzLiYyIXlPpeEWeRKLllcCLkqDNniGgjqbEcltTRTYJgquUcxmxXMXaOaywfFNHhVNwWuFfUnYyGgvLlLAABOobmMpIiPrRxXafmMFsSFfBbocCOavFsyVdkKhIeVvEoOzaAZJjicCCAMmaYHhEeylLtTrRcDKdDdOmkKMouUXujJkKUxIqQiovGUugugEFpXxIibBEVQZzKkqTtveFYQqpjJiFSYJjwwEeyYDdpNnKDKHgHAaAaJjfQYyqyYvIeeuuJgGjUUEnNJjyMmYRjJPpkKrsKpPQqvjJVeEPpcQtTjPpfFrrrSsdfFTxnNXoebjJBEGgAatPbOaksSfFhNtTQqlcCNnmMjYyzZuUyYqeNYoOylLlFfXJEeUuzZwsStTHQAaqhSHhQqHhsIIiiwWnAeddDyYKmMTmMXxDdiImtKKXxTRjaAYTtPRrEeqmxedDEzEgAauMqoRMoDGPmMWmMwUbBuPCcgaxEeVvxnBbUJlzHTLplcCLAajJAJJLlzZcKkzCcBgGDFPOopsSKqAaQkAjWKkuaOoOomMGgZzeTtEZNnFfVRqQrvziIhHxPpXcTxqQGgmqQpPpPPraRihHgGdDCnnbmyYNGzZpPSskKggGyKEegKTgKkVvvVUuLlGhehHtTCchOteUNnAVHhlQerRzIdDQqeVgGFBbYgGwonRGgENnerIPKwWkDdUFTdQiEqQehHnNInqYyVvWwaAitvdDVKIiKHUuEXxgeEMmiJLlCTtSWBbVvwRrkNnKsMSAgGDzZoOTtCaoOAcdacFRpvVPCHuQMQqmyWeEaIivVSRrsqNiXxlEexXOoMmxBiXyBYyRrbVgPfFpBbFKhHNlEscCcCLlCHhwWdLRrHhysSYeEPvYyHLTtTPpjZMmzJIiAaVPPppZkaAwZMuUVOIiBgGqQbIZziUkhvIHhVGgwAaWXOUwWuZzoGgThHtXxZzuhHUrRNnBZvNnotUutEcqQsSCVvNnmUkKXxXpPiIJjYWbBDKkdTtwylWwcCQqXxQgGLlZzKkAaqcBbAahbVvQnNqpkKcCiIHhbSeNnEbiIaiWwmTdDuUNnEBRrwSqGjJnNgBnNAaVPpEeXDdxvVWMHhTNYLlyVvqQnVvtVbBvafFAwmEXurRZjJzakrWwHcChFxXfhHwoZVjJLEelWjJxxkKVbBvsjhHJpYyZzQURyxkdDgGpPlcmoYXVBhNiIEAaNnwWEeewVvWndtMmsGgGNLlRrCBxVFbLlTtBhHRrUVFCcBxJSXxIiQqsUukKtTGgGgGKkwWVvdnqwWswWGGUubkCrqQUgHhGPGodPpoOHTBbMmtnNhlNnrRdHhZzDiIGgMalEeMftWwTBbePpEBPpkKbLlLFfAadkXxKMmpPievtTNnKsSuEeXMVvmkKlWqrtrqzZQqTjpqQPPpYGTttTGgIVLiAaXnNtsSmMCIiKkPppPcgGTlLUxxdDvVpPaAWZzYywCcmWIilIibFUuxjGzEiIlHdIMmiebOZVQYTtKRrkyTBbrRtfpPRrMswWhQdDySyYfFeiIqcwWFaLCcNcCnpPEAaCcezkKCcWImRoMIiiKXhXxxKNnPWnRJWjnzdDaAZcjJTiIqQnOohTtvkUuBiIcCwWQqIZziJjCTzefFXxxJjZVamfqQFYyMmhHJLwWoXxlLiRSyLIXrUzKkpPGgXFfzoOXLqOyMcpPpaPpAPJKvVkjbCcCcQTtGgLlqBtKiSsfFIHhKkkynNySsOoQqQqFffSsFoOroFffnNPpKkWwnArtTRlLinNaYQqQvqxXKXxkQucCWTttTBbwUWwfFgJjZblLBMRriOoIqFhjxXJaqQANlLbdWwDBOUlLtoOThoOnNsSoDpqQxpPKnaBbANTtfyYnNhLPRrdDPhHVNVvVvcThXxHjgmMaAaauUAYyOtTnNjoOYbQqkKlLCJixYNnyXoOeFfgngGwcZzCWVQqNgGPwWyYpjqQXnwWvFfVJrRjNneEMmsMgGiCcMeEmGkVviMTtmtGwyrRJjjCKYuRrOSiIsHDdPcCHhkKrITtrRSQqteVvsSnpznNtTXxGOibDdhVvrxGREeMFXxGtTPpRdEeDfFHhlLYyrxlkKUxHdDhhHZzXKsSCVMYyHotTOEIigGUOJFdDfjuUcyhHZYyYamxXMXlLdQqDQDcCiIksvjJOwWIiIizKgGZXxYyzkOaZzAqcXgGxbBYDJjdfnPpPpjJqQqTXRqQTtrzkKlLGatrvvIihHsSXxXEerUrsZzSqQjjLAZwWzqKkwWQaPEepQInNWwiRKQqVvkJzZjjJrnNhOhjJDdcQQqOYOZzoKkqQhfcsSCGgirRqQoOIdDYivVpnNPIygdmMfFaACUuhLlgCoOptTPWyYqzzZNCcntTMiYyIjJjJmZfUrRcClSsiIqQqFdfxDJMNAahHrwzlwsSdDWJXxrRNnxXlLjVpSiIAaOnFfNHEeMKkjeVKkxXSVOugGWKKkksHhSNnovViIMCSfBbhlLyYDBoOWwbAeEeEeEcChHIuUicCBXxbSHTzZTtIbBiKNnkwWRmhvVnNoFlEMnNpPTtmGKjJzZhwBZzCcpUucCIiJbOqYDdyrQqcCqvCcHuVpPvOocmMlOoLjsSVvnHpPhdKzZibtNJiIjBKbnTHhQyOyYoYReDzcqRrRRrrRoOVzBbupeUuoOEaOyCQqgGlLKtGajqQJlxXLDWiIkkKKkOmMmZEeSMvuUoOeyqgLlnBbwRrGgWGsSQqgzZgGNrLEHhWwVvemsiIPpCbQqKgoOGVvPpulUuLgGUkllLDeLlBbgSweEKMmkIiZSKkAasgHhGIaAiWoPpOOowzWskKdDEvVePpGOoeEPNncCmKkMKwWNniIXxoIiOYZBbzClTtCcLUxEkKmoOMwWXBbxDfEeFdDFfTCpPKkRrBnOosSuxXAKLlkRrgoeEFfOeEtTRzZZaFKkNxRrRvEFbBfQqIiekKNnpLlzwvVDdjJWojbUTtuZMcCWesSEwXSsbGgDpPcCkxXKdfldaADpROHUuyaAYzkKDdaoLYyizZYygGdnNDfFxbBNiiqQgGGWzZBbeqPxXpFQAnmkBxXrRXxoOyYcCAiIIHhiAgFfGCXxSsMqQmgXyYxGcXiIiITtnZzgKbBBbkFfXxhIioDuUHvbBVbBpPlLADdNEenGgaXxdtTDkKcHIiNSsrIcduUwtTWDmMlyqQYazZWFWWiaxXEyYwWeLlYFqQVxXyWwYvfKkFEedHwWOohbHhgMFmMmMfmrPtdPpHhmMUHCHhcYycCMHhqQgiIUbBUuTOOoodcDCactPmMPGqOZzOoOvVTSFfstcCaxdkKHhRJEeOwtgGGLgGlgmMbBCRGrRGuUGggcyYCibiIKkrRmHhMxXBsSyYqnNQVAMdDaUlbBSsLMmdVvfFEeDdYPpyZAaKBbMUPpuWykyYpYPtTpJjVCcQqEEvVnXOorRxXxQqXFfKZHTtoGgGUocfFDdUDddDuQqNnUugbBuoOUnwWwGhHDdWwgdeEDryeTtEYpPpFfIaqQUuCcZwWzAiMmSOoKkEelLZHwWglYqQyZvVvYyfFVQqmMPdHhlLDWiIwmpxiIbyYrPpkFfowWTsWlXlLWKbbBCcPzZJdDjemqTthHinZzvVtFfAcEeCsYqKkMFtqxXRrGecCEpNmgwuUWNYeDdOoEJjyzlLZeEnIiLVvVJjvRzZrZrRzQrMmRgGyYRDRkKrdQZgzZGzqHhrRUdDuuckjEIzZJjdVvoOViIkKWwVWsSQqlhHrcCDZVvzZJGdDncaACBBDRrbjUuJfNnrRocgGCIlNnDSBbtTMrRnidDCcIwhcCmbBMAmbXxdDrRQHcCgzZuUiSfFspLlrRPpCkiAaVvMmIKCKkFiIfVvchZzTtirHhoORKMkHhKmaAkSBbdvVonNWwmMeWuUoiIxrRfFXZHGgBbbBjvVJuZzEdDVDYydLkKeEBbxuUXxXXhHxICckKTqTdDUuVvPIRrerRHtThtTpPyYDWeEYTtyHhwdDfUuIbBMmNFlLDLloghHrRhpAPdDpHlLhHhGgMpDdLUuRrIilLaAlmMmKkWZzZrGgIBySNJdsSDsKimMIlaALSdDyYLlkKIishHVvgGKkpPcDrUDdZpZTtQNnqTKVvmiInNLlMCFfcmDdqyMuUyYlQqcLlCBbLmjJCTfbBzHFfpPnNCchzVvEetTNrRwWXBbbUuBxnmMEZzXoODpYMmRrcCVvyISmSsEWiIhJjCctJjXxTHNtUzxXIHhxXiZrTmMzZqVoSREdOrRoOlLdDLleEWroOXxsStNnTdQKaAkqETbsSBtfFfQqFeyxnhHTTyYttqZzafFReBbzZEdDwWlGgGxFfVgGdDAocCUumXxMUqQoUSsLQNnPpqGDddLwBUuDdQqFYsSHhwfGfFdDwWejJcCcpnqQNmfsSFJjfiPpIOozZXxXxLlQqIPpXxPpJjeVvENnaldJCcjDdNxcCbBVWfFIEeEehHYNnPpyaATtiCTJjtkKHXxhuUKkxoOoyYuUxXOAAayYaMmLXlLYnNjEegGJbdDBjkKYytIiTLlcMmCjJcCoGmOcCnNonnumMUNNFfMLlYMmnnNNpPaAaAWHqtTDdUuQSsrZzhEeVvHaAKkKBbYyJwWjsvlbBUImMNnWwpmMPiVvVfwhjJDTgpPOoiINuUdDeCxXeEnbBYyRrNdhHqQTtoOOkrHrTtQXxPIikCcrRWwctsSrwWVDZzBfFPGfFgZzIAUuOrkKCcWcKkCwqfFQgxUPLpvVPGglpGTtgaHhMsPpaAxHOohHOotzZTYZQSZzUpPHyYpzvQkeuUEmOoMcpSMmCgGcsrRfXxBhHbFJjcAaCnxoOXuUGgMUzZqcNnCkKRjllLLdHEevVvxXVhtTHPphBbqQYOoycjJDiIwYyjJdWpPwDLFeEfqVvQOolEjJqQkKfHhSWNWcCdGvViIsSljJjDdJINncHhCiVtpPtTTvoOHhTtkKkkKAavVKLnNIiVvwWOXsSyCcnnFfouXUuxBbHpLlWwPhVvSixsuUiIsSkhHKJvVjCclrRcCLsbBSPJoKTtiIkegGvuUwuULaAlXiaZzUySsYKiFKRTtmMuAawTlqQYyRrwWzcCnNNQUfFewIiEeWCcBKktwFRrvVtmMTzXxRXxNnoOoOwlPptTLnNNnJcCnNgGZYyzNncYyWwWmDdKkJjOXpPUupPuUVvbBuDdUuuHhUCTRVvNnrzPpZzgWFfwiIGHLaAlBhqQYyyYULlRricSThPfbBYLlvVyhHATtatlLTYycCWDkaAKdMdDyYoOBbNnixQscCPpSsSSsqSYyAaRWwJjrlLsvVUTtBzYgeEGhHyvrkKkKtTEeHhmMKmfRVvrOGJwWjgZzjJjqQJjzZpPJfFFvTthHiDdWwIviIVcdDhHBbmxXGgVvXUuCVvtTYycKkpPXxFfLlhtTbByMmvVYbQqcCPpLNRrYyEengOoQrRtTrRrNnMmXUuOVvoczZCxaAYbBhFqQwWQqfQqqhoOzXxATtkKdXxLjJmcCMKhHklDaUgYyFfCcAagBbAWwTtAaqQaTtGvVWOowGscNnCtXKuUkTrRtcCiIvVCcGgJjmIxXHOouqQUJEeyYFyTVvdDOGgooOcCHsbRMPpxXLlcMmJjRxXryYCliILPuUuAAagGafFofFOlLuUiMmWPpSsMmwWnLlNGLLlgUuGlMNoOnuWvVzZHLlGLOolgfAaWoOdDUuFfNnQqTtbBAYyaHhDYyqKFfgGuEaAeBbBbHhHRWKkiIwPAaVAWwsspjnNoOXxdZEezrjJCclLRKcEeeElLNnNnVvSkGvVFzZcCJjiQqDraomqHhQMxMmCcXOSssSAPIdFfnNAaDzZfuUepwmQDdDdqDdWwcCfTtnsAaCifFFckuUGgvVkKBbiIDOodFfFfxXfFTtNnvVGEVbBvJjexXTtHhqQUusSSsgYEeIiLlCbfSRrKkHhFfVUQqxJxXBbLBhEePTtpHJjCGyYCYyAIAJjIUUVvZzuCcbBqpzWwZsSQUuYkKEvVeyqHhUAaDduhSsHPaHvhHVeEiIXBbeVvPpEJjHhvxXVGFfVKkvUugKkbXxmMgNnGjJIgOoGiuUlHDdLLlzmDdMSsvVXyYLlxmMVPpvHuUvVLWwzZlpoOoOFZzMCNnXtTxcezZwWQZzpPVvkBWwbIicijJJlUuHeEhtMmTLscWwCnNBlLXLjJsbNnBSnaANHhGgDHaAiINUfyiIYFuhTNntIqUuyYyKiIkNFcCLlfyYMOomtaFHpPhZwLlMmfFmqZuUTtzBbxbBaXxSEeSsDdLbWwUatTiIkKfFAuAoOaZUuzDdnNwWPYypnZPyfAaFJUAauYyjqQEeCcgscCSoKcCRVvsSrMEadClLnNcaOoFfIiOoaiIDsSdkKAgTtGxgMmGgpAaAKkatXGghHeExHYUpPeEUuAanPpNNMmntwexFfSIijCcJsKkmMrRzZbsSRqQLlqQdzZDqDdsSieEgGMtqQQqTSsccCDfFFfEFbgmMGzZBamSsMGgPYRrWwDrRdvVtTHhiIsSoCJjGScDdlweAaEWTHhIiFCcVveEGqQgftIDdMmioJPAapeEjkgXsGgSlLksSKEexfcCcCkKqQxXcfFTtVdKFfJjrZzRjJVvJjmMjJkMccNnAXxVvgGvVTqQtBbgGPpVTQWtTwuQvVxdbbBBbsSRrtTKPpkljJMmvIiDWGgcCwdtOJjtOKkOWiIwooiuUIkKHhCcNnbiIBWhisSWwzZvVlLMdDmoOQqbBPPbBHoOtTPWwkKjJzZpBhHwIiWWLbpPEeKTdDMmYmnNMysntTNkmWvVDYgGWwPpVcCvFetTapPOonNmMAJjdYyzxPeUubBEmMcsSkKkKTtpPGRrqQFeEdLlmMeEDiMuUHcCfFTtrnNRwWTrRteEsbbwWvLlAZzaziHSsdrRVvhorRwWtEnNeLfFoOlZzTKnNkaAMVvxXvVDdQoOKkxXxJeEjXFfxbQIvwWlLjJVHhDDBbdMUumkqQkaAKYsNnypPQqYyXZbiIQqiIiIclLEeoTtdGgpMbKxXuUbcDCRrePyYpHVOovhdfNLllLeaBgGTtlLbsSAHCcyYhNnQdPpiIDSsIYoOsmVvWByYeeEXlvVlLAwVEevWEejNDpPOxtTQqXYypcCCYeyHhiIYEyYGxnlKkLsSXxmMNOsarzZLPpTtltTCcbBmxXfFdDVoOvjnttTIiTAaqQUoJMxuUXeEJQjJeEqjmcOoyYAamMCjpYRrzkKfFZhHjJyhHZbxXIiBqQVvNFjAaqQYyJizZIdnNvcLsJWwdDjEaAQDHiIhaAILldsSDrCHhAacCcQqfaAYNXxnmiIMPRxXeEGuUgrPeFfHhEuULuUqQlvVIUdDuoOidDoJjOSsujbxXBJdDLmwolLIiYXxwWlFfQdDqeESspPxlNpwWPnLTtzZEBbeMoxXOmwWJjMBbFfYBWwSsbFOSyYHPwvVYyfUuBLffHhFUOOooDdxXceAwWamMcCrRRMmrEtTtTChHbrRBMmpPAxazZuUAdDXdDYWwyaYyVvaAuJNtfFfxXQqEeYyFTADzKQqOdDonNaAAawRlLrWWCcwkjQVvxgGAaCiIAEeaAacuUoBbMmzZOzZRtTrVvEeZzZzEenJjtMliIJjOoqfFoOQlaAIixXLeElLqpOoPXxtVvTDWtdtTDhKkoOHcfFEdZzcCDeEAaKkzZeCBhHQqbwuUkKyrYqQeauUKkZzEeGVvgEJjeNWwvxXVTteEVPgGUudAafFbBzYyZgGySjoKkJjXBbsSjJKkKgGkkKrwXsSSsxkKzZNnaAoqUulLJYyjcCdDPJwBbWIibBAaUuoOKGgkjFfnYWwdyYsSEeLltTkKvVBjJDdqQGCFYyfyYvVbBbBFHeEGoONqQzZxXeEEenFMDeEOoQtTqsOgGoixXHjJhjJIaKaAVvXxTQkHhvJjVKOoZzqtxPDdwbHhNnRrfFuUiRrGgrRWwDdCccCwHmPUuGgSsOWgGbBwNAbRWwWwMmmhHUulJmMjLonnVvNTtMUnjCclLZzJjlNxXNnMmrqpyYPQnyktTwWnNVvOoKxXYFfkJjjJfFKtoeEcCOwClbGXWMmlLgnNrRIIIhMmHiixCwWOHhozZOkKjJHhozZdzbBZmMNnlSmMitTIsGnNgYySsMmMtXxXvrRVxsVvyNXxeJjBbEnMJjOodYyUuDBbeEMPpuUmJtPrRpCcbBRrTiPnNwHhWpxXlrSsRcCLnNgeEoJeYuUKkOoyOoYyqJjQIiuvjJnNbIiMdDIeELlOpyYZzgGUuCcqQvwWNnuUKkVPoNniNuUfHhRrRlLfMmrRFrFEeicyYCiIlLQqPeEpVKkrRSsefFMmEIiWoaeVoOhHvMmEeuXxUdDETtARulLdsudAaDRRrTxFfECceXtrNnsSmMksSZzKoOZeEzfFjqduoMBbeECcAamtTdnNfnaiuUeEHrRrIKkiRnNtlLTiGgIAagXxzoOZMmeDdBWrRTtALlAauTtUgSsWxXwtstTSTgZTtzZerDdREYyXxzQiIjJJjwWBiIRTtpPcCwWrHXvFfVBbOFfoUuksefFEaASYiIyKxVvsShbBTtOnNEoOZzlLeoxXCcCcrQqcYyKkvzOhHYyhHCcHhNnMmdDFfbdDjJhHFjlLvVjMwIiwlLWWaiIAZiIzszZJjbdDAanNBBbZVvPyYRWHsSLlQRryYsSMacCmFPpfMdJjJjMLlgNnwWGRrMmqQuLdgGDuxXUpPOolMmUcLPppPPRrurRZzPpEecCnNUuEtTpGgqYnUuxfFWsSZzDdiPmMYbByGrRuUgdDMUuXGgXfFiIxxqKQpPccCHhCqMmgJjGgGhHPVvMmOojmMKMoOpPgrMJMZzmVvSoOsjmBbVaAtMmTwWveQdDNnTcLlJzZTplHhFfZzFaAfLlEeEyYvVxAabWwfFiUQquICcYMmsSyBdDeERrGgYymdfFsSDyYMJjmWsEyYeSwrbVZzvltTLYyBEAyYaeOouyGwWwSsWvVgztTMmPppPZsSDiIgwWGdYLlqDhyhHpFfPbEWwemMmMGfaAXxFDdjJMmSoOseyYEYyYYypZzrRZzIiPmMiIyNnCczZtTtpPaEtTeXXuRrUUGtTzsSjkKhrOoRHXxHhUCculPpzZCcWBbFfJNNTtLlnWweENdQqLlDGgnqQtTJlGgLTtMmPpjSscCLlJjVvnzZjSswLPptfrRFbBTldipPYZzyfqQRxXriIFaAOMmpeEMtsSaXxAXxwWbBYyMmJjIVviYKEWNnNjjJJCcSsbywzZWEelLvVcSsVvAaSkKhHOosQOoXxqiiIICKUaaAjJAaAbWwIiarRCcvVqQVvdDIKkiIYyiihfFbBHgGIxfFXRrpPpaAPXxotTOaAsAaSxXdamKkxMmyYAaGTOotVvCmowWklFfLKhHZnNzOQiITcCtrsSRbBeDdECcqEUuegGuPeEchfFrRlLjGgJWwUbBgGVeEZeDdXxRUuiAaxRrzZXiItLlTaAXxsmMmkdDKigGiIICHhcrAaiIfxlLHhAhHWwQqrkRaAOYyqQoNNxXndDJjhZzHcCMmTtrMmdDdDRrzYExXAIkKiDnkKNdKNNnOonIVvHhlEezZHIHGgdLlwWDJUujiIhVlLvzZCGOogUuHJjIihXUkKuUOoUuoOPpUceECFfccTcCeDaAdEeuUEhIYSsySwWLUuhfFAaoOTtsxXNnsSSAaWwPDkKTtwUQMmjJdDMmqfFvVIiGuULAaEXiIxXxevQaAqVlHfaAgbBgTtGfFfAamMWpPhYyHjJGgqQihHIwRKDdkxXbLlBWwrFoOfmMkyYKBbAfVvBUubwWGXxgbmMBvVmMEevVtTuUQGgxpyYPyYVvTtXkKNnJjcCGbBgNeULlpPmuUmVvdDsSXtDdqQcOoXnNPhjJTtHkxUuXKQNwWnqQqfFAjZvVzBMqQYVpCdDFaMmEeAUsSxmMzZXuTbxXaABuFfMmhHTTtOwnNWotfeEFaNnAoJjYyOaALvVnlLNUbBVvSsjJvVRrqRrQXxeECcPMNnShHWwtTLlCcaAfRRuUfFDdWwPpNwWYynrRHuvVUdDkKkTtKRrfFkUNnoOVJOXTtgGmMxVQPbvVBjJASsaSsoHKkhOQiIqbBVtTiIvgGrRYDaAHhaAdtBbKIikrRzZTOKkouUEePpacgWuUwGtYyTLlEetsEesVvaAONRrPAapBwlLWIrYyRiQbmMkKXDdxGtuxXDiISsdDdzyYRrAnNaclLaVvQqFfNTtRrAaQHrRuUTthqEwWeBbngGwdDfFUudDzFfYMaAmTPpfFtqQxBbwWBbCaASsvhHJjyYVrRiIgfiIYysScCWsSAaHyNqIiQnNBNnnNxXbzVvVvTMJjmXxSswWmPpMdPEeplLnNLlkKTttnUuzZNUDdtLlTbBPpgGuqgGpPQzplhHwWpTtPuQqUdJjsSsUuaYZzylFfuUifZzFbCcvVBKxXkhHwLlTUutTmMzZFGgftpzqBbMmesSuvabBGgGmMgAhHcCHhIiFfVvCcjJGgqQaRrxsSFftuUTeELlNneEvVEVihHayOuUvVuUGgkoOzZKdUuDQqfFFfzJjkKZQbBLlzZRsnNnNrzZgGiZzIoJEejPpMCcmXxGgORSrTtZzDkFEefrPpRDdzaAZQXxqeUuEsLlMmdjJeDTMRdDkJjyYKrXxmtdMwWnDWwLldkOaAoKqyVvGgYpPwWoOQtTNXpVvPigGaSsSOosTtAdmZiIzMSsDVvBBbblLSsuaAvVsSmMrRUMmqPphHAxNZznXNnvVbzZBnyYsSNzRrZDdMdDWwvVmxXodDOhHZLlzhHfIUufFwWXxbBTttEfoHhdDOQiTtIqgyYGFCcEeOoaAeUAPpaaAFyYBCiZzIEeYycbzCcZfaJjPmMpoOGxXtWwTtTWwgCcVBbgGvSjnNiTtyYvCQqcVzZLlNnIdgGDpcSsCfFPGdDUuxtMNnVJqQjPaACctIQTtTtCAacqxBdDuUnNCJJjjccCbyUuYBPeEpuUrRZAacmMCwZzZzWzfGgFYyrSsRbjnTtNJNWwluULnsSCUfFgGXxtbBTuFfVvqHhaAQiIMYwWyKRRrrhxLluewWEhhHbBodnNrRAkKaDEesSKkUuyFWwfuUFZzdvSQqQqsiIxDyYdMmXIiFfRrHhiIVvIgYycCRrhHDdGifFZpOoLlXxPzzhlxXfKsBZzbeErRSkTqQjJtFIiqbBsSMWwmlLQqtpFUueEFffjsSgGgGWwXxQyiIYqTtZqAaQwCdIiDYNnyfvVFcfNgGnUuHhJRrjhHFAawWEeQhDuUqQdDdaADdMmHgGcCiIuRVvQqlLrtTdDvVUcwEvVvVeWGgYTtYyyUxXusxXSQqChjJUSsLloWwOeojPbBpPwWpXuUjJFfPoOmMpyYAaxdDJONnNnxuZzUeEXpPqbdDqQGgJjBKEqQkhhHvVviIdDVgGqnNYyhMmGgHWweEsSbmMWwZzoOaAXHhcClLDdvVawZzWKkQqAnNPQBbZzhHkKVvhHOgGoDdhsSHoOLluUbtTcyYFfBbuiIfFzsSXWdDFflLwuUBPpPpxXbxnoOgGVBPpbLlinNIvpPEeHBCcrRbESlLWwZzsNCQUuqcnJjJjjJiaANhtLlfFTbBuUDMmdRmMKkrjfFJlLhsSRrbBHHvrzZXxRVGpmOoYvVyMJJjhHBbjdDWOxXowPrWwpPxXzZRYynSRrsNGmqQirRBcCkdDZKkzkvVKucCUKYtqddDDtcFrRfCqTFftnNQTnNhHQKkmMbnNBmrRNnYExXeBipPIElLnyYNebDgGrRdEuUeoOZzyeDdtTICciMYymkKaFfrRzZYoYysmMCcSPpOyljJSsLAyYjJEBWzZzZvVmGgMYybxmMtTXfFfFCcsSOSQqnNPbBpPpBbDpPqQdsGCcgXxTtGglMrRVvmLgGHhTtUdfFiIeouCcZsSGBbgzTROGgocCrAsShHSsavVIiteEmMEGglLeNnKkiEXxnNgGenCcVvlIiihHoOaIiAVvPpIOhHwCcWNneEVvLhJjrRSsgitkKTIGeEAlFfLVvZTtrRsSjJQqsEeSSTtsQnNaHhAqQqAVgGAaDdvcCBlLbpIiGglpPLVSsEeYlLyvVHiIhvJQrRqjOoFbeEeExEQCcnNzZmMdDmbBkJjHhKyVUEGgeuqQmxIiXolLOZfeEbsSBbBOoZRrdDqKkQzFkBJjbKrRjJKwWkzGgiIMAiISsPpavCcoZzaGgjJhxXHAcCxzZhHVSYysdDdDvaADdcmMCBbBbOoXgGYJvOoVPodDOpoOQIiHhbBqxXAAaiIZzaIijJoOKkFfjVvvYKkacCyYoOAJoOjsSsSArRwUuWuUacCuUzZCcrXxRimBbMIBsSXxWweEsztTLwWljwWjtTPbBOouUpgGIibIVhOQqhHPpRrogGpdJjDPYyQqclLCHdLFflcuUCvVQBbqLIiTAahHtdDwWoOZPpzOYyoOsSoVvwdDWnrRNJmMjmMGgIFfieEIirRRthHviIhIiHlXxLJjGglYyLbBzfFZawWuUuUiJkDdjoOxXJgGJjbBjJGtEeTcCPjJlTtLMmpMmgdDUOQqounCcAaNmEwWeZzzZpPMuUJnNjUHhEedDugGaAgAaGEeXLbBVvkQqswWSKSadpPlKkLHhxXIiHhgGtTiIkWQVvqwKWwDwFfpPbBnNDmxXCcMdjMmuPpOOooUnGwWgNJOoJjHsqQSiIUmCcMulkFfKFfEeyYOHhorPpeElLRLfRrFIkKiiDdlZzEenGXxbNNnnXxBaATtXpPxBbqQrRsVvUugGMmsGgjJSPpmHhgGPSspChDdHciCcbBIFfEpPeDJjZzdFfMOgGrRuUoEZLlaAzmxXMbLlBxXLjJldDkBbdDSsYyBbPpbBKsSGgeWwrOoRWCTtcczZkaAKCTsRrSAgFfGEeeEazZtNnHhqQwFDdLlfcCaEewbBWhHnNxXGgqQiYKkyByYyYsBbSgIiGeEMMmmbjTtJTtIxXNnRrZzlLzZgZzsSGUYZzyeEuiMmoOIiIeXaAYTtyxlvVHFDZzdaAfjkKoOHBbhCccCjLqrRCcQsHhCcSkKfFlvVpSyYsPkKJSqQsIioOcCowWWMmwOXxPpMmMeEmiSsIOmkjyYJcCBbBVvzZbZzKKUhHulLLZztTlmMNnQGgTtkkKKSPpsmtTcPpBLlbCCVaAvcXxlLtTFflLfFWwdDcCGgVvnIiIiNzoOneENZlLPpFfMmgsokKOVnSsNvyYSjJMmzZGfyYXxEefFsCcSrcCgGRsSFwkKxXTtIihQsSzZIiqyYQzhHZqINnNtTnwWRXxreEMmiHnsSbQqMeEIimXxgwWAJjakKlLlZLlKkzLWbBwsSnNYyOVvSsobsKcCdDoVvkKOhxXHkQiIqSsPsSVvZzpIiTNiIIigGvVUzLlAaZhHBsSYxXKkNHhnyYIiyAEeacOoCnNGkhHfFfiIfFJjFKFxXflqqQFwWSsffFCcVvQLTtQiIqwuUEeAaYyMmyYevVEKiIkcCgGLlQquUjuUJpPIHhkdDKIiAqQaklLKWwWHTthwLXxlJnHyYhSZzDdHhuJjUCdDcjSsjJJwTVvtWQpPtTcUuCTMmhHtlLqsNlLULlumMHEeLlraGgAtTycCQdDqDdDdWwYRXxhcCOyYoSskHhxXuUKSsZzJjqQhqQNnQxXpPQtTqUugGqocCOStUuKkzZTbBTtqQwWnNxHOoDdhwWzZCcXOobBwaAWssSSUusHSsRaATtrqBbvDkKZzmMdCNncVQEsSeUuliIUuLBxWVvwXxXMmbyKkkKUuTgGtUpIXhtTHxiPadYyvVDmMOoAxkKXvDdVHhocCOfMJjGgmrRYyFeEwrRWtTpPWYywcCBAaxXbkKKkaAAaOoRyYmMrlLUuDWwfFFfyYeEdBbcaCeEAaiVvIUIiuDdrlIMjJmiZzxXkKiIyYiIwTtAJjabPbBpdOjJVvFfoDBWJjzqiIpbBeErXxREePQqQvViAaTtIJsSjSstTjrRZNnzzZBbwWnNKkwoOWSsJSsAaAbBaPprREedDZNaAeEnYyZzIiZyYoIUugGixXxXhFfIiNSsnHOzuUhaADdHpPvVLlBbtRJjrQqdJjLCZzEeclfBbFXKoOkcCeENnxyYDOohLJNnlLjlEeCcTDdbBnNEzZeLltwWHbRrsnNBbtTSSQqssrRSPpgGNnBdDWVOovsbgSsLlGpPsyXxUuYSvtMmFfZWRlMmLrwUmMuBbzYyjJiiIYyIYyTQqsSvVvVVMmBYRHhGgruaAJjUQUuTtqvVRrgZzJjEeGKkiEeCcEhHRrvVzZeSswLlVvgGWFVvfTtItTnNgviAIixfFXaYyIVYtTyBXxobBKkBbiIBaAbxXObtToiIOHhVqQuUuUHqrRPhHWwpcDYydAaCsSQIihHhvorVvRcuUCOoFfANnxXarhHRnNPpFolOoLnNaAOdKkDpPRrGgimWwchHgaAGCMDGgMEemSsLlVvLldRDdrQqypPNnYtTMvtTVmvJjQqbIizZxeEKkXvVttTTxXzDdZNhHGKMmQqkgTTmMSHhBbsALlatLlfFDdtZzKkFfssSSrRtTcVvCaXxADdfaAeEFefMmFXxAaEHhqQeIjwcTtCFPpSuUsfgGsSLqQlZzAdoOjJtFoOfmoOMFfTyYDzZqQmMexXEJjaLlkKlLWJjAajJaAJCrRhHKkkKHhKkAoOcCaPpIiCCcxXcUDhHdjJkeEPpKiyYmlLMIzqQOoZjJWwklLSsKjBbJKEekbkKNqQnBAoOaNnwWiIAabsSfFBbujJUBaAEeuoOpTXxtPQCHhcqZOTHhtojJzJNnfFFfhsSlqQRrLHKSskoOgGNzZnyiIYuUu \ No newline at end of file diff --git a/src/year_2018.rs b/src/year_2018.rs index e8a55fa..2b63cdd 100644 --- a/src/year_2018.rs +++ b/src/year_2018.rs @@ -6,6 +6,7 @@ pub mod day_01; pub mod day_02; pub mod day_03; pub mod day_04; +pub mod day_05; pub fn solve(day: u8, part: u8, input: impl Into) -> Option { if part > 2 { @@ -17,6 +18,7 @@ pub fn solve(day: u8, part: u8, input: impl Into) -> Option { 2 => Some(day_02::day_02(part, input).to_string()), 3 => Some(day_03::day_03(part, input).to_string()), 4 => Some(day_04::day_04(part, input).to_string()), + 5 => Some(day_05::day_05(part, input).to_string()), _ => None, } } @@ -52,4 +54,11 @@ mod tests { assert_eq!(day_04::day_04_v1(input), 35_623); assert_eq!(day_04::day_04_v2(input), 23_037); } + + #[test] + fn day_05() { + let input = include_str!("../inputs/year_2018/day_05_input"); + assert_eq!(day_05::day_05_v1(input), 11_298); + assert_eq!(day_05::day_05_v2(input), 5_148); + } } diff --git a/src/year_2018/day_05.rs b/src/year_2018/day_05.rs new file mode 100644 index 0000000..3203547 --- /dev/null +++ b/src/year_2018/day_05.rs @@ -0,0 +1,55 @@ +fn react_polymer(input: &str) -> u16 { + input + .bytes() + .fold(vec![], |mut acc, chr| { + if !acc.is_empty() && *acc.last().unwrap() == (chr ^ 32) { + acc.pop(); + } else { + acc.push(chr); + } + acc + }) + .len() as u16 +} + +pub fn day_05_v1(input: impl Into) -> u16 { + react_polymer(&input.into()) +} + +pub fn day_05_v2(input: impl Into) -> u16 { + let input = input.into(); + let maj = 'A'..='Z'; + ('a'..='z') + .zip(maj) + .map(|(min, maj)| react_polymer(&input.replace([min, maj], ""))) + .min() + .unwrap() +} + +solvable!(day_05, day_05_v1, day_05_v2, u16); + +#[cfg(test)] +mod tests { + use super::*; + + const SAMPLE: &str = "dabAcCaCBAcCcaDA"; + + #[test] + fn works_with_samples_v1() { + let sample_one = [ + ("aA", 0), + ("abBA", 0), + ("abAB", 4), + ("aabAAB", 6), + (SAMPLE, 10), + ]; + for (sample, result) in sample_one { + assert_eq!(day_05_v1(sample), result); + } + } + + #[test] + fn works_with_samples_v2() { + assert_eq!(day_05_v2(SAMPLE), 4); + } +}