From 741aae4f5e4aad0c5d9c0ff155a67d25da9e2e0f Mon Sep 17 00:00:00 2001 From: Mattrixwv Date: Thu, 19 Dec 2024 18:22:49 -0500 Subject: [PATCH] Complete day 12 --- .../adventOfCode24/ProblemSelector.java | 6 +- .../adventOfCode24/days/Problem23.java | 167 +++++++++++ .../adventOfCode24/days/Problem24.java | 260 ++++++++++++++++++ src/main/resources/days/Problem23.txt | 140 ++++++++++ 4 files changed, 572 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/mattrixwv/adventOfCode24/days/Problem23.java create mode 100644 src/main/java/com/mattrixwv/adventOfCode24/days/Problem24.java create mode 100644 src/main/resources/days/Problem23.txt diff --git a/src/main/java/com/mattrixwv/adventOfCode24/ProblemSelector.java b/src/main/java/com/mattrixwv/adventOfCode24/ProblemSelector.java index f5e2690..e2a602c 100644 --- a/src/main/java/com/mattrixwv/adventOfCode24/ProblemSelector.java +++ b/src/main/java/com/mattrixwv/adventOfCode24/ProblemSelector.java @@ -22,6 +22,8 @@ import com.mattrixwv.adventOfCode24.days.Problem2; import com.mattrixwv.adventOfCode24.days.Problem20; import com.mattrixwv.adventOfCode24.days.Problem21; import com.mattrixwv.adventOfCode24.days.Problem22; +import com.mattrixwv.adventOfCode24.days.Problem23; +import com.mattrixwv.adventOfCode24.days.Problem24; import com.mattrixwv.adventOfCode24.days.Problem3; import com.mattrixwv.adventOfCode24.days.Problem4; import com.mattrixwv.adventOfCode24.days.Problem5; @@ -37,7 +39,7 @@ public class ProblemSelector{ protected static final List PROBLEM_NUMBERS = List.of( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22 + 20, 21, 22, 23, 24 ); @@ -72,6 +74,8 @@ public class ProblemSelector{ case 20 : day = new Problem20(); break; case 21 : day = new Problem21(); break; case 22 : day = new Problem22(); break; + case 23 : day = new Problem23(); break; + case 24 : day = new Problem24(); break; default: throw new InvalidParameterException(); } return day; diff --git a/src/main/java/com/mattrixwv/adventOfCode24/days/Problem23.java b/src/main/java/com/mattrixwv/adventOfCode24/days/Problem23.java new file mode 100644 index 0000000..b5d8d82 --- /dev/null +++ b/src/main/java/com/mattrixwv/adventOfCode24/days/Problem23.java @@ -0,0 +1,167 @@ +package com.mattrixwv.adventOfCode24.days; + + +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +import com.mattrixwv.Stopwatch; +import com.mattrixwv.Triple; + + +public class Problem23 extends Problem{ + private static final String inputFileName = "days/Problem23.txt"; + private List> map; + private List> traversedNodes; + + + public Problem23(){ + super(); + description = "Find the total price of fencing for the area."; + result = "Unresolved"; + } + + + public String runSolution(){ + Stopwatch timer = new Stopwatch(); + timer.start(); + + + //Read the file + /* */ + map = new ArrayList<>(); + try(Scanner scanner = new Scanner(this.getClass().getClassLoader().getResourceAsStream(inputFileName))){ + scanner.useDelimiter("\n"); + while(scanner.hasNext()){ + String mapLine = scanner.next(); + if(!mapLine.isBlank()){ + List charLine = new ArrayList<>(mapLine.length()); + for(Character ch : mapLine.toCharArray()){ + charLine.add(ch); + } + map.add(charLine); + } + } + } + /* */ + /* + map = List.of( + List.of('R', 'R', 'R', 'R', 'I', 'I', 'C', 'C', 'F', 'F'), + List.of('R', 'R', 'R', 'R', 'I', 'I', 'C', 'C', 'C', 'F'), + List.of('V', 'V', 'R', 'R', 'R', 'C', 'C', 'F', 'F', 'F'), + List.of('V', 'V', 'R', 'C', 'C', 'C', 'J', 'F', 'F', 'F'), + List.of('V', 'V', 'V', 'V', 'C', 'J', 'J', 'C', 'F', 'E'), + List.of('V', 'V', 'I', 'V', 'C', 'C', 'J', 'J', 'E', 'E'), + List.of('V', 'V', 'I', 'I', 'I', 'C', 'J', 'J', 'E', 'E'), + List.of('M', 'I', 'I', 'I', 'I', 'I', 'J', 'J', 'E', 'E'), + List.of('M', 'I', 'I', 'I', 'S', 'I', 'J', 'E', 'E', 'E'), + List.of('M', 'M', 'M', 'I', 'S', 'S', 'J', 'E', 'E', 'E') + ); + /* */ + /* + map = List.of( + List.of('A', 'A', 'A', 'A'), + List.of('B', 'B', 'C', 'D'), + List.of('B', 'B', 'C', 'C'), + List.of('E', 'E', 'E', 'C') + ); + /* */ + + + // = + traversedNodes = new ArrayList<>(); + List> plots = calculatePlots(); + + + int totalPrice = 0; + for(Triple plot : plots){ + totalPrice += (plot.getB() * plot.getC()); + } + + + //Save the result + timer.stop(); + result = "The total price of fencing is " + totalPrice + ".\nIt took " + timer.toString() + " to run this algorithm."; + return result; + } + + + // = + private List> calculatePlots(){ + List> plots = new ArrayList<>(); + + //Traverse the map and start a plot anywhere that hasn't already been traversed + for(int row = 0;row < map.size();++row){ + for(int col = 0;col < map.get(row).size();++col){ + //If the current node hasn't been traversed calculate the plot that this node is a part of + Triple currentNode = new Triple<>(row, col, map.get(row).get(col)); + if(!traversedNodes.contains(currentNode)){ + Triple plot = calculatePlot(currentNode); + plots.add(plot); + } + } + } + + return plots; + } + + private Triple calculatePlot(Triple currentNode){ + //Add the current node to traversed nodes + traversedNodes.add(currentNode); + + //Create the new possible nodes + Triple upNode = new Triple<>(currentNode.getA() - 1, currentNode.getB(), currentNode.getC()); + Triple rightNode = new Triple<>(currentNode.getA(), currentNode.getB() + 1, currentNode.getC()); + Triple downNode = new Triple<>(currentNode.getA() + 1, currentNode.getB(), currentNode.getC()); + Triple leftNode = new Triple<>(currentNode.getA(), currentNode.getB() - 1, currentNode.getC()); + + int perimeter = 0; + int area = 1; + //If the top of the node is a perimeter add the value, otherwise traverse to that node if it hasn't already been traversed + if((currentNode.getA() <= 0) || (map.get(currentNode.getA() - 1).get(currentNode.getB()) != currentNode.getC())){ + ++perimeter; + } + else if(!traversedNodes.contains(upNode)){ + Triple upPlot = calculatePlot(upNode); + perimeter += upPlot.getB(); + area += upPlot.getC(); + } + //If the right of the node is a perimeter add the value, otherwise traverse to that node if it hasn't already been traversed + if((currentNode.getB() + 1 >= map.get(currentNode.getA()).size()) || (map.get(currentNode.getA()).get(currentNode.getB() + 1) != currentNode.getC())){ + ++perimeter; + } + else if(!traversedNodes.contains(rightNode)){ + Triple rightPlot = calculatePlot(rightNode); + perimeter += rightPlot.getB(); + area += rightPlot.getC(); + } + //If the bottom of the node is a perimeter add the value, otherwise traverse to that node if it hasn't already been traversed + if((currentNode.getA() + 1 >= map.size()) || (map.get(currentNode.getA() + 1).get(currentNode.getB()) != currentNode.getC())){ + ++perimeter; + } + else if(!traversedNodes.contains(downNode)){ + Triple downPlot = calculatePlot(downNode); + perimeter += downPlot.getB(); + area += downPlot.getC(); + } + //If the left of the node is a perimeter add the value, otherwise traverse to that node if it hasn't already been traversed + if((currentNode.getB() <= 0) || (map.get(currentNode.getA()).get(currentNode.getB() - 1) != currentNode.getC())){ + ++perimeter; + } + else if(!traversedNodes.contains(leftNode)){ + Triple leftPlot = calculatePlot(leftNode); + perimeter += leftPlot.getB(); + area += leftPlot.getC(); + } + + //Create the new plot from the derived values and return it + return new Triple(currentNode.getC(), perimeter, area); + } +} + + +/* +Find the total price of fencing for the area. +The total price of fencing is 1434856. +It took 1.041 seconds to run this algorithm. +*/ diff --git a/src/main/java/com/mattrixwv/adventOfCode24/days/Problem24.java b/src/main/java/com/mattrixwv/adventOfCode24/days/Problem24.java new file mode 100644 index 0000000..a0d282a --- /dev/null +++ b/src/main/java/com/mattrixwv/adventOfCode24/days/Problem24.java @@ -0,0 +1,260 @@ +package com.mattrixwv.adventOfCode24.days; + + +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +import com.mattrixwv.Stopwatch; +import com.mattrixwv.Triple; + + +public class Problem24 extends Problem{ + private static final String inputFileName = "days/Problem23.txt"; + private List> map; + private List> traversedNodes; + + + public Problem24(){ + super(); + description = "Find the total price of fencing for the area."; + result = "Unresolved"; + } + + + public String runSolution(){ + Stopwatch timer = new Stopwatch(); + timer.start(); + + + //Read the file + /* */ + map = new ArrayList<>(); + try(Scanner scanner = new Scanner(this.getClass().getClassLoader().getResourceAsStream(inputFileName))){ + scanner.useDelimiter("\n"); + while(scanner.hasNext()){ + String mapLine = scanner.next(); + if(!mapLine.isBlank()){ + List charLine = new ArrayList<>(mapLine.length()); + for(Character ch : mapLine.toCharArray()){ + charLine.add(ch); + } + map.add(charLine); + } + } + } + /* */ + /* + map = List.of( + List.of('R', 'R', 'R', 'R', 'I', 'I', 'C', 'C', 'F', 'F'), + List.of('R', 'R', 'R', 'R', 'I', 'I', 'C', 'C', 'C', 'F'), + List.of('V', 'V', 'R', 'R', 'R', 'C', 'C', 'F', 'F', 'F'), + List.of('V', 'V', 'R', 'C', 'C', 'C', 'J', 'F', 'F', 'F'), + List.of('V', 'V', 'V', 'V', 'C', 'J', 'J', 'C', 'F', 'E'), + List.of('V', 'V', 'I', 'V', 'C', 'C', 'J', 'J', 'E', 'E'), + List.of('V', 'V', 'I', 'I', 'I', 'C', 'J', 'J', 'E', 'E'), + List.of('M', 'I', 'I', 'I', 'I', 'I', 'J', 'J', 'E', 'E'), + List.of('M', 'I', 'I', 'I', 'S', 'I', 'J', 'E', 'E', 'E'), + List.of('M', 'M', 'M', 'I', 'S', 'S', 'J', 'E', 'E', 'E') + ); + /* */ + /* + map = List.of( + List.of('A', 'A', 'A', 'A', 'A', 'A'), + List.of('A', 'A', 'A', 'B', 'B', 'A'), + List.of('A', 'A', 'A', 'B', 'B', 'A'), + List.of('A', 'B', 'B', 'A', 'A', 'A'), + List.of('A', 'B', 'B', 'A', 'A', 'A'), + List.of('A', 'A', 'A', 'A', 'A', 'A') + ); + /* */ + /* + map = List.of( + List.of('E', 'E', 'E', 'E', 'E'), + List.of('E', 'X', 'X', 'X', 'X'), + List.of('E', 'E', 'E', 'E', 'E'), + List.of('E', 'X', 'X', 'X', 'X'), + List.of('E', 'E', 'E', 'E', 'E') + ); + /* */ + /* + map = List.of( + List.of('A', 'A', 'A', 'A'), + List.of('B', 'B', 'C', 'D'), + List.of('B', 'B', 'C', 'C'), + List.of('E', 'E', 'E', 'C') + ); + /* */ + + + // = + traversedNodes = new ArrayList<>(); + List> plots = calculatePlots(); + + + int totalPrice = 0; + for(Triple plot : plots){ + totalPrice += (plot.getB() * plot.getC()); + } + + + //Save the result + timer.stop(); + result = "The total price of fencing is " + totalPrice + ".\nIt took " + timer.toString() + " to run this algorithm."; + return result; + } + + + // = + private List> calculatePlots(){ + List> plots = new ArrayList<>(); + + //Traverse the map and start a plot anywhere that hasn't already been traversed + for(int row = 0;row < map.size();++row){ + for(int col = 0;col < map.get(row).size();++col){ + //If the current node hasn't been traversed calculate the plot that this node is a part of + Triple currentNode = new Triple<>(row, col, map.get(row).get(col)); + if(!traversedNodes.contains(currentNode)){ + List> plot = calculatePlot(currentNode); + //Calculate the sides + int numSides = calcSides(plot); + Triple plotStats = new Triple<>(map.get(row).get(col), numSides, plot.size()); + plots.add(plotStats); + } + } + } + + return plots; + } + + private List> calculatePlot(Triple currentNode){ + //Add the current node to traversed nodes + traversedNodes.add(currentNode); + List> plots = new ArrayList<>(); + plots.add(currentNode); + + //Create the new possible nodes + Triple upNode = new Triple<>(currentNode.getA() - 1, currentNode.getB(), currentNode.getC()); + Triple rightNode = new Triple<>(currentNode.getA(), currentNode.getB() + 1, currentNode.getC()); + Triple downNode = new Triple<>(currentNode.getA() + 1, currentNode.getB(), currentNode.getC()); + Triple leftNode = new Triple<>(currentNode.getA(), currentNode.getB() - 1, currentNode.getC()); + + //If the top of the node is a perimeter add the value, otherwise traverse to that node if it hasn't already been traversed + if((currentNode.getA() > 0) && (map.get(currentNode.getA() - 1).get(currentNode.getB()) == currentNode.getC()) && (!traversedNodes.contains(upNode))){ + List> upPlots = calculatePlot(upNode); + plots.addAll(upPlots); + } + //If the right of the node is a perimeter add the value, otherwise traverse to that node if it hasn't already been traversed + if((currentNode.getB() + 1 < map.get(currentNode.getA()).size()) && (map.get(currentNode.getA()).get(currentNode.getB() + 1) == currentNode.getC()) && (!traversedNodes.contains(rightNode))){ + List> rightPlots = calculatePlot(rightNode); + plots.addAll(rightPlots); + } + //If the bottom of the node is a perimeter add the value, otherwise traverse to that node if it hasn't already been traversed + if((currentNode.getA() + 1 < map.size()) && (map.get(currentNode.getA() + 1).get(currentNode.getB()) == currentNode.getC()) && (!traversedNodes.contains(downNode))){ + List> downPlots = calculatePlot(downNode); + plots.addAll(downPlots); + } + //If the left of the node is a perimeter add the value, otherwise traverse to that node if it hasn't already been traversed + if((currentNode.getB() > 0) && (map.get(currentNode.getA()).get(currentNode.getB() - 1) == currentNode.getC()) && (!traversedNodes.contains(leftNode))){ + List> leftPlots = calculatePlot(leftNode); + plots.addAll(leftPlots); + } + + //Create the new plot from the derived values and return it + return plots; + } + + private int calcSides(List> plot){ + int sides = 0; + List> sidePoints = new ArrayList<>(); + + //Loop through every element in the plot + for(Triple element : plot){ + //Check if the top is an edge and doesn't already have a point in the list + if(!plot.contains(new Triple<>(element.getA() - 1, element.getB(), element.getC())) && (!sidePoints.contains(new Triple<>(element.getA(), element.getB(), '^')))){ + //Add this element to the list + sidePoints.add(new Triple<>(element.getA(), element.getB(), '^')); + //Add all elements to the right that are in the plot and continue to have a top edge + Triple nextElement = new Triple<>(element.getA(), element.getB() + 1, element.getC()); + while(plot.contains(nextElement) && (!plot.contains(new Triple<>(nextElement.getA() - 1, nextElement.getB(), nextElement.getC())))){ + sidePoints.add(new Triple<>(nextElement.getA(), nextElement.getB(), '^')); + nextElement = new Triple<>(nextElement.getA(), nextElement.getB() + 1, nextElement.getC()); + } + //Add all elements to the left that are in the plot and continue to have a top edge + nextElement = new Triple<>(element.getA(), element.getB() - 1, element.getC()); + while(plot.contains(nextElement) && (!plot.contains(new Triple<>(nextElement.getA() - 1, nextElement.getB(), nextElement.getC())))){ + sidePoints.add(new Triple<>(nextElement.getA(), nextElement.getB(), '^')); + nextElement = new Triple<>(nextElement.getA(), nextElement.getB() - 1, nextElement.getC()); + } + //Increase the number of sides + ++sides; + } + //Check if the right is an edge and doesn't already have a point in the list + if(!plot.contains(new Triple<>(element.getA(), element.getB() + 1, element.getC())) && (!sidePoints.contains(new Triple<>(element.getA(), element.getB(), '>')))){ + //Add this element to the list + sidePoints.add(new Triple<>(element.getA(), element.getB(), '>')); + //Add all elements to the bottom that are in the plot and continue to have a right edge + Triple nextElement = new Triple<>(element.getA() + 1, element.getB(), element.getC()); + while(plot.contains(nextElement) && (!plot.contains(new Triple<>(nextElement.getA(), nextElement.getB() + 1, nextElement.getC())))){ + sidePoints.add(new Triple<>(nextElement.getA(), nextElement.getB(), '>')); + nextElement = new Triple<>(nextElement.getA() + 1, nextElement.getB(), nextElement.getC()); + } + //Add all elements to the top that are in the plot and continue to have a right edge + nextElement = new Triple<>(element.getA() - 1, element.getB(), element.getC()); + while(plot.contains(nextElement) && (!plot.contains(new Triple<>(nextElement.getA(), nextElement.getB() + 1, nextElement.getC())))){ + sidePoints.add(new Triple<>(nextElement.getA(), nextElement.getB(), '>')); + nextElement = new Triple<>(nextElement.getA() - 1, nextElement.getB(), nextElement.getC()); + } + //Increase the number of sides + ++sides; + } + //Check if the bottom is an edge and doesn't already have a point in the list + if(!plot.contains(new Triple<>(element.getA() + 1, element.getB(), element.getC())) && (!sidePoints.contains(new Triple<>(element.getA(), element.getB(), 'v')))){ + //Add this element to the list + sidePoints.add(new Triple<>(element.getA(), element.getB(), 'v')); + //Add all elements to the left that are in the plot and continue to have a bottom edge + Triple nextElement = new Triple<>(element.getA(), element.getB() - 1, element.getC()); + while(plot.contains(nextElement) && (!plot.contains(new Triple<>(nextElement.getA() + 1, nextElement.getB(), nextElement.getC())))){ + sidePoints.add(new Triple<>(nextElement.getA(), nextElement.getB(), 'v')); + nextElement = new Triple<>(nextElement.getA(), nextElement.getB() - 1, nextElement.getC()); + } + //Add all elements to the right that are in the plot and continue to have a bottom edge + nextElement = new Triple<>(element.getA(), element.getB() + 1, element.getC()); + while(plot.contains(nextElement) && (!plot.contains(new Triple<>(nextElement.getA() + 1, nextElement.getB(), nextElement.getC())))){ + sidePoints.add(new Triple<>(nextElement.getA(), nextElement.getB(), 'v')); + nextElement = new Triple<>(nextElement.getA(), nextElement.getB() + 1, nextElement.getC()); + } + //Increase the number of sides + ++sides; + } + //Check if the left is an edge and doesn't already have a point in the list + if(!plot.contains(new Triple<>(element.getA(), element.getB() - 1, element.getC())) && (!sidePoints.contains(new Triple<>(element.getA(), element.getB(), '<')))){ + //Add this element to the list + sidePoints.add(new Triple<>(element.getA(), element.getB(), '<')); + //Add all elements to the top that are in the plot and continue to have a left edge + Triple nextElement = new Triple<>(element.getA() - 1, element.getB(), element.getC()); + while(plot.contains(nextElement) && (!plot.contains(new Triple<>(nextElement.getA(), nextElement.getB() - 1, nextElement.getC())))){ + sidePoints.add(new Triple<>(nextElement.getA(), nextElement.getB(), '<')); + nextElement = new Triple<>(nextElement.getA() - 1, nextElement.getB(), nextElement.getC()); + } + //Add all elements to the bottom that are in the plot and continue to have a left edge + nextElement = new Triple<>(element.getA() + 1, element.getB(), element.getC()); + while(plot.contains(nextElement) && (!plot.contains(new Triple<>(nextElement.getA(), nextElement.getB() - 1, nextElement.getC())))){ + sidePoints.add(new Triple<>(nextElement.getA(), nextElement.getB(), '<')); + nextElement = new Triple<>(nextElement.getA() + 1, nextElement.getB(), nextElement.getC()); + } + //Increase the number of sides + ++sides; + } + } + + return sides; + } +} + + +/* +Find the total price of fencing for the area. +The total price of fencing is 891106. +It took 1.502 seconds to run this algorithm. +*/ diff --git a/src/main/resources/days/Problem23.txt b/src/main/resources/days/Problem23.txt new file mode 100644 index 0000000..5fc3f40 --- /dev/null +++ b/src/main/resources/days/Problem23.txt @@ -0,0 +1,140 @@ +SSSSSOOOOOBFFJJFTFBBBBBBBBPPPPPPPPBBBBBBBBBBBSSDDDDDDCCCCCCCCCCCUUUUUAAAAAAAAAAAAAAAUUUUUUUUUUUUUUUUUUUUUUDDDDDDMMMMMZZFFZZFFFFFFFFFFFFFFFII +SSSOOOOOFFFFFFJFFFFBBBBBBBPPPPPPPPPBBBBBBBBBSSSSSSSSDDCCCCCCCCCUUUUUUUUAAAAAAAAAAAAAUUUUUUUUUUUUUUUUUUUUUUUDDDDDMMMMZZZZFZZFFFFFFFFFFFFFFFII +OOSOOOOOFFFFFFJFFFFBBBBBBPPPPPPPPPPBBBBBBBBBBSSSSSSSDCCCCCCCCUUUUUUUUUUUUAAAAAAAAAAUUUUUUUUUUUUUUUUUUUUUUDDDDDDDDDDZZZZZZZFFFFFFFFFFFFFFFFII +OOOOOOOOFFFFFFFFFFFHBBBBBBPPPPPPPPPBBBBBBBBBBSSSSSSSDCCCCCCCUUUUUUUUUUGGUAAAAAAAAAUUUUUUUUUUUUUUUUUUUUUDVDDDDDDDDDDZZZZZZZZFFFFFFFFFFFFFFFII +OOOOOOOOOFFFFFFFFFFFFBBBBPPPPPPPPPPPBBBBBSSSSSSSSSSSDXXCYCCCUUUUUUUUUUUUUAAXXAAAAUUUUUUUUUUUCUUUUUUUUUUDDDDDDDDDRDHZZZZZZZZFFFFFFFFFFFFFFFII +OOOOOOOOOOFFFFFFFFFFFFFFBPPPPPPPPPPPBPPPBBSSSSSSSSXXXXXCXXCCUUULUUUUUUUUUUAXXXAAAUUUUUUCCCCCCCCCSUUUUUUDDDDDDDDFRRFZZZZZZZZZZZFFFFFFFFFFFFII +OOOOOOOOOOFFFUFFFFFFFFFFIPPPPPPPPPPPBBPPBBSSSSSSSMMMXXXXXXWUUUUUUUUUUUUUUCXXXXXXXWWWUUCCCCCCCCCCSUUUUUDDDDDDDDXFFFFZZZZZZZZZZZFFFFFFFFFFFFII +COOCOOOOOOKFFUFUUUFFFFFIIPPPPPPPPPPPPPPPPPSSSSSSSSMXXXXXXXUUUUUUUUUUUUUUUUUUXXXXXXXWWWCCCCCCCCCCSSSUUUUUDDDDDDFFFKFFZZZZZZZZFFFFFFFFFFFFIIII +COCCCOOOOOKFUUUUUUFFFFFIIIIPPPPPPPPPPPPPPIITSSSSSIXXXXXXXXUUUUUUUUUUUUUUUXXXXXXXXXWWWWWCCCCCCCCSSSSSSSSUUDDDDDFFFFFFZZZZZZZZFFFFFFFFFQQQIIII +CCCCCCCOKOKKUUUUUUFFFFFIIIIPPPPPPPPPPPPPPIIIIISIIIIXXXXXXXUUUUUUUUUUUUUUUXXXXXXXXXWWWCCCCCCCCCGSSSSSSSSSUDDDDFFFFFFFZZZZZZZZMZFFFXFSQQFQQQII +CCCCCCCCKKKKKKUUUUFUUKKIIIIPPPPPPPPPPPPPPIIIIIIIIIIIIIXXXXXURUUUUUUNUNUUXXXXXXXXXXWWWWCCCCCCCCSSSSSSSSSKKDDDDFFFFFFZZZZZZZZZZZXFFXFFFQQQQQII +CCCCCCKKKKKKKKUUUUUUKQKKIIIIIPPPPPPPPPPPPIIIIIIIIIIIIIXXXXXURUKKUUNNNNUXXXXXXXXTXXWCCCCCCCCCCCISSSSSSSSKKKKDDSFFFZZZZZZZZZZZZZXXXXFQQQQQQQQI +CCCCCCCCKKKKKKUUUUUUKKKKKLLIIPPPIPPPPPPPPPIIIIIIIIIIIIXXXXXXRSSSUUNNNNUNXXXXXXZXXWWCCCCCCCCCSSSSSSSSSSSSSKKKDSSZZZZZZZZZZZZZZZXXXXFFGQQQQQQQ +CCCCCCCCCCUKKKUUUUUUUUKKLLLIPPPIIIPPPPPPPIIIIIINIIIIIIIIXXXXSSSSNNNNNNUNXXXXXXZXXXCCCCCCCCCCCSSSSSSSSSSSSKKKSSSZZZZZZZZZZZZFFFFFXXFFFQQQQQQQ +CCCCCCCCCUUUUKUUUUUUULKKLLLLLIIIIIPPPPPPPIIIIKKNIIIINIIIISXXSSSSGGGNNNNNNNXQZZZZZXXXXCCCXCSCCCSSSSSSSSSSSKKKSSSSZZZSZZZZZZZFDFFFFFFFWQQQQQQQ +CCCCCCCCCUUUUUUUUUUUULLLLLLLLLLIIIPPPPPPPKIIKKBNNNNNNNNSSSUXSSJGGGGGNNNNNQQQZZZXZXXXXCCCXXSSSSSSSSSSSSSSSKKSSSSSZSSSZSZZZFFFDFFFFFFFQQQQQQQQ +CCCCCCCCCUUUUUUUOULLLLLLLFLMLLIIIIPPPPPKKKIEEKKNNNNNNNNSSUUSSSJJGGGNNLNNNQQQQZZXXXXXXXXXXXXXXSSSSTSSSSSKKKKKKSSSSSSSSSSZZJFFDFFFFFFFFQQQQQQQ +CCCCCCCCCUJJJJJJUULLLLLLLLLLIIIIIIPPPKKKKKEEKKKNNNNNNNNNSSSSSSSGGGGNNLNNNQQQQQXXXXXXXXXXXXXXXTSSSTSSSSSKKKKKSSSSSSSSSSSZZFFFFFFFFFFFFQQQQQQQ +CCCCCCKKKUUJJJJJJJLLLLLLLLLLLIIIIIIPKKKKKKKKKKKNNNNNNNNNSSSSSSSGGGGGGLLLNQQQQQQQXXXXXXXXXXXXXTSTTTTTSSSKKKKSSSSSSSSSSSSSSSFFFFFFFFFFQQQQQQQQ +CCCCFFFFFFJJJJJJJLLLLLLLLLLLLLIIIIPPKKKKKKKKKKNNNNNNNNNXXXSSMMMGGGLLLLLLNQNQQQQQXXXXXXXXXXXXXTTTTTTTTTSHKKSSSUSSSSSSSSSSSZFFFFFFFFFFQQQQQQQQ +CCCCFFFFFFFJJJJJJLLLLLLLLLLLLLIIIHHPPKKKKKKKKKKKNNNNNNNNXXXSMMLLLLLLLLLNNNNNQQQQQXXXXXXXXXTXTTTTTTTTTTTHKSSSSSSSSSSSSSSSSSFFFFFFFFFQQQQQQQQQ +CCCCFFFFGFFJJJGJJJJJLLLLLKKLLLIIIHHKKKKKKKKKKKKKNNNNNNNXXXXSMMMLLLLLLLLNNNNNQQQQQQXXXXXXXXTTTCCTTTTTTTHHHHHDSSLSSLSSSSSSSSFFFFFFFFFQQEEQQQQQ +CCFGFFFFFFFFGGGJGJJLLLLLUEELILIIIKKKKKKKKKKKIKKUNNNNNNXXXXXXXLLLLLLLLLLLQQQQQQQQQQQXXXXXXXXCTCTTTTTTTTTHHHHHIILLLLSSSSSSHHHFHFFFFFFEEEEEQEQQ +CCFFFFFFFFFFGGGGGJJLLLLLUEESIIIIIIDDKKKKKKKKUUUUNNNNNNXXXXXXZZLLLLLLLLLLLQQQQQQQQQQQXXXXXXJCCCCTTTTTTTTHHIIHIIIWLLSSSQQSHHHHHHFFFFFFEEEEEEQQ +XFFFFFFFFFFFGGGGGGJHLLLLUEEIIIIIIIDDDDKYKKKKKUUUUNUUNNCXXXXXXZZLLLLLLLLBLMBQQQQQQQQQXXCCCXCCCCCTTTTTTTHHHIIIIIWWQQQQQQQSSHHHHHFFFPPFEEEEEEQQ +FFFFFFFFFFFGGGRGGPHHLHHLLEEEIIIIIDDDDDUYYKKKKUUUUUUUWWXXXRXXXKKKKKKLLLBBBBBQQQQQQQCCXXCCCCCCJCCTTTTTTTTHFIIIIIIWWQQQQQQJHHHHHHHJJPEEEEEEEIEQ +FFFFFFFFFCFFFGRRPPHHHHHELEEEEEEIDDDDDUUUYYYKUUUUUUUWWWWWXXXKKKKKKKLLLBBBBBBQQQQQQQQCCCCCCCCCCCCFTTTTFTTFFFIFIWWWWQQQEQQJJHHHHHJJJJJJXEEEEEEQ +FFFFFFFFFFRFRRRRPPHHHHEEEEEEEEEEEDDDDUUUUUKKUUUUUUWWWWWWXKKKKKKKKKLLLBBBBBBQQQQQQQCCCCCCCCCCCCGFFFFFFFTFFFIFIWWWWEEQEQQJJJHJJJJJJJJJJJREQQEQ +FFFFFFFFFFFFFFPPPPPHPEEQEEEEEEEEEEDEUUUUUUUUUUUUUUUWWWWWWKKKKKKKKKKLLBKBBBBBBQQQQCCCCCCCCCCCCCCAFFFFFFFFFIIFIIIWWEEEEQJJJHHJJJJJJJJJJJJJJQEQ +FFFFFFFFFFFFPPPPPPPPPEEEEEEEEEEEEEEEUUUUUUUUUUUUUUUWOXXXXKKKKKKKKKLLLBBBBBBBBBBQQCCCCCCCCCCCCCCCFFCCCFCFFFFFFFFWWEEEEEJJJJJJJJJJJJJJJJJJJQQQ +FKFFFFFFFFFFFPPPPPPPPPEEEEEEEEEEEEEEUUUUUGUUUUUUUWUWOVVXXKKKKKKKKKLBLBBBBBBBBBQQQCCCCCCCCCCCCCCCFCCCCCCFFFFFFFFWEEEWWEJJJJJJJJJJJJJJJQJQJQQQ +KKFFFFFFFFFFFPPPPPPPPPPEEEEEEEEEEHELLLUUUGUUUUUWWWWWOOOXXXWWKKKKKILBBBBBBBBBBOQQQQCCCCCCCCCCCCCCCCCCCGCFFFFKKKAWWWWWWWWJJJJJJJJJJJJJJJJQJQQQ +KKKKKFFFFFKFPPPPPPPPPPEEEEEEEEEEEELLLLLGGGGUUUUWWPWOOCOOOXWWKKKKKIBBBBBBBBBBBOOQQCCCCCCCCCCUUUCCCCCGGGGFFFKKKAAAAAWWWWWWJJJJJJJJJJJJQQQQQQQQ +KKKKKFFFFFKKKPPPPGGGGPIEEEEEEEEEELLLLLLLGRRRUCUPPPPOOOOOOOWWWKKKIIIBBBBBBBBBBBOQOCCCCCCCCCUUUUUCCGGGGGGFCEAAAYAAAAWWAAWWJJJJJJJJJJJJJQRQQQRQ +KKKKKKFFKFKKPPPGGGGTTEEEEEEEEEEEELLLLRRLLRRRRUUNPPPVOIORROWXXXMKKXXBBBBBBBBBBBOOOOOOCCCCCUPUUUUUUGGGGGCCCAAAAAAAAAAAAAWWNJJJJJJJJJJJJQRRQRRQ +KKKKKKFKKKKKKPPGGGGGGGSSSSEEEEEQUUUURRRRRRRRGGGPPPVVPPKRRWWXXXMKXXXBBBBBBBBBBBOOOOOOCCCUUUPUUUUUUUGGGGGCCAAAAAAAAAAAAAANNNNJJJJJJJJJQQRRRDRR +KKKKKKKKKKKKKGGGGGGGGGGSSSEPEEEQUUUUUURUUUUUGGPPPPVPPNRRRRRXXXXXXXXXBBBBBBBBBBBBBOOOOOUUVUUUUUUUYYGGGGRCCAAAAAAAAAAAAAANNNNNNJJJJJQQQRRRRRRR +KKKKKKTKKTKKTTSSGGSGSGGSSSPPFEZUUUUUUUUUUUUUPGPPPPPPPPBRRRRXXXXXXXXXXBXBBBBBBBBBBBOOOOUUUUUUUUUUUUAAGGRCAAAAAAAAAAAAAAAGNNNNNJJJJJQQRRRRRRRR +KKKKTTTTTTTTTTSSGGSSSSSSSSPPFPZUUUUUUUUUUUUPPPPPPPPPMPRRREEXXXXXXXXXXXXBBBBBOBBBOOOOOUUUUUUUUUUUUAAGGGGAAAAAAAAAAAAAAAAANNNNNNJJJJJJRRRRRRRR +KKKKKTWTTTTTTTTSSSSSSSPSPPPPPPUUUUUUUUUUUUUUPPPPPPPPPKRRREXXXXXXXXXXXXXVBBBOOOOOOOOOOUUUUUUUKUUUUAAGVVVVAAAAAAAAAAAAAUUUNNNNNNJJJJJRRRRRRRRR +KKKKKTTTTTTTTTTSSSSSSSPPPPPPPPJUUUUUUUUUUUUPPPPPPPPPPPPPPEEXXXXXXXXXXXXXXFBEEOOOOOOOAUUUAAUUUUUDAAAWYVYAAAAAAAAAAAAAAUUUNNNNNNNRRRRRRRRRRRRR +KKKKTTTTTTTTTTTSSSSSSSPPPPPPPPPURUUUUUUUUUPPPPPPPPPPPRPPPEEEEEXXXUXXXXXXXFFEEOOOOOOOAUUUAAUAUUUAAAAWYYYYYAIAJAAAAAUUUUNNNNNNNNNTRRRRRRRRRRRR +KKKKTTTTTTTTTTSSSSSSPPPPPPPPPPSSUUUUUUUUUUUPSPPPPPPPPPPJPREEEEXXXUUXXXXXCEEEOOOOAOAAAAAAAAAAAUAAAAAYYYYYYQAAAAAAAAUUUUUNNAANNIITTRTRRRRRRRRR +KKKKKTTTTTTSSSSSSSSPPPPPPPPPPPPPPUUUUUUUUUGPPPPPPPPPPPJJJRRRRRXXXOUUUXXXCEEEOOOOAAAAAAAAAAAAAAAAAAAYYYYYYYYYAAAAAAUUUUUUUATTTTTTTTTRRRRRRRRR +KKKKKTTTTTTSSBSSSSSSSPPPPPPPPPPPUUUUGGUUUGGGGGPPPPPJJJJJRRRRRRRRUUUUUSXCCEEEOOOGAAAAAAAAAAAAAAAAAYYYYYYYYYBYYBBAAUUUUUUUUUTTXTTTTTTTTRRRRRRR +KKBKBBTTTTBBBBSSSSSSSSPPPPPPPPPPPUUGGGCGUGGGGGPPPPJJJJJJJRRRRRUUUUUUUUXUEEEEEEEGGAAAAAAAAAAAAAAAAYYYYYYYYYYYBBBBUUUUUUUUUTTTTTTTTTTBBBBRRRRR +KBBBBBBTTBBBBBSSSSSSSSPPPPPPPPPPPPUJGGCGGGGGGGGPXPPJJJJJRRRRRRUUUUUUUUXUVEEEEEEGGGGAAASAAAAAAAAAAYYYYYYYYYYBBBBBUUUUUUUUUTTTTTTTTTTBBBBRRRRR +KKKBBBBBTBBBBBSSSSSSSSPXPPPPPPPPPSSGGGGGGGGGGGPPPPZZZZJJZZNRRRUUUUUUUUUUUEEEEGGGGGIIIIAAEUUUUAAAAYYYYYYYYYYBBBBUUUUUUUUUBBBTTTTTTTTTBBBRRRRR +KKBBBBBBBBBBBBBSSSSSPPPPPPPPPYPSPSSSGSGGGGGGGGPPPZZZZZJZZNNNRRRUUUUUUUUUEEEEEEGGIIIISAAAUUUUWAACYYYYYYYYYYYBBBBBUUUUUUUUBBTTTTTTTTTBBBBRRRRR +KKKBBBBBBBBBRBBBBSSSSSPPPPPPPPSSPPSSSSGGGGGGGGPPZZZZZZZZNNNUUUUUUUUUUUUUUEEEEEEEEEIIIIAAUUUIWAAYYYYYYYYYPBBBBBBBBUUUUUUUBBTTTTTTOOTBBBBRRRRR +OOKKBBBBBBBBBBBBSSSSSSPPPPPPPPSSPPSSSSGGSGGGGGGZZZZZZZPZNNNUUUEEUUUUUUUEEEEEEEEEEIIIIAAIIIIIIIIIIIYYYYYYPBBBBBBBBBBUUUBBBBBBYYYYOONNNBRRRRRR +OOOOOOBBBBBBBBBBBBSSSSPPPKPMPPSSSSSSSSSSSGGGGGGZZZZVVZZNNNNNNEEEUUULUUUULLEEEEEEEIIIIIIIIIIIIIIIIIYYYYPPPBBBBBBBBBBBBBBBBBBBYOYYOONNNNPRRPRP +OOOOOOBBBBBBBBBBBFVSSSPMMMMMMMSSSSSSSSSSSGGGGGGCCZZVZYZNNWWNWEEEUULLULLLLLEEEEEEEIIIIIIIIIIIIIIIIIYYYYQPPBPBBBBBBBBBBBBBBBBBBOYOOOONVVPPPPRP +OOOOOOOBBBBBVVBVTVVSSVMMMMMMMSSSSSSSSSSSGGGGGXCCCCZZZZKKKKKKKKKKELLLLLLLLLEEEEEEEIIIIIIIIIIIIIIPIIIUUPPPPPPBBBKBBBBJJJBBBBBOOOOOOOONVVPPPPPP +OOOOOOOBBBBBVVVVVVQVSVMMMMMMMSSSSSSSSSSSSVGGGXXCMMZZZZKKKKKKKKKKELLLLLLLLEEEEEEEEIIIIIIIIIIIIIIPPPPPPPPPPBBBKBKKKKBJJJBBBBOOOOOOOOONVVPPPPPP +OOOOOOOOOBXVVVVVVVVVVVVMMMMMYSSSSSSSSSSASVVAGXCCMVZMZMKKKKKKKKKKELLLLLLLLLEEEEEIIIIIIIIIIIIIIIIPPPPPPPPPCBBKKKKKKKBJJJBBBBOOOOOOOOOOXXXXPPPP +OOOOOOOOOXXXVVVVVVVVVMMMMMCMSSSSSSSSSSSVVVXGGXMMMVMMMMKKKKKKKKKKQLLLLLLLEEEEIEIIIIIIIIIIIIIIIIIIIPPPPPPPCPBCKKKKKKJJJJJJJJOOOOOOOOOOXXXXXPPP +OOOOOOOOOZXXVVVVVVVVVMTMCMCCSSSSSSSSSSSVVVXXXXMMMMMMMAKKKKKKKKKKLLLLLLLLLLIIIIIIIIIIIIIIIIIIIIIIPPPPPPPPPPBBKKKKKKJJJJJJJJJJJJOOOOOOXXXXXXMM +OOOOOOOOOXXXVVVVVVVVVVVVCCCCCSSSSSSSSSVVVXXXVVMMMMMMMMKKKKKKKKKKLLLLLLLLLKIIIIIIIIIIIIIIIIIIIIIHPPPPPPPPPPBBBKKKKKJJJJJJJJJJJJOOXOOOXXXXXXXM +OOOOOOGOOXXXXXVVVVVVVVVVCCCCCCSSSSSSSSVVVVXXVMMMMMMMMMKKKKKKKKKKLLLLLLLLLKIIKIIIIIIIIIIIIIIIHHHHHPPPPPPPPPQQQQKKKKJJJJJJJJJJJJXXXXXXXXXXXXXM +OOOOOOOOOXXXXXVVVVVVVVVVCCNNCCSSSSSSSSSVVVXXVVMMMMVMMVVVVWWWWWWWLLLLLLLLLKIIKKKIIIIIIIIIIIIIHHHPPPPPPPPPPWOQQQQQQQJJJJJJJJJJJJOSAAXXXXXXXXXM +OOOOOOOOOOXCECCCVVVVVVVCCCNNNCSSSSSSSVVVVVVXVVVMVVVMMVVVVVWWWWWWLLLLLLLLLKKIKKKIIIIIIIIIIIIHHHHPPPPPPPPPXOOQQQQQQQJJJJJJJJJJJJSSWWXXXXXXXXXM +OOOOOOOOOOCCCCCVVVVVCCCCCNNVNSSSSSSVVVVVVVVVVVVMVVVVVVVVVVVLWWWWWLLLLLLLLLKKKCCCCCICIIIIIIHHHPPPPVVVPCCPPOOQQQQQQQJJJJJJJJJJJJSSWWWWXXXXXXXX +OOOOOOOOCCCCCCCCCVVVVCCCCNNNNNNSSSSVVVVVVVVVVNNZZZVVIVVVVVVLLLWWLLLLLLLLOODKKKCCCCCCIIIIBIHHHTTPPOOOCCPPPOOOOOQOXQJJJJJJJJJJJJJSWWWWWXXXXXXX +OOOOOOOOOCYCCCCCCVVVCCCCNNNNNNNSSSSSVVVVVVVVVVNZZZZZIVVVVVVLLLLLLLLLLLLLLDDDDCCCCCCIIIIIIIHHHTTPPFOCCCOOOOOOOOOOXQWWWJJJJJJJJJJSSWWWWXXXXXXR +OOOOOOOOYYYCCCCCCVVCCCCNNNNNNNNNNNVVVVVVVVVVVVNNVVZIIVVVVVVLLLLLLLLLLLLZZDDDZCCCCCCCIIIIIIHHHHHPPFOCCCOOOOOOOOXXXXXXWJJJJJJJJJJSWWWWWWXXXXXX +OOOOOOOYYYYYCCCCCCCCCCCNNNNNNNNNCOVVVVVVVVVVZZNSGVVVVVVVVVVLLLLLLLLLLLLLZDDZZCCCCCCIIIIIIHHHHHHFFFOOOOOOOOOOOOOXXXXXWJJJJJJOSDSWWWWWWWXXXXXX +OOOOOYYYYYYYCCCCCCCCCCCNNNSNNNNNCCVVVVVVVZZVVZFSGGGGVVVVVVVMLLLLLLLLLLLLZZZZZCCCCCCCTIIITTTHHHHFFFOOOOOOOOOOOOOOOXXXXXWXXXOOSDWWWWWWWWWXXXXX +OOOYOYYYYYYYCCCCCSCCCCCCCNNNNNNNCCCVVVVZZZZZZZSSSGGMLVVVVVHMMMMMMLLLLLZZZZZZZZCCCCTTTTITTTTBFFFFFFOOOOOOOOOOOOOXXXXXXXXXXXOOOWWWWWWWWWWXXXXM +OOOYYYYYYYYYYGGCCSSSSCCCNNNNNCCCCCCVVZZZZZZZZZZZZMMMLVVVVMMMRLLBLLFFFFFFFFFFZZCXCCCTTTITTTTBBFFFCFOOOOOOOOOOOOXXXXXXXXXXXXXOOXWWWWWWWWWWWMXM +OOOYYYYYYYYGGGGCCCCSSSCCCNNNNNCCCCKVVNNZZZZZZZZZZZKMMVVVVMMMRLLLLLFFFFFFFFFFZZCCCCZATTTTTTTBFFFCCCOOOOOOOOXXOXXXXXXXXXXXXXWXXXSSSWWWWMMMWMMM +OODBYYYYYYYGGGGGSSSSSSSCCCCCCCCCCCCNNNNNZZZZZZZZZMMMMMMMVMMMMMLOLZFFFFFFFFFFZZZZZZZAATTTTTTBBFCCCOOOOOOOOOOXXXXXXXXXXXXXXXXXXXSSSSWWMMMMMMMM +OBDBBBBBEYSGGGGGSSSSSSSSSCCCCCCCCCNNNNZZZZZZZZZZMMMMMMMMVMMMMMMMMZFFFFFFFFFFZZZZZAAAATTTTBBBFFCCBOOOOOOOOOOOOODDDXXXXXXXXXXXXXSSSSWHHMMMMMMM +BBBBBBBBBGGGGGGSSSSSSSSSCCCCCCCCCCCCZZZZZZZZZZZZMMMMMMMMMMMMMMMMMZZZZZZZZZZZZZZZZAAAAAATTBBBFFBBBIOIZZOZZOOOOOODDXXXXXXXXXXXXXSSHSSHMMHHHMMM +BBBBBBBBGGLGGGGGSSSSSSZZCCCCCCCCCCCCCCZZZZZZZZZZZMMMMMMMMMMMMMMMMZZZZZZZZZZZZZZZAYAAAAATBBBBBBBBBIIIZOOZZZZOODDDDDXXXXDXXXXXXXSSHSHHMMHHMMMM +BBBBBBBBGGGGGGAASSSSSSSSCCCCCCCCCCCCCCZZZZZZZZZZZMMMMMMMMMMMMMMMZZZZZZZZZZZZZZZAAAAAAAATTBBBBBBBBZIZZZZZZZZOODDDDDDDDDDDQQQXXSSSHHHHHHHHMMMM +BBBBBBBBBGGGFFSSSSSSSSCCCCCCCCCCCCCWCCCZZZZZZZZZZZZCMMMMMMMMMMMMZZZZZZZZZZZZZTZAAAAAAAAAAQQBBBBBZZZZZZZZZZZOOODDDDDDDDDQQQQXXSHHHHHHHHHHHYYM +BBBBBBBBBBBBBSSSSSSSSSCCCCCCCCCCCCCWCCCZZZZZZZZZZZZMMMMMMMMMMMMMZZZZZZZZZZZTTTZAAAAAAAAAAQQBBBBBZZZZZZZZZZZZDODDDDDDDDDQQQQQXXHHHHHHHHHHHLYY +BBBBBBBBBBBBBBSSSSSSSSCCCCCCCCCCCCWWCCZZZZZZZZZZZZZYMMMMMMMMMMYZZZZZZZZZZZTTTTTWBAAAAAAAQQQBBBBBWZZZZZZZZZZZDDDDDDDDDDDQQQQQQHHHHHHHHHHHHYYY +BBBBBBBBBBBBSSSSSSSSSSSCCCNNCCCWWWWWYYYZZZZZZZZZZYYYYYMMMKMKMMMKKZZZZZZZZZTTTTXBBBAAAAAAQQQBBBBBBZZZZZZZZZSZDDDDDDDDDDDQQQQQQQHHHHHHHHHHHYYY +EEBBBBBBBBBBSSSSSSSSSSSCCNNCCCZWWZWYYYYYYYZZZZZZZYYYYAMMMKKKMMKKKZZZZZZZZZKKKBBBBBVBAIAQQQQBBBOOZZZZZZZZZZZYDDDDDDDDDDDQQQQQQQHHHHHYHHHHYYYY +EEBBBBBBBBBBSSSSSSSSSSSSCNNCGCZZZZZZYYYYYYZZZZZZZYYYYAAMMKKKKKKKKKZZZZZZZZKZKBBBBBBBBBQQQQQQQBBBBZZXZZZZZZDDDDDDDDDDQDDDQQQQQQBHHHHYYHHHYYYY +EEBBBBBBBBBBSBBSSSSSSSSSSSNNZZZZZZZZYYYYYYYYZZXXYYYYAAAAMKKKKKKKNNNZZZZZZZZZBBBBBBBBJJJQQQQQQQXZZZZXZZZZZZFFFFDDDDDDQDDDDQQQBBBBYYYYHHYYYYYY +EEEBEEBBBBBBBBSSSSSSSSSJJJJJZZZZZZZYYYYYYYYYAXXXYYYYAAAEEKKKKKNKNNNNNZZNZZTBBBBBBBBBJJBQQQQQQQXXXXXXXXXZZFFFFDDDDDQDQDDDDQQQQQBBBYYYYYYYYYYY +EEEEEEBBBBBBBBBSSSSSJCSJJJJPZZZZZZZYYYYYYYXXXXXXXYYYXXDEEEEKKNNNNNNNNNNNNBBBBBBBBBBBBJBSOQQQVQXXXXXJJXXJZFFQQQQQDQQQQQDQQQQQQBBBYYYYYYYYYYYY +EEEEEEZEBBOOBBBSSSJBJCCJJJJJZZZZZZZYYYYYYXXXXXXXXXYXXXXEEEEKKNNNNNNNNNNNNNNBBBBBBBBBBBBOOOQQVXXXXJJJJJJJJFQQQQQQQQQQQQQQQQQQBBBBYYBYYYYYYYYY +EEEEEEZEOBOOBOBSSOJJJJJJJJJJJZZZZZZZCCCAAAAXXAAXXXXXXEEEEEEKKNNNNNNNNNNNNNNBBBBBCBBBBOOOOOQXXXXXYJJJJJJJJJQQQQQQQQYYQQQQQQQQBBBBBBBBBBYYYYYY +EEEEEEEEOOOOOOBOOOJJJJJJJJJJJTZZZZCCCCCCCAAAAAKXXOXOEEEEEEEKKNNNNNNNNNNNNNNNBBBCCCCOOOOOOWYYYYYYYJDDJJJJJJWQQQQQQQYYQQQQQQBBBBBBBBBBBBYYYYYY +EEEEEEEEOOOOOOOOOJJJJJJJJJJJJJJJFGCCCCCCCCCAKKKQXOOOEEEEEEEKKNNNNNNNNNNNNNNNNBCCCCCOOOOOOOYYYYYDDDDDJJJJJJWWQQQQYYYYYYQQQQBBBBBBBBBBRBYYYYYY +EEEEIEOOOOOOOOOOOJJJJJJJJJJJJJZZGGGGCCCCCCCKKKKKKOOEEEEEEEEEECCNNNNNNNNNNNNNNCCCCCOOOOOOOYYYYYYDDDVDDDJJJJWWQQQJYYYYYMMMMMMMMMMJJJJJRBYYYYYK +EEEIIROOOOOOOOOOJJJJJJJJJJJJJJJZGGGGZZCCUUKKKKKKKKOOHPPEEEEEECCNNNNNNNNNNNNNCCCCCCOOOOOOYYYYYYYYDVVVDAJAWWWWQQQDYYYYYMMMMMMMMMMDJJJJJOYKYKKK +ERRRRRRROOOOOOOOOJJJJJJJJJJJJJJZZGZZZCCCUUUKKKKKKKOOHHHPEECCCCCCNNNNNNNNNNNNCCCCYCOYYOOOYYYYYYDDDDVVDAAAAWWQQWDDYYYYYMMMMMMMMMMJJJJJJJYKKKKK +ERRRRRRRRROOOOOOOOJJJJJJJJJJJJJZZZZZZZZZZUUUUKKKIIIIFHPPPECCCKKCNNNNNNNNNNCCCCYYYYYYYOYYYYUUYYYDDDDDAAAAAWWWQWDDDYYYMMMMMMMMMMMJJJJJNYYKKKKK +RRRRRRRRRROOOOOOOOOJJJJJJJJJJJJZZZZZZZZZUUUUUUKGGGIIHHHHPKKCKKKKNCCNNNNCCNNNCCCCYYYYYYYYYYUUUTADDAAAAAAWWWWWWWWWDDDOMMMMMMMMMMMJJJJJJLLLKKKK +RRRRRRRORROOOOOOSOOJJJJJJJJJJVZZZZZZZZZZUUUUUUKGGIIIHHHHPKKKKKKKKKCCCCCCCCNCCCCCCCCCHYHHYUUUUAAADAAAAAAAAAWWWWWDDDDOMMMMMMMMMMMJJJJJJLKKKKKK +ZZRRRRROOOOOSOOOSOOOJJJPJJJJVVVZZZZZZZUUUUUUUUUIIIIIIHHHPKKKKKKKKKKCCCCCCCCCCCCCCCCHHHHHHHUUNAAAAAAAAAAAXAWAWWWDDDDOMMMMMMMMMMMJJJJJJJJKKKKK +SZRXXROOSSOSSSSSSSOOOPJPJJJJVVVZZZXXXUUUUUUUUUUIIIIIIHHKKKKKKKKKKKKCCCCCCCCCCJCCCHHHHHHHHHUUNAAAAAAAAAAAAAAAAAWDDDDOMMMMMMMMMMMJJJJJJJKKKKKK +ZZZXXZOSSSSSSSSSSSSSSPPPPJJJVZZZZZZXXVVVVUUUUUUUIIIIIHBBKKKKKKKKKKKCCCYYYCCJJJCCHHHHHHHHHHCCAAAAAAAAAAAAAADAAIWDDDDOMMMMMMMMMMMJJJJJJJKKKKKK +ZZZZZZOSSSSSSSSSSSPPPPPPPPJVVVVVVZXXXCXXVUUUUUUUIIIIIHHBBKKKKKKKKKKCCYYAYCCJJJCCHHHHHHHHHHCHRRAAAAAAAAAAAAAAAAADDDDOMMMMMMMMMMMJYJJJJJKKKKKK +ZZZZZZZSSSSSSSSSSSPPPPPPPPPPPVVVVZXXXXXXVUUUUIIIIIIIIIZZKKKKKKKKKKKKCYYYYYCJJJCCCHHHHHHHHHHHHRRAAAAAAAAAAAAAAAIIIDCCLOOMMMMMJJYYYKKYKKKKKKKK +ZZZZZZZZSSSSSSSSSSPPPPPPPPPVVVVVVVVXXXXXUUUUUIIIIIIIIIZZKKKKKKKKKKKKYYYYDDJJJJJJJIIIHHHHHHHHHRRAAAAAAAAAAAAMMLLLLLLLLOOMMMMMYYYYKKKKKKKKKKKK +ZZZZZZZZASSSSSSSJSPPPPPPPPPPVVVVVVXXXXXXXXUUUUIIIIIIIIIZZKKKKKKKEEDYYYYYYDJJJJJJJJIIJHHHHHHHHRRRRRARARRARRAAMLLLLLLLLOOOOOJYYYYYKKKKKKPKKKKK +ZZZZZZZZZZSSSSSSPPPPPPPPPPVVVVVVVVVXXXXXXXXUUUUIIIIHIIZZZZZZKKKKEEDYYYYYDDDJJJJJJJIIJJHHHHHHHRRRRRRRRRRRRRRAALLLLLLLLOOOOOJYYYYFFFKKPKPPPKWK +ZZZZZZZZZZZUSDSSSPPPPPPPPVVVVVVVVXXXXXXXXXXUUUUUUIIIIIZZVVZKKEFEEEYYYYYYDJJJJJJJJJJJJHHHHHHHHFFFRMMMMMMRRRRRLLLLLLLLLOOOOOJYFFFFFEKPPPPPPKWK +ZZZZZZZZZZZZDDDSSPPPPPOPPPPVVVVVVXXXXXXXXXXXUUKUUIIIIQVZVVVTKEEEEEEYYYYYDJJJJJJJJJLJHHHHHTHHHFFUMMMMMMMMMMRRRRLLLLLLLLOOOOOOOFFFFFFGPEEPPWWK +ZZZZZZZZZZZZZDDDSPPPPPOOEPVVVVVVVVXXXXXXXXXXUKKKKKIIIQVVVVVTTEEEEEEETTYYYJJJJJJJJJJHHHHHHHHHHFFUMMMMMMMMMMRRLLLTLLDLARAOOOOOOHHFFFXPPEEPPPPK +ZZZZZZZZZZZZDDDDDPPPPOOOOOOOOVVVVVXXXXXXXXXUUKKKKKKIQQVVKVTTTEEEEEEETTTTJJJJJJJJJJZZHHHHHHHHFFFMMMMMMMMMMMMRJTTTTTAAAAAOOOOOOOHFFFFFPPPPAPPA +ZZZZZZZZZZZZDDDDDPPPPOOOOOOOOVVVVXXXXXXXXXUUKKKKKKKIIKKAVVVVTTEEEEEETTTTTTJJJJJJJJZZZHHHHHFFFXXXXXXXXXMMMMMJJTTTTTTAAAAAAOOOOOHFFFFFPPPAAAAA +ZZZZZZZZZZZIZDDDDDDPPOOOOOOOOVVVVBXXXXXXXPKKKKKKKKKKKKAAVTTTTTTTEEEETTTUUUUUUJJJJJJZZHHHHHFFFXXXXXXXXXXXXXXXJJJTTTTAAAAAAOOHOOHFFFMPPPSPPPAA +BZZZZZZZZZZZZZDDDDDPDOOOOOOOOOOVVBLXXXXTXXKKKKKKKKKKKKKKTTTTTTTTTEEETTUUUUUUFJJJJJJJHHYHHHHFXXXXXXXXXXXXXXXXJJTTTTTAAAAAAOAHHHHHPFFPPPPPPPAA +BZZZZZZZZZZZZZDDDDDDDDOOOOOOOBBBBBLXXXXKKKKKKKKKKKKKKKKKTZZTTTTTTEEETUUUUUUUJJJJJJCCCCFFHHFFXXXXXXXXXXXXXXXXJTTTJTTAAAAAAAAAAAAPPPPPPPPPPPAA +BZBBBZWWZZNZDZDDDDDDDDDDOOOOOLLBBBLLXXXXRRRRKKKKKKKKKKKKTZZTTTTTTTTTTUUUUUUUUJJJJJCCCCFFFFFFXXXXXXXXXXXXXXXXTTTTJTTAAAAAAAAAADPPPPPPPPPPPPPA +BBBBBBBBBWWNDDDDDDDDDDDDODDOOLLLLLLXXXXRRRRNNNNNKKKKKAAZZZZTTTTTTTTUUUUUUUUCCCJJJVVVFFFFFIIIXXXXXXXXXXXXXXXXJTTTJJTAAAAAAAAAAPPPPPPPPPPPAAAA +BBBBBBBBWWNNDDDDDDDDDDDDDDDDDDLLLLLLXRRRRRRNNNNNKKKKKKZZZZZZTTTTTTTUUUUUUUKKVCCJJVVVCFFFFFIIXXXXXXXXXXXXXXXXTTJJJJTAAAAAAAAAAAPPPPPPPPPPPPAA +BBBBBBBWWWNNDNDDNDDDDDDDDLLLLLLLLLLLLRRRRRRNNNNNKKKKKZZZZZZZTTTTKKTKAUUUUKKKKCCCJVVVCCFFCFIIXXXXXXXXXXXXXXXXTTJJJJTTTAAAAAAAAAZPPPPPPPPPPPAA +BBBBBBBRWWNNNNNNNNDDDDDDLLLLLLLLLLLLLLRRRRRNNNNNKKKZZZZZZZZZZNNNNKKKUBUUUKKKKCVVVVVVCCCFCCCIXXXXXXXXXXXXXXXXTTTJJKTTTAAAAAAAAAZZPPPPPPPPPPPA +BBBBBBBBBNNNNNNNNDDDDLLLLLLLLLLLLLLLLLRRRRRNNNNNKZZZZZZZZZZZZNNNKKKKUUUUUKKKKCVVVVVVCCCCCCCIXXXXXXXXXXZZZZKKKKKJJKKTTTTAAAAEAAZZZZPZPPPPPPPA +BBBBBBBVNNNNNNNNNDDDDDDLWWLLLLLLLLLLRRRRRRRNNNNNZZZZZZZZZZZZZNNNNKKKUUKUKKKKKCVVVVVVCCCCCCIIIIIIZZZZZZZZZZKKKKKKKKKTTTTTAAAEAZZZZZZZZZPPIITA +BBBBBBBBBLNNNNNNNDDDDKKWWWLLLLLLLLLLLRRRNNNNNNNNNNZZZZZZZZNZNNKNNLKKUKKKKKKKKCVVVVVVCCCCCCCVILIIZZZZZZZZZZKKKKKKKKKKKTTTAAAEEGGZZDDDDZPPITTA +BBBBBBBBBLLLNNNNNNDKKKKKWWWWWLLLLLLLRRRRNNNNNNNNNNNNZZZZZNNNNKKKKKKKKKKKKKKKKKVVVVVVKCCCCCCCLLLIZZZZZZZZZZKKKKKKKKYYTTTTTAEEGGGZDDDDTZZZTTTT +BBBBBBBBLLLLNNNNNNKKKKKKWWWWLLLLLLLLRRRRNNNNNNNNNNNNZZZZZZNNNNKKKKKKKKKKKKKKKKVVVVVVVVVVCCCCCCLLIITZZZZZZZKKKKKKKKYYYYTTTGGGGGGDDDDDTTTTTTTT +BBBBBBOWLWLLLNNNKNKKKKKKWWWWLLLLLLLLLRRRNNNNNNNNNNNNZZZZZZNNNNKKKKKKKKKKKKKKKKVVVVVVVVVVKKCQQFLLLTTZZZZZZZKKKKKKYYYYYTTTGGGGGWWWDDDDDDTHTTTT +BBBBBLWWWWWNNNNNKNKKKKKWWWWLLLLLLLWLLRRRNNNNNNNNNNNNZZZZZZZNNNNKKKDWWWKKKKKKKRVVVVVVVVVVKKVQQFFFFCCZZZZZZZKKKKKYYYYYTTTTGGGGGGWDDDDDDDTTDLTT +BBBBBBWWWWWNCNNNKKKKKKKKWWWWLWLWLLWLLRRRNNNNNNNNNNNNZZZZZZZNNNNNKKDWWWKKKKKRRRRRRQVVVVVVKKKQQFQFFFCZZZZKKKKKKKKKKYYYYTTTGGGGGGGDVDDDDDDDDDDD +BBBBBBBBWWWCCKKKKKKKKKKKWWWWWWWWLWWWRRRRNNNNNNNNNNNNZZZZZZZNNNNNOWWWWWKKKRRRRRRRRRKKKKKKKKKQQQQQCCCCCCKKKKKKRKKKRYYYYTGTGGGYWDDDDDDDDDDDDDDD +BBBBBBBBHWWHKKKKKKKKKKKKKWWWWWWWWWWWRRRRRNNNNNNNNNNNEEEEZZNNONNNOOOWWWKKKKRRRRRRRRKKKKKFKKKQQQQQKCCWWCKKKKKRRRRRRJXXXTGGGGGYYDDDDDDDDDDDDDDD +FBBBBBHHHHHHKKKKKKKKKKKKKWWWWWWWWWWWWRRRRNNNNNNNNNNNEEEEZZNNOOOOOOOWOWKKKRRRRRRRKKKKKKKFFFFQQQQQQWWWCCCKKKRRRRRRRXXXXXGGGGYYODYYDYYDDDDDDDDD +BBBBBBBBHHHHHKKKKKKKKKKKKWKWWWWWWWWWWWRRRNNNNNNNNNNNOOEEEZNNNOOOOOOOOWWUKKCCRRRRKKKKKKKKQQQQQQQQWWWWCCCCCKRRRRRRXXJJJYYGGYYYYYYYYYYYYDDDDDDD +BBCBOBECCCHHKKKKKKKKKKKKKKKWWWWWWWWWWWRRRRRRRRRROOOOOOEEEZZNSOOOOOOOOUUUCCCCRRRIIIKKKKKKQQQQQQQQQQCWWCCCCRRRRRRRXXIYYYYGGYYYYYYYYYYYYYYYYYDD +CCCCCCCCCCCKKKKKKOKKKKKKKKKWWWWWWWWWWWRRRRRRRRROOOOOEEEEEZZSSOOOOOOUUUUCCCCCCCIIIKZKKKKKKKQQQQQQQQCCCCCCWWWWRRRXXXIYYYYYGYYYYYYYYYYYYYYYYYDD +CCCCCCCCCCKKKKKKGGGGKKKKKKKWWWWWWWWWWWRRRRRRRRROOOOOEEESSSZSSOMMOOOOCCCCCCCCCIIIIKKKKKKKKIQQQQQPPQQQCCCCCWWRRRXXXIIIYYYYYYYYYYYYYYYYYYYYDDDD +CCCCCCCCCCCKKKKKGGGGKKKKKKWWWWWWWWEWWRRRRRRRRRRROOOOOOSSSSSSSMMOOOOOOCXCCCCCCIISSSLLLKKKIIQIIIICCCCCCCCCCWWRRRXXXIIYYYYYYYYYYYYYYYYYYYYYDDDD +CCCCCCCCCCCCCKKGGGGGGGKKKKWKWWWEWWEEEGGRRRRRRRUOOOOOOOSSSTSSSMMOOOOOOOOOCCCCCIISSSSLLKKIIIIIIIIICCCCCCCCCCCXXXXXXXIIYYYYYYYYYYYYYYYYYYYDDDDD +CCCCCCCCCCCCCCTGGGGGGGGGKKKKEEWEEEEEEGPRPPPRRUUOOOOOOOSSSTSSSMOOOOOOOOOOOCCCCIIISSSSSIIIIIIIICCCCCCCCCCCCCCXJXXXIIIIIYYYYYYYYYYYYCCYYYYDDDDD +CCCCCCCCCCCCGTTGGGGGGGGGKKEEEEEEEEEEEPPPPPPRUUOOOOOOOOOOSOSSSOOOOOOOOOOOOOIICCISSSSSIIIIIIIIICICCCCCCCCCCCCJJJXXIIIIIIIYYYYYYYYYCCCYYYDDDDDD +CCCCCCCCCCCGGGGGGGGGGGGGKKEEEEEEEEEEEEEPPPPRUUOZOOOOOOOOSOSSSOOOOOOOOOOOOOOIIIISSSUSIIIIIIIIIIICCCCCCCCCCCJJJJJJIIIIIIIYYYYYYYYYCCYYYYYDDDDD +CCCCCCCCCCCCGGGGGGGGGGGGKKKEEEEEBEEEEPPPPPPPPOOOOOOOOOOOOOOUOOOOOOOOOOOOOOOOIIIIVVIIIIIIIIIIIIIIICICCCCCCCCJJYYJYIIIIIIYYYYYYYYYYYYYYYDDDDDD +CCCCCCCCCCCCGGGGGGGGGGGGGKKKEEEEEEEEEPPPPPPPPOOOOOOOOOOOOOOUOOOOOOOOOOOOOOOOOOIIIIIIIIIIIIIIIIIIIIICCCCCCCCYYYYYYIIIIIIIYYYYYYYYYYYYYDDDDDDD +CCCCCCCCCCCCGGGGGGGGGGGGGKKKKKKKEEEECPPPPPPPOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOIIIIIIIIIIIIIIIIIIIIICIICCCCCYYYYYYYYYYYYYYYYYYYYYYYYYYYDDDDDD +CCCCCCCCCCCGGGGGGGGGGGGGGKKKKKKKEEECCCCPPPPIOOOOOOOOOOOOOOPOOOOOOOOOOOOOOOOOGGGGIITIIIIIIIIIIIIIIIIIIICCCYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYDDY