{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "fefa9c07-7eef-44e4-b64e-dee3f7de5c74",
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.optim as optim\n",
    "import pandas as pd\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "from sklearn.metrics import accuracy_score\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8a26e48b-d1b7-46f4-89bf-dbe719d30563",
   "metadata": {},
   "source": [
    "# Load Dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "b37c429f-613f-4cb0-b029-4dc6718a4c20",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Load the dataset\n",
    "data = pd.read_csv('data/task1/dermatology.data', header=None, delimiter=',', na_values=\"?\")\n",
    "\n",
    "# Drop rows with missing values\n",
    "data = data.dropna()\n",
    "\n",
    "# Split the data into features and target label\n",
    "X = data.iloc[:, :-1]\n",
    "y = data.iloc[:, -1]\n",
    "\n",
    "# Standardize the features (mean=0 and variance=1)\n",
    "scaler = StandardScaler()\n",
    "X_scaled = scaler.fit_transform(X)\n",
    "\n",
    "# Split the data into training and testing sets (70-30 split)\n",
    "X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.3, random_state=42)\n",
    "\n",
    "                                                    # Convert data to PyTorch tensors\n",
    "X_train_tensor = torch.tensor(X_train, dtype=torch.float32)\n",
    "y_train_tensor = torch.tensor(y_train.values - 1, dtype=torch.long)\n",
    "X_test_tensor = torch.tensor(X_test, dtype=torch.float32)\n",
    "y_test_tensor = torch.tensor(y_test.values - 1, dtype=torch.long)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5731b9d4-72c6-4d88-8f31-2e0a9df44daf",
   "metadata": {},
   "source": [
    "# Model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "f94774ff-712e-45c1-b755-af3f5d7fdec9",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "# Define the MLP model\n",
    "class MLP(nn.Module):\n",
    "    def __init__(self, input_size):\n",
    "        super(MLP, self).__init__()\n",
    "        self.fc1 = nn.Linear(input_size, 128)\n",
    "        self.fc2 = nn.Linear(128, 6)\n",
    "\n",
    "    def forward(self, x):\n",
    "        x = torch.relu(self.fc1(x))\n",
    "        x = self.fc2(x)\n",
    "        return x\n",
    "\n",
    "# Instantiate the model, define the loss function and the optimizer\n",
    "model = MLP(X_train.shape[1])\n",
    "criterion = nn.CrossEntropyLoss()\n",
    "optimizer = optim.Adam(model.parameters(), lr=0.001)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6a709cb7-b28f-47fa-be2a-bb590fc025a3",
   "metadata": {},
   "source": [
    "# Train"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "f4597a38-c233-4db4-b21e-6479fab712df",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/300, Loss: 1.6871, Training Accuracy: 44.00%, Test Accuracy: 38.89%\n",
      "Epoch 2/300, Loss: 1.6297, Training Accuracy: 54.40%, Test Accuracy: 44.44%\n",
      "Epoch 3/300, Loss: 1.5736, Training Accuracy: 59.20%, Test Accuracy: 51.85%\n",
      "Epoch 4/300, Loss: 1.5188, Training Accuracy: 62.40%, Test Accuracy: 57.41%\n",
      "Epoch 5/300, Loss: 1.4654, Training Accuracy: 64.40%, Test Accuracy: 62.04%\n",
      "Epoch 6/300, Loss: 1.4132, Training Accuracy: 67.20%, Test Accuracy: 65.74%\n",
      "Epoch 7/300, Loss: 1.3624, Training Accuracy: 70.40%, Test Accuracy: 67.59%\n",
      "Epoch 8/300, Loss: 1.3129, Training Accuracy: 71.60%, Test Accuracy: 70.37%\n",
      "Epoch 9/300, Loss: 1.2648, Training Accuracy: 74.40%, Test Accuracy: 75.93%\n",
      "Epoch 10/300, Loss: 1.2181, Training Accuracy: 78.40%, Test Accuracy: 79.63%\n",
      "Epoch 11/300, Loss: 1.1729, Training Accuracy: 80.40%, Test Accuracy: 80.56%\n",
      "Epoch 12/300, Loss: 1.1290, Training Accuracy: 81.20%, Test Accuracy: 86.11%\n",
      "Epoch 13/300, Loss: 1.0866, Training Accuracy: 82.80%, Test Accuracy: 87.04%\n",
      "Epoch 14/300, Loss: 1.0456, Training Accuracy: 85.60%, Test Accuracy: 88.89%\n",
      "Epoch 15/300, Loss: 1.0061, Training Accuracy: 86.00%, Test Accuracy: 89.81%\n",
      "Epoch 16/300, Loss: 0.9681, Training Accuracy: 87.20%, Test Accuracy: 90.74%\n",
      "Epoch 17/300, Loss: 0.9316, Training Accuracy: 88.00%, Test Accuracy: 90.74%\n",
      "Epoch 18/300, Loss: 0.8965, Training Accuracy: 90.40%, Test Accuracy: 90.74%\n",
      "Epoch 19/300, Loss: 0.8629, Training Accuracy: 90.40%, Test Accuracy: 90.74%\n",
      "Epoch 20/300, Loss: 0.8307, Training Accuracy: 91.20%, Test Accuracy: 90.74%\n",
      "Epoch 21/300, Loss: 0.7998, Training Accuracy: 92.00%, Test Accuracy: 90.74%\n",
      "Epoch 22/300, Loss: 0.7703, Training Accuracy: 92.40%, Test Accuracy: 91.67%\n",
      "Epoch 23/300, Loss: 0.7420, Training Accuracy: 92.80%, Test Accuracy: 91.67%\n",
      "Epoch 24/300, Loss: 0.7149, Training Accuracy: 93.60%, Test Accuracy: 91.67%\n",
      "Epoch 25/300, Loss: 0.6891, Training Accuracy: 94.00%, Test Accuracy: 92.59%\n",
      "Epoch 26/300, Loss: 0.6643, Training Accuracy: 94.40%, Test Accuracy: 92.59%\n",
      "Epoch 27/300, Loss: 0.6405, Training Accuracy: 94.40%, Test Accuracy: 93.52%\n",
      "Epoch 28/300, Loss: 0.6178, Training Accuracy: 94.40%, Test Accuracy: 93.52%\n",
      "Epoch 29/300, Loss: 0.5961, Training Accuracy: 95.20%, Test Accuracy: 94.44%\n",
      "Epoch 30/300, Loss: 0.5752, Training Accuracy: 95.20%, Test Accuracy: 94.44%\n",
      "Epoch 31/300, Loss: 0.5552, Training Accuracy: 95.20%, Test Accuracy: 94.44%\n",
      "Epoch 32/300, Loss: 0.5361, Training Accuracy: 95.20%, Test Accuracy: 94.44%\n",
      "Epoch 33/300, Loss: 0.5177, Training Accuracy: 95.20%, Test Accuracy: 94.44%\n",
      "Epoch 34/300, Loss: 0.5000, Training Accuracy: 95.20%, Test Accuracy: 94.44%\n",
      "Epoch 35/300, Loss: 0.4830, Training Accuracy: 96.00%, Test Accuracy: 95.37%\n",
      "Epoch 36/300, Loss: 0.4667, Training Accuracy: 96.40%, Test Accuracy: 95.37%\n",
      "Epoch 37/300, Loss: 0.4510, Training Accuracy: 96.40%, Test Accuracy: 95.37%\n",
      "Epoch 38/300, Loss: 0.4359, Training Accuracy: 96.40%, Test Accuracy: 95.37%\n",
      "Epoch 39/300, Loss: 0.4213, Training Accuracy: 97.20%, Test Accuracy: 95.37%\n",
      "Epoch 40/300, Loss: 0.4073, Training Accuracy: 97.20%, Test Accuracy: 95.37%\n",
      "Epoch 41/300, Loss: 0.3938, Training Accuracy: 98.00%, Test Accuracy: 95.37%\n",
      "Epoch 42/300, Loss: 0.3809, Training Accuracy: 98.00%, Test Accuracy: 96.30%\n",
      "Epoch 43/300, Loss: 0.3684, Training Accuracy: 98.40%, Test Accuracy: 96.30%\n",
      "Epoch 44/300, Loss: 0.3563, Training Accuracy: 98.40%, Test Accuracy: 96.30%\n",
      "Epoch 45/300, Loss: 0.3448, Training Accuracy: 98.40%, Test Accuracy: 96.30%\n",
      "Epoch 46/300, Loss: 0.3336, Training Accuracy: 98.40%, Test Accuracy: 96.30%\n",
      "Epoch 47/300, Loss: 0.3229, Training Accuracy: 98.40%, Test Accuracy: 96.30%\n",
      "Epoch 48/300, Loss: 0.3126, Training Accuracy: 97.60%, Test Accuracy: 96.30%\n",
      "Epoch 49/300, Loss: 0.3026, Training Accuracy: 97.60%, Test Accuracy: 96.30%\n",
      "Epoch 50/300, Loss: 0.2931, Training Accuracy: 97.60%, Test Accuracy: 96.30%\n",
      "Epoch 51/300, Loss: 0.2840, Training Accuracy: 97.60%, Test Accuracy: 96.30%\n",
      "Epoch 52/300, Loss: 0.2752, Training Accuracy: 97.60%, Test Accuracy: 96.30%\n",
      "Epoch 53/300, Loss: 0.2667, Training Accuracy: 97.60%, Test Accuracy: 96.30%\n",
      "Epoch 54/300, Loss: 0.2586, Training Accuracy: 97.60%, Test Accuracy: 96.30%\n",
      "Epoch 55/300, Loss: 0.2509, Training Accuracy: 98.00%, Test Accuracy: 96.30%\n",
      "Epoch 56/300, Loss: 0.2434, Training Accuracy: 98.00%, Test Accuracy: 95.37%\n",
      "Epoch 57/300, Loss: 0.2363, Training Accuracy: 98.00%, Test Accuracy: 95.37%\n",
      "Epoch 58/300, Loss: 0.2294, Training Accuracy: 98.00%, Test Accuracy: 95.37%\n",
      "Epoch 59/300, Loss: 0.2228, Training Accuracy: 98.00%, Test Accuracy: 95.37%\n",
      "Epoch 60/300, Loss: 0.2165, Training Accuracy: 98.00%, Test Accuracy: 95.37%\n",
      "Epoch 61/300, Loss: 0.2105, Training Accuracy: 98.00%, Test Accuracy: 95.37%\n",
      "Epoch 62/300, Loss: 0.2046, Training Accuracy: 98.00%, Test Accuracy: 95.37%\n",
      "Epoch 63/300, Loss: 0.1991, Training Accuracy: 98.00%, Test Accuracy: 95.37%\n",
      "Epoch 64/300, Loss: 0.1937, Training Accuracy: 98.00%, Test Accuracy: 95.37%\n",
      "Epoch 65/300, Loss: 0.1886, Training Accuracy: 98.00%, Test Accuracy: 95.37%\n",
      "Epoch 66/300, Loss: 0.1836, Training Accuracy: 98.00%, Test Accuracy: 95.37%\n",
      "Epoch 67/300, Loss: 0.1789, Training Accuracy: 98.00%, Test Accuracy: 95.37%\n",
      "Epoch 68/300, Loss: 0.1743, Training Accuracy: 98.00%, Test Accuracy: 95.37%\n",
      "Epoch 69/300, Loss: 0.1699, Training Accuracy: 98.00%, Test Accuracy: 95.37%\n",
      "Epoch 70/300, Loss: 0.1657, Training Accuracy: 98.00%, Test Accuracy: 95.37%\n",
      "Epoch 71/300, Loss: 0.1617, Training Accuracy: 98.40%, Test Accuracy: 95.37%\n",
      "Epoch 72/300, Loss: 0.1577, Training Accuracy: 98.40%, Test Accuracy: 95.37%\n",
      "Epoch 73/300, Loss: 0.1540, Training Accuracy: 98.40%, Test Accuracy: 95.37%\n",
      "Epoch 74/300, Loss: 0.1504, Training Accuracy: 98.40%, Test Accuracy: 95.37%\n",
      "Epoch 75/300, Loss: 0.1469, Training Accuracy: 98.80%, Test Accuracy: 95.37%\n",
      "Epoch 76/300, Loss: 0.1435, Training Accuracy: 98.80%, Test Accuracy: 95.37%\n",
      "Epoch 77/300, Loss: 0.1403, Training Accuracy: 98.80%, Test Accuracy: 95.37%\n",
      "Epoch 78/300, Loss: 0.1372, Training Accuracy: 98.80%, Test Accuracy: 95.37%\n",
      "Epoch 79/300, Loss: 0.1342, Training Accuracy: 98.80%, Test Accuracy: 95.37%\n",
      "Epoch 80/300, Loss: 0.1314, Training Accuracy: 98.80%, Test Accuracy: 95.37%\n",
      "Epoch 81/300, Loss: 0.1286, Training Accuracy: 98.80%, Test Accuracy: 95.37%\n",
      "Epoch 82/300, Loss: 0.1259, Training Accuracy: 98.80%, Test Accuracy: 95.37%\n",
      "Epoch 83/300, Loss: 0.1233, Training Accuracy: 98.80%, Test Accuracy: 95.37%\n",
      "Epoch 84/300, Loss: 0.1209, Training Accuracy: 98.80%, Test Accuracy: 95.37%\n",
      "Epoch 85/300, Loss: 0.1185, Training Accuracy: 98.80%, Test Accuracy: 95.37%\n",
      "Epoch 86/300, Loss: 0.1162, Training Accuracy: 98.80%, Test Accuracy: 95.37%\n",
      "Epoch 87/300, Loss: 0.1139, Training Accuracy: 98.80%, Test Accuracy: 95.37%\n",
      "Epoch 88/300, Loss: 0.1118, Training Accuracy: 98.80%, Test Accuracy: 95.37%\n",
      "Epoch 89/300, Loss: 0.1097, Training Accuracy: 98.80%, Test Accuracy: 95.37%\n",
      "Epoch 90/300, Loss: 0.1076, Training Accuracy: 98.80%, Test Accuracy: 95.37%\n",
      "Epoch 91/300, Loss: 0.1057, Training Accuracy: 98.80%, Test Accuracy: 95.37%\n",
      "Epoch 92/300, Loss: 0.1038, Training Accuracy: 98.80%, Test Accuracy: 96.30%\n",
      "Epoch 93/300, Loss: 0.1020, Training Accuracy: 98.80%, Test Accuracy: 96.30%\n",
      "Epoch 94/300, Loss: 0.1002, Training Accuracy: 98.80%, Test Accuracy: 96.30%\n",
      "Epoch 95/300, Loss: 0.0985, Training Accuracy: 98.80%, Test Accuracy: 96.30%\n",
      "Epoch 96/300, Loss: 0.0968, Training Accuracy: 98.80%, Test Accuracy: 96.30%\n",
      "Epoch 97/300, Loss: 0.0952, Training Accuracy: 98.80%, Test Accuracy: 96.30%\n",
      "Epoch 98/300, Loss: 0.0936, Training Accuracy: 98.80%, Test Accuracy: 96.30%\n",
      "Epoch 99/300, Loss: 0.0921, Training Accuracy: 98.80%, Test Accuracy: 96.30%\n",
      "Epoch 100/300, Loss: 0.0906, Training Accuracy: 98.80%, Test Accuracy: 96.30%\n",
      "Epoch 101/300, Loss: 0.0892, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 102/300, Loss: 0.0878, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 103/300, Loss: 0.0865, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 104/300, Loss: 0.0852, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 105/300, Loss: 0.0839, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 106/300, Loss: 0.0826, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 107/300, Loss: 0.0814, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 108/300, Loss: 0.0803, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 109/300, Loss: 0.0791, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 110/300, Loss: 0.0780, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 111/300, Loss: 0.0769, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 112/300, Loss: 0.0759, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 113/300, Loss: 0.0748, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 114/300, Loss: 0.0738, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 115/300, Loss: 0.0728, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 116/300, Loss: 0.0719, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 117/300, Loss: 0.0709, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 118/300, Loss: 0.0700, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 119/300, Loss: 0.0691, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 120/300, Loss: 0.0682, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 121/300, Loss: 0.0674, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 122/300, Loss: 0.0665, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 123/300, Loss: 0.0657, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 124/300, Loss: 0.0649, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 125/300, Loss: 0.0641, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 126/300, Loss: 0.0634, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 127/300, Loss: 0.0626, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 128/300, Loss: 0.0619, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 129/300, Loss: 0.0612, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 130/300, Loss: 0.0605, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 131/300, Loss: 0.0598, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 132/300, Loss: 0.0591, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 133/300, Loss: 0.0584, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 134/300, Loss: 0.0578, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 135/300, Loss: 0.0571, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 136/300, Loss: 0.0565, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 137/300, Loss: 0.0559, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 138/300, Loss: 0.0552, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 139/300, Loss: 0.0546, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 140/300, Loss: 0.0540, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 141/300, Loss: 0.0535, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 142/300, Loss: 0.0529, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 143/300, Loss: 0.0523, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 144/300, Loss: 0.0518, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 145/300, Loss: 0.0512, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 146/300, Loss: 0.0507, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 147/300, Loss: 0.0502, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 148/300, Loss: 0.0496, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 149/300, Loss: 0.0491, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 150/300, Loss: 0.0486, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 151/300, Loss: 0.0481, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 152/300, Loss: 0.0476, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 153/300, Loss: 0.0472, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 154/300, Loss: 0.0467, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 155/300, Loss: 0.0462, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 156/300, Loss: 0.0457, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 157/300, Loss: 0.0453, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 158/300, Loss: 0.0448, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 159/300, Loss: 0.0444, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 160/300, Loss: 0.0440, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 161/300, Loss: 0.0435, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 162/300, Loss: 0.0431, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 163/300, Loss: 0.0427, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 164/300, Loss: 0.0423, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 165/300, Loss: 0.0419, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 166/300, Loss: 0.0415, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 167/300, Loss: 0.0411, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 168/300, Loss: 0.0407, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 169/300, Loss: 0.0403, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 170/300, Loss: 0.0399, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 171/300, Loss: 0.0395, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 172/300, Loss: 0.0392, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 173/300, Loss: 0.0388, Training Accuracy: 99.20%, Test Accuracy: 94.44%\n",
      "Epoch 174/300, Loss: 0.0384, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 175/300, Loss: 0.0381, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 176/300, Loss: 0.0377, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 177/300, Loss: 0.0374, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 178/300, Loss: 0.0370, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 179/300, Loss: 0.0367, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 180/300, Loss: 0.0363, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 181/300, Loss: 0.0360, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 182/300, Loss: 0.0357, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 183/300, Loss: 0.0354, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 184/300, Loss: 0.0350, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 185/300, Loss: 0.0347, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 186/300, Loss: 0.0344, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 187/300, Loss: 0.0341, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 188/300, Loss: 0.0338, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 189/300, Loss: 0.0335, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 190/300, Loss: 0.0332, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 191/300, Loss: 0.0329, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 192/300, Loss: 0.0326, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 193/300, Loss: 0.0323, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 194/300, Loss: 0.0320, Training Accuracy: 99.20%, Test Accuracy: 95.37%\n",
      "Epoch 195/300, Loss: 0.0317, Training Accuracy: 99.60%, Test Accuracy: 95.37%\n",
      "Epoch 196/300, Loss: 0.0315, Training Accuracy: 99.60%, Test Accuracy: 95.37%\n",
      "Epoch 197/300, Loss: 0.0312, Training Accuracy: 99.60%, Test Accuracy: 95.37%\n",
      "Epoch 198/300, Loss: 0.0309, Training Accuracy: 99.60%, Test Accuracy: 95.37%\n",
      "Epoch 199/300, Loss: 0.0306, Training Accuracy: 99.60%, Test Accuracy: 95.37%\n",
      "Epoch 200/300, Loss: 0.0304, Training Accuracy: 99.60%, Test Accuracy: 95.37%\n",
      "Epoch 201/300, Loss: 0.0301, Training Accuracy: 99.60%, Test Accuracy: 95.37%\n",
      "Epoch 202/300, Loss: 0.0299, Training Accuracy: 99.60%, Test Accuracy: 95.37%\n",
      "Epoch 203/300, Loss: 0.0296, Training Accuracy: 99.60%, Test Accuracy: 95.37%\n",
      "Epoch 204/300, Loss: 0.0293, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 205/300, Loss: 0.0291, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 206/300, Loss: 0.0288, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 207/300, Loss: 0.0286, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 208/300, Loss: 0.0284, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 209/300, Loss: 0.0281, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 210/300, Loss: 0.0279, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 211/300, Loss: 0.0276, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 212/300, Loss: 0.0274, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 213/300, Loss: 0.0272, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 214/300, Loss: 0.0270, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 215/300, Loss: 0.0267, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 216/300, Loss: 0.0265, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 217/300, Loss: 0.0263, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 218/300, Loss: 0.0261, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 219/300, Loss: 0.0259, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 220/300, Loss: 0.0257, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 221/300, Loss: 0.0254, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 222/300, Loss: 0.0252, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 223/300, Loss: 0.0250, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 224/300, Loss: 0.0248, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 225/300, Loss: 0.0246, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 226/300, Loss: 0.0244, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 227/300, Loss: 0.0242, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 228/300, Loss: 0.0240, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 229/300, Loss: 0.0238, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 230/300, Loss: 0.0237, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 231/300, Loss: 0.0235, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 232/300, Loss: 0.0233, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 233/300, Loss: 0.0231, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 234/300, Loss: 0.0229, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 235/300, Loss: 0.0227, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 236/300, Loss: 0.0226, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 237/300, Loss: 0.0224, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 238/300, Loss: 0.0222, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 239/300, Loss: 0.0220, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 240/300, Loss: 0.0219, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 241/300, Loss: 0.0217, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 242/300, Loss: 0.0215, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 243/300, Loss: 0.0214, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 244/300, Loss: 0.0212, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 245/300, Loss: 0.0211, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 246/300, Loss: 0.0209, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 247/300, Loss: 0.0207, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 248/300, Loss: 0.0206, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 249/300, Loss: 0.0204, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 250/300, Loss: 0.0203, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 251/300, Loss: 0.0201, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 252/300, Loss: 0.0200, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 253/300, Loss: 0.0198, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 254/300, Loss: 0.0197, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 255/300, Loss: 0.0195, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 256/300, Loss: 0.0194, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 257/300, Loss: 0.0192, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 258/300, Loss: 0.0191, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 259/300, Loss: 0.0190, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 260/300, Loss: 0.0188, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 261/300, Loss: 0.0187, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 262/300, Loss: 0.0185, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 263/300, Loss: 0.0184, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 264/300, Loss: 0.0183, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 265/300, Loss: 0.0181, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 266/300, Loss: 0.0180, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 267/300, Loss: 0.0179, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 268/300, Loss: 0.0178, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 269/300, Loss: 0.0176, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 270/300, Loss: 0.0175, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 271/300, Loss: 0.0174, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 272/300, Loss: 0.0173, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 273/300, Loss: 0.0171, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 274/300, Loss: 0.0170, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 275/300, Loss: 0.0169, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 276/300, Loss: 0.0168, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 277/300, Loss: 0.0167, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 278/300, Loss: 0.0165, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 279/300, Loss: 0.0164, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 280/300, Loss: 0.0163, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 281/300, Loss: 0.0162, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 282/300, Loss: 0.0161, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 283/300, Loss: 0.0160, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 284/300, Loss: 0.0159, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 285/300, Loss: 0.0158, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 286/300, Loss: 0.0156, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 287/300, Loss: 0.0155, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 288/300, Loss: 0.0154, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 289/300, Loss: 0.0153, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 290/300, Loss: 0.0152, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 291/300, Loss: 0.0151, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 292/300, Loss: 0.0150, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 293/300, Loss: 0.0149, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 294/300, Loss: 0.0148, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 295/300, Loss: 0.0147, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 296/300, Loss: 0.0146, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 297/300, Loss: 0.0145, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 298/300, Loss: 0.0144, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 299/300, Loss: 0.0143, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n",
      "Epoch 300/300, Loss: 0.0142, Training Accuracy: 100.00%, Test Accuracy: 95.37%\n"
     ]
    }
   ],
   "source": [
    "# Training loop\n",
    "epochs = 300\n",
    "train_losses = []\n",
    "test_accuracies = []\n",
    "\n",
    "for epoch in range(epochs):\n",
    "    model.train()\n",
    "    optimizer.zero_grad()\n",
    "    outputs = model(X_train_tensor)\n",
    "    loss = criterion(outputs, y_train_tensor)\n",
    "    loss.backward()\n",
    "    optimizer.step()\n",
    "\n",
    "    model.eval()\n",
    "    with torch.no_grad():\n",
    "        # Compute training accuracy\n",
    "        outputs_train = model(X_train_tensor)\n",
    "        _, predicted_train = torch.max(outputs_train, 1)\n",
    "        train_acc = accuracy_score(y_train_tensor, predicted_train)\n",
    "\n",
    "        # Compute testing accuracy\n",
    "        outputs_test = model(X_test_tensor)\n",
    "        _, predicted_test = torch.max(outputs_test, 1)\n",
    "        test_acc = accuracy_score(y_test_tensor, predicted_test)\n",
    "\n",
    "    # Save the training loss and testing accuracy for plotting\n",
    "    train_losses.append(loss.item())\n",
    "    test_accuracies.append(test_acc)\n",
    "\n",
    "    print(f'Epoch {epoch+1}/{epochs}, Loss: {loss.item():.4f}, Training Accuracy: {train_acc*100:.2f}%, Test Accuracy: {test_acc*100:.2f}%')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "80d2e3df-e467-4f2c-9e68-f0a9204dcceb",
   "metadata": {},
   "source": [
    "# Results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "1dae8dc7-559b-4121-9b92-57913b5ed59b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAnYAAAHVCAYAAAB8NLYkAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAABw9UlEQVR4nO3dd3xV9f0/8Ne5+ya5N3svRiAQ9hBkqoCKohXB1aJiW7RWHHX0p2gVaLWAs2oddaP1q4irFdEqIC6GgOywBbL3uDd3j/P74+becEkCuTc399wkr+fjcR9wzz33c9/3GJpXP+sIoiiKICIiIqJuTyZ1AUREREQUGgx2RERERD0Egx0RERFRD8FgR0RERNRDMNgRERER9RAMdkREREQ9BIMdERERUQ/BYEdERETUQzDYEREREfUQDHZEREREPYRC6gIikdPpxM6dO5GamgqZjNmXiIiou3G73aisrMSoUaOgUJw97mz9pRavfPcL9pY2ospow79uGIOLh6Sd8T2bj9Xi0c8LcaSyCelxGtx+QR6uHpsdqq8QFAa7NuzcuRPjxo2TugwiIiLqpJ9++gnnnHPOWc8zO1wYnK7H1WOzceu/d5z1/OI6M3731jbMG5+DZ68biR+P1uKBj/ciRa/BeQOTQ1F6UBjs2pCamgrA88OQnp4ucTVEREQUqPLycowbN873O/1sLshPwQX5KR1u/99bTyI7QYu/XFYAAMhL0WHbiTq8/sNxBrtI4x1+TU9PR1ZWlsTVEBERUbBMJhMMBoPvuVqthlqt7nS7O082YFJekt+xqQOT8bfPCjvddmdwAhkRERH1WAUFBYiNjfU9li1bFpJ2q5tsSIrxD4jJMWoYbU5YHa6QfEYw2GNHREREPVZhYSEyMzN9z0PRWxfJGOyIiIiox9LpdNDr9SFvNzlGjZomm9+x6iYbdGoFNEp5yD+vozgUS0RERBSgUblx2HS01u/YD0dqMCo3XqKKPBjsiIiIqNcz2ZzYX9aI/WWNADzbmewva0RpgwUAsOLLg7hn1S7f+dePz0VRnRnL1h7A0aomvLP5BD7fW47fT+4rRfk+HIolIiKiXm9PSSN+/eoW3/NHPz8AAJg7OgtPXTMCVQabL+QBQHZCFN646Rz8bU0h3vzxBNJiNVg+Z5ikW50AgCCKoihpBRGopKQE2dnZKC4u5nYnRERE3VBv/V3OoVgiIiKiHoLBjoiIiKiHYLAjIiIi6iEY7IiIiIh6CAY7IiIioh6CwY6IiIioh2CwIyIiIuohuEFxGFn274fxyy+hzMxE/HXXSV1OWJysNWHdgSrccG4uVAr+/4hI8cnOEhSWGaQuQxIDUnW4Zmy21GWEndst4s1NJ1DRaDn7yURhduf0AdBplFKX0SMw2IWR/ZdfUPvqa4gaP77XBLt7PtiNHSfr4XS58Yfz+ktdDgHYX9aIu1ftlroMSeWlxGB0jrT3cwy3L/ZV4G9rCqUug6hNN0/px2AXIgx2YaTMzAQAOEpLJa4kPI5WGbHjZD0AYNW2YtwytR8EQZC4Klq9vQQAMCwzFhP7J0pcTXhtPV6HXcUNWL29uNcFu/e3FQEAJuclYUiGXuJqiPxpVXKpS+gxGOzCyBfsysshOp0QFD378n/QHCAA4JcaE3acrMfYPgkSVkRWhwuf7PT8H4v7Ls6X/J6G4bbll1pc98oWfLa7HA9fVoAoVc/+N+hV2mDBD0drAAB/v3IYchKjJK6IiLpK7/hftQihSE4GlErA4YCzstIX9HoKl1vEi98cRVnzHJ4v9lUAAHISolBUZ8aSz/ZjWGZspz9nSEYsrj83N+D3bT5Wi//uLgPQe2+PXG20o9HiQEasBpPzkqQuJ+zG901AbmIUTtaacfv/7USqXi11SWFxrNoEUQQm9EtkqCPq4RjswkiQyaDMSIfjZBHspaU9Lth9vrccT3192O9Yik6NJ64ajmtf2YJ9pQbsKw3FhP1ijMyOw9AAQqLD5cYd7+1ETZMtBJ/f/V01NhtyWe8bFhcEAdeMzcYT/zuEDQerpC4n7K4b1/sWjRD1Ngx2YabKzILjZBEcpWVSlxJyq7cXAwBmDE7ByOw4CIKA8/OTMSQjFi/8ZjSO1zR1+jM2HKzCz0UN+GB7cUDBbuOhatQ02ZAYrcJvJ/XpdB3dWbRagevOyZG6DMn8fnJfRKvkaLI5pS4lrJJi1Lh8eIbUZRBRF2OwCzPfPLuSkrOc2b2U1Jt9c3gWXz4E2Qn+wz2zhqeH5HNGZMfhhtd/wqc7S/HgpYOhUXZswu2qbZ7QedWYLNw+bUBIaqHuSaOU46ZJfaUug4ioSzDYhVlPWBlrdbiw/IuDfsOaxfUWiCIwKS+xVagLpUn9k5AZp0VpgwW/X7kN8VGqs75HBPDNIc+w29Vjs7qsNiIiIqkx2IVZTwh2/7e1CG9tOtHma9d28RCfTCbg2nOy8fTXh/Hj0dqA3js2Nx55KbouqoyIiEh6DHZh1t2DnSiK+GB7y7Dm0FP2w0qMUeOyEA25nsktU/shLVYDcwBzpOQyATMKUruwKiIiIukx2IWZMqs52FVWdsu97PaVGnCwwgiVQoa/zBqMuA4MhYaaRinvlbeEIiIiOhvevDPMFElJEFQqwOWCo6JC6nICtmq7Z/f6i4ekSRLqiIiIqH0MdmHm2cvOs+WAo6R7DcdaHS78Z5dnm5Zr2WNGREQUcRjsJNBd59n9b38FjFYnMuO0ve4eo0RERN0Bg50ElFmeLTe6W7Dz7gV39dgsyHrhXQuIiIgiHYOdBLpjj11xnRmbjtVCEDyrYYmIiCjyMNhJQJnpmWNnL+0+d59YvcNT66T+SciK503EiYiIIpGke22Yt21D7etvwLp/P5zV1cj65/PQzZjR7vllDyxC46eftjquyuuP/mvWAACqn/8nal54wf/1vn3R/4u1Ia29M1S+Hrvucb9Yl1vEh817111zDhdNEBERRSpJg53bYoF6UD5i585B6R13nvX81IceRMq99/ieiy4Xjl8xG/qLZ/qdpx6Qh5w33mg5EGF7xXmHYp2VlRDtds/2JxHsx6M1KGu0IlarxEXc5JeIiChiSZp4YqZORczUqQCAjsw2k+t0gK7lllDGdevgMhgQN+fK005UQJGc3OE6bDYbbLaW+54ajcYOvzcY8qQkCGo1RJsNjspKqLIjsxesrMGCu1ftwrHqJgDA7JEZ0CjlEldFRERE7enWc+waPvwI0RMm+HrAvOwnT+LIlKk4OuNClN73ZzjKzjzkuWzZMsTGxvoeBQUFXVk2BEFoWUBRErnz7F77/ji2Hq9DTZMdcpmAX4/v2vvAEhERUed022DnqKxC0/ffI+7qq/yOa0cMR8ayvyP7tVeRtngxHCUlOHH99XA1mdpta9GiRWhsbPQ9CgsLu7r8iF8Za3e68clOT+j8y6zB+OruqRiUpj/Lu4iIiEhKkTX5LACNn34KuU4H3fTpfse9Q7sAgPx8aEcMx9Fp02H88gvEXXUV2qJWq6FWq33PDQZDl9R8qpaVsZEZ7NYdqES92YFUvRo3TewDhbzb/n8AIiKiXqNb/rYWRRENH3+E2Ct+ddaFB3K9Hqo+fWA/WRSm6jom0nvsPmheBXvVmCyGOiIiom6iW/7GNv+0DY6TRYidO/es57pNJtiLiwNaTBEOKt/dJyJvy5PyRgu+O1wNALh6TGQu7CAiIqLWpN3uxGSCvailJ81eUgLrgQOQx8ZCmZGBqqeehrOqEhkrVvi9r+GjD6EZMRyagQNbtVm54nHEXHA+lBmZcFZVoeafz0OQyaC/bFZXf52ARPLiiY92lMAtAuP6JqBPUrTU5RAREVEHSRrsLPv2o2j+fN/zquWeABc7ezYyli+Ds7oajrJyv/e4jEYYv/oaqQ8uarNNZ2UFyu69D66GBsgTEhA1ZjT6rHofioSErvsiQfDtZVdVBbfdDlmE7GXndov4YLsnbF47lr11RERE3YmkwS56/DgMPnig3dczli9rdUyu02HQrp3tvifz6adDUltXkyckQNBqIVoscJaXQ5WbK3VJAICtx+tQVGdGjFqBS4alSV0OERERBaBbzrHrCTx72XlWxkbSAorVzYsmLh+RgShVt100TURE1Csx2EnIOxwbKVueGKwOrN3nGfq+ZmyWxNUQERFRoBjsJKTyLaCIjGD32e4yWB1uDEiJwcjsOKnLISIiogBxrE1C4d7LbtPRGtz67x0w2V1tvu5yiwCAa8/JhiAIYamJiIiIQofBTkLhDnb/2VUGg9V5xnOSYlS4clTmGc8hIiKiyMRgJyFlpneT4vAEu31ljQCAx68ajvMHtr1hc2yUEmqFPCz1EBERUWgx2ElImXXKXnY2G2Sn3K821OxONw5XGgEAE/olIkWv6bLPIiIiImlw8YSE5HFxEKKiAACOsq69tdiRKiMcLhF6jQJZ8dou/SwiIiKSBoOdhARBgMq7l10Xr4zdX2YAAAzJiOXCCCIioh6KwU5iyizPbbscpV17z9j9pZ75dUMy9F36OURERCQdBjuJKbM9CyjsxcVd+jm+HrtMBjsiIqKeisFOYipvj11x1/XYOVxuHCj3BLuhGbFd9jlEREQkLQY7iYWjx27DwSqY7C4kxajRLzmmyz6HiIiIpMVgJzFVTg4AwFFcDFEUu+QzVm/3hMa5ozMhl3HhBBERUU/FYCcx790n3E1NcDU0hLz9KoMV3xyqBgBcPTY75O0TERFR5GCwk5hMo4EiJQUA4CgJ/Ty7j34uhcstYkxuPPJSOAxLRETUkzHYRQBltncBRWjn2Ymi6BuGvZa9dURERD0eg10EUGU1L6AoCm2w236yHr/UmBClkuPS4ekhbZuIiIgiD4NdBFDmeHrT7CWhDXYfbPO0N2tYOmLUvC0wERFRT8dgFwFU2aHfy67J5sTne8sBANeew2FYIiKi3oDBLgL4bisWwjl2n+8pg9nuQr+kaIzJjQ9Zu0RERBS5GOwigKp5k2JHRQVEuz0kbX6w3dP7d/XYbAgC964jIiLqDRjsIoA8KQmCVgu43XCUlXW6vaNVTdhxsh5ymYC5ozNDUCERERF1Bwx2EUAQhJaVsSGYZ+fd4uSC/GSk6DWdbo+IiIi6Bwa7COHby66TK2MdLjc++rkUAHAN964jIiLqVRjsIoR3nl1ne+w2HqpGTZMNSTEqXDAoJRSlERERUTfBYBchQrUydlXz3nVzRmdBKed/XiIiot6Ev/kjhNLXYxd8sKsyWvHNoSoAwDVjs0JSFxEREXUfDHYRQpWTA8DTYyeKYlBtfPxzKVxuEaNz4pCXogtleURERNQNMNhFCGWmZ1sSt8kEV0NDwO8XRREfNK+G5Z0miIiIeicGuwghU6uhSE0FENw8u5+L6vFLtQlapRyzhmeEujwiIiLqBhjsIkhn5tn9d5dnY+NZw9MRo1aEtC4iIiLqHhjsIojKtzI28C1Pdpc0AgDOG5gc0pqIiIio+2CwiyDKHE+wsxcXBfQ+p8uNA+UGAMCQDH3I6yIiIqLugcEugqiyg+ux+6XGBJvTjWiVHH0So7uiNCIiIuoGGOwiiNJ7v9gAbyu2v8wzDFuQoYdMJoS8LiIiIuoeGOwiiLfHzlleAdFu7/D79pd6h2Fju6QuIiIi6h4Y7CKIPDERQlQUIIpwlJV1+H37TumxIyIiot6L+2JEEEEQoMrKgu3wYdiLi6Hq0+es7xFFEYVlXDhBRETUWW9vPoF/ffsLqptsGJyux9JfDcHI7Lh2z3/9h+N4d8tJlDZYkBCtwiVD0/H/ZuZDo5SHr+jTSNpjZ962DcW3/hFHpkzFgUGDYVy37oznm7b+hAODBrd6OKur/c6re/ddHJ02HQeHj8Dxa66FZc+ervwaIaXM9q6M7dg8u4MVRhisTqjkMgzgbcSIiIiC8tnuMjy65gDumjEAn98xGQXpOtz4+lbUNNnaPP8/u0qx4suDuGvGAKy75zysmDsca/aU4Yn/HQpz5f4kDXZuiwXqQflIfeThgN7X74u1GPD9d76HPDHR95ph7VpULV+BpIUL0ffjj6DJz0fRgpvhrK0NdfldQtW8gKKjK2M/3OE5b9qgFKgUHFknIiIKxms/HMd147JxzdhsDEjV4bHZw6BVyX236zzdjpP1GJsbjytGZiI7IQpTBybjVyMysLu4IbyFn0bSJBAzdSpS/vQn6C+8MKD3KRIToUhO9j0EWcvXqH1rJeKuvhpxc+dAnZeHtKVLINNo0PDRx+22Z7PZYDAYfA+j0Rj0d+osb4+dowMrY+1ONz7ZWQoAuOacrC6ti4iIqDsyGo1+v+NtttY9cHanG/tKGzEpL8l3TCYTMCkvCT+fbGiz3TG58dhb2ohdzUGuqNaMbw5V4YJBKV3xNTqsW86xOz77SrgddmgGDEDS7bcjavRoAIBot8O6fz+SbrnZd64gkyF6wgRYdu1qt71ly5Zh6dKlXV12h6i8txUrOnuwW3+gEnUmO1L1akwdwDtOEBERna6goMDv+eLFi7FkyRK/Y/VmO1xuEUkxar/jyTFqHKs2tdnuFSMzUWey4+qXN0EUAadbxLzxOVh4QV5I6w9Utwp2iuRkpC1ZAs3QoRDtdjR8+CFO3jgffVa9D+2QIXDWNwAul9/QLADIkxJhO3683XYXLVqEe+65x/e8tLS01Q9CuChzcgB45tiJoghBaH9fulXN3cNzR2dBIecwLBER0ekKCwuRmZnpe65Wq89wdsdtPlaLF745hr9dMRQjc+JwosaMv362H8+tP4I7pw8IyWcEo1sFO3W/vlD36+t7HjV6FBxFRahbuRKZjz8efLtqtd9/aIPB0Kk6O0OVmQnI5RDNZjirqqFMbbtLt7zRgu8OexaNXDM2O5wlEhERdRs6nQ56/Zl3jYiPUkEuE1otlKhusiE5pu0g+PTXhzBndCauG+fpkBmUpofF4cSij/fi9gvyJLthQLfv5tEMHw7HSc+9VRXxcYBcDtdpCyVcNbVQJCW18e7II6hUUGZkAAAcRSfbPe/jn0vhFoFxfRPQJ4m3ESMiIgqWSiHD0MxYbDpa4zvmdovYdLQWo3Pj2nyPxeHC6YNqsuYDYlcV2gHdPtjZDh6AIsUzv0xQqaAZMgSmzVt8r4tuN0xbtkA7cqREFQZOlZsLALCfbDvYud2ib5UOe+uIiIg6b8HkvnhvWzE+3FGCo1VGPPTpPpjtTlw9xvN79p5Vu7Diy4O+86cPSsW7W4rw391lKK4z4/sj1Xj668OYPjgVcglv7ynpUKzbZIK9qMj33F5SAuuBA5DHxkKZkYGqp56Gs6oSGStWAADqVq6EMisL6rw8uG02NHz4IUxbtiLn9dd8bSTeNB9lDyyCZuhQaIcPQ93Kt+G2WBA358qwf79gqXJzYfrhh3aD3aFKI07WmhGlkuPSYWlhro6IiKjnuXxEBupMdjzz9WFUG20YnKHHyt+NQ7LOMxRb2mDxm/d+x7Q8CALw1FeHUNFoRWK0CtMHp+K+i/Ol+goAJA52ln37UTR/vu951XJPgIudPRsZy5fBWV0NR1m573XR4UDlisfhrKyETKOBOj8fOW+8gehzx/vO0V96KZx19ah+/jm4qmugHjwYOa++0m2GYgFAldu8gOJkUZuv7yv13EJsWGYsolTdapokERFRxJo/sQ/mT+zT5mur/jDB77lCLsOfZgzEn2YMDENlHSdpKogePw6DDx5o9/WM5cv8nicuWIDEBQvO2m7C9fOQcP28TtcnlbMNxe5vvoXY0MzYsNVEREREka/bz7HriXzBrqgIoth6Cub+Mk+PHe8NS0RERKdisItASu+WJxYLnFX+98F1u0UUNvfYDclgjx0RERG1YLCLQIJS6Ql3AOwnT/i9drLODJPdBbVChv7J3OaEiIiIWjDYRaj25tl5h2EHpel4twkiIiLyw2QQoVTNtxZzFPmvjPUunCjgMCwRERGdhsEuQvl67E7499j9Ut0EAMhPjQl7TURERBTZGOwilKpP20OxjRYHACChnXvXERERUe/FYBehvEOxp295YrA4AQCxWqUkdREREVHkYrCLUL4tT6xWOKuqfMe9PXZ6De84QURERP4Y7CKUoFRCmeXd8qRlONZgbQ527LEjIiKi0zDYRTBVjv88O7dbRJONQ7FERETUNga7COZdGetoDnZGqxPe6XY6DsUSERHRaRjsIljLJsWevey8w7AapQxqhVyyuoiIiCgyMdhFMFVu88rY5h4778IJDsMSERFRWxjsIpivx66oCKLbDYNvRSyDHREREbXGiVoRTJmR0bLlSXU1DFY3APbYERERUdvYYxfB/LY8OXGyZQ87BjsiIiJqA4NdhGtZQHHCd9cJbk5MREREbWGwi3DevewcRUVcPEFERERnxGAX4Vp67E7yrhNERER0Rgx2EU7VpznYnTjpWxXLHjsiIiJqC4NdhFPlNO9lV1zcsniC250QERFRGxjsIpwyMxNQKCBarWg0mAEAei0XTxAREVFrDHYRTlAooMr0bHnS0GQFwDl2RERE1DYGu25A2TzPjneeICIiojNhsOsG1H36AACMnm3suHiCiIiI2sRg1w2o+vaFXaaArfk/F4diiYiIqC0Mdt2Aqk9fmJQaAIAgADo1F08QERFRawx23YCqb180KbUAPKFOJhMkroiIiIgiEYNdN6BISYZBnwQAiFMx1BEREVHbGOy6AUEQYMjuBwBIkjklroaIiIgiFYNdN2FIyQIAxDvMEldCREREkYrBrpuoj08BAMSb6iWuhIiIiCIVg103Ua+NBQDE11dKXAkRERFFKga7bqJO7lkVq68olrgSIiIiilQMdt1EjUsOAIirr4SznsOxRERE1BqDXTdRY7IDAOJtRtiPH5e4GiIiIopEDHbdgNPlRm1zsEuwGhjsiIiIqE0Mdt1ATZMdogjIIUJvMzHYERERUZskvemoeds21L7+Bqz798NZXY2sfz4P3YwZ7Z5v+OorNLz/PqwHDkK026HOy0PS7bcjZspk3znVz/8TNS+84Pc+Vd++6P/F2i77Hl2t2mgDAMQrRMghwnb8hLQFERERUUSSNNi5LRaoB+Ujdu4clN5x51nPN2/fjuiJE5F8992Q63Ro+PgTFN92G/queh+aggLfeeoBech5442WNyok/ZqdVmW0AgBSopUAwB47IiIiapOkiSdm6lTETJ0KACjtwPlpDz7o9zzlnrth3LAexm++8Qt2kCugSE7ucB02mw02m8333Gg0dvi94VDV3GOXHB8NALAXF0N0OCAolVKWRURERBGmW8+xE91uuE1myGPj/I7bT57EkSlTcXTGhSi9789wlJWdsZ1ly5YhNjbW9yg4NSRGAO9QbGqSHoJGAzgcsJeUSFwVERERRZpuHezq3ngDbrMZ+ktm+o5pRwxHxrK/I/u1V5G2eDEcJSU4cf31cDWZ2m1n0aJFaGxs9D0KCwvDUX6HeYdiU/UaqPr0AQDYOc+OiIiITtNtJ581frYG1S+8iOwX/glFYqLvuHdoFwCQnw/tiOE4Om06jF9+gbirrmqzLbVaDbVa7XtuMBi6rO5gVBmah2J1aqj79YXt4EHYj/8C4AJpCyMiIqKI0i2DXePnn6P84YeR+Y9nED1x4hnPlev1UPXpA/vJojBVF3qlDRYAQEasFqp+/QEAtmO/SFkSERERRaBuNxTbuOZzlD/4EDKfehK6888/6/lukwn24uKAFlNEmuI6MwAgK0ELdf9+AAD7sWNSlkREREQRSNrtTkwm2ItaetLsJSWwHjgAeWwslBkZqHrqaTirKpGxYgUAz/Br2aJFSH1wEbTDh8NZXQ0AEDQayHU6AEDliscRc8H5UGZkwllVhZp/Pg9BJoP+sllh/36h0GhxwGB1AgCy46Mg7+/tsTsGURQhCIKU5REREVEEkTTYWfbtR9H8+b7nVcs9AS529mxkLF8GZ3U1HGXlvtcbPvgAcDpR+de/ofKvf/Md954PAM7KCpTdex9cDQ2QJyQgasxo9Fn1PhQJCWH6VqFVUu/prUuIViFarYC7Tx9AJoO7qQnOqmooU1OkLZCIiIgihqTBLnr8OAw+eKDd171hzSv3nbfP2mbm0093uq5IUlznmV+XHa8FAMhUKqhycmA/cQL2Y0cZ7IiIiMin282x6228PXZZCVG+Y6r+XEBBRERErTHYRTjvwons+JZgp/YGu1+4gIKIiIhaMNhFuOL65qHYBK3vmG9l7FEGOyIiImrBYBfhvEOxp/bYqfrnAQBsv3AoloiIiFow2EUwURR9iyey4k/psevXFwDgqq2Fs75ektqIiIgo8jDYRbBakx0WhwuCAGSeEuxkUVFQZKQDAOzstSMiIqJmDHYRrKR5fl2KTg21Qu73mto7HMt5dkRERNSMwS6CVRmsAIC0WG2r19T9mhdQcGUsERERNWOwi2BVRhsAIDlG3eo1VV7zlifssSMiIqJmDHYRrLo52KXoWwe7lr3sOMeOiIiIPBjsIpi3xy5F10awax6KdZaXw9VkCmtdRERE1DlPf33Yt6VZKDHYRbBqo2eOXXIbwU4eFwd5UhIAwH6cvXZERETdydeFlTjviY34zatb8J9dpbA5XSFpl8EugvmGYnWaNl/39tpxnh0REVH38sVdU/CfhZMwMFWHpZ8V4pxH1+GhT/Zid3FDp9pVhKY86gq+xRNt9NgBgDovD+affoL92NFwlkVEREQhMDQzFkMzY/HQrMFYf6ASq7eX4KqXN6F/cgyuGZuNq8ZmQa9RBtRmwD12DZ98CuPGjb7nlU88gUPnjMOJ634NR2lpoM1RO9xuETVN7c+xAwD1wAEAAOuRI2Gri4iIiEJLFAGHS4Td5YYoAnqtEm9vPoGJyzbgs91lAbUVcI9d7b/+hbQliwEA5p07Uf9/7yH1gQfQtHEjKpcvR9bzzwfaJLWhweKAwyUCAJLa2O4EANQDPMHOdpjBjoiIqLvZW9KI1TuK8d/dZVDJZZgzOgt/u2Io+iRFAwDe+vE4ln62H5ePyOhwmwEHO0dFBVQ5OQCApvXrob/oQsRfew2iRo/CyRvnB9octcM7vy4+SgmVou2OVXWe5+4TzvJyuIxGyHW6sNVHREREwbv4me9wrLoJUwYkYcXc4ZgxOBVymeB3zq9GZmLpmsKA2g042MmiouBqaIAyIwNNP25C4k2eMCeo1XDbbIE2R+2oal4R297CCQCQx8ZCkZYGZ0UFbEeOImr0qHCVR0RERJ0wa3g6rhmbjbTY9n/PJ0SrcHzZrIDaDTjYRU+ciPK/PAx1wWDYT5xA9NSpAADb0aNQZXa8q5DOrMpw5oUTXuoBA5qD3REGOyIiom7izukDuqTdgBdPpD3yMLQjR8JVV4+s556FIj4eAGDdtx/6WYGlSmpf9VkWTnj55tlxAQUREVG3ces7O/DSxtbblb387THc9u6OoNsNuMdOrtcj7ZGHWx1PvvOOoIug1gLpsQMA2+HDXV4TERERhcZPJ+rwpwtb99qdn5+M174P/sYDAffYNX3/Pcw7WpJk3bvv4pfZV6L03vvgamwMuhDy5+2xCyTYiaLY5XURERFR55lsTijlrWOYQiaD0eoMut2Ag13V40/A3dQEALAeOoyqFY8jZupUOEpKULl8RdCFkL+as2xO7KXO6w8IAlwNDXDV1oajNCIiIuqkQWk6rNld3ur4Z7vLMCA1Juh2Ax6KtZeWQtXfs82G8auvEHP++Ui5525Y9u9H8R9uDboQ8tdk86T1s+04LdNooMrJgf3kSdiOHIGi+f6xREREFJi3N5/Av779BdVNNgxO12Ppr4ZgZHZcu+c3Whx48n+H8OX+CjSaHciM1+KRywpwwaCUs37WHdMG4NZ/78DJOhMm9vf87t50tAb/3V2GF+aNDvo7BBzsBKUSotUCADBt3ozYK64AAMhj43w9edR53mAXozn7fyL1wAG+YBc9YUJXl0ZERNTjfLa7DI+uOYBHrxyKUdlxeOPH47jx9a3YcN/5bd4owO5044bXtyIxWoWX5o1Gql6D0gZLh28BNqMgFa/cOAYvfHMMX+zdB41ShkFpevx7wXic2y8x6O8RcLCLGj0alctXQDt6FCx79yLzmacBAPYTJ6BMTQ26EPLnHV+PUXcg2A0YAOPX62DlAgoiIqKgvPbDcVw3LhvXjM0GADw2exg2HKzCB9uLcdv5ea3O/2B7MRrMDnz0x4m+uXLZCVEBfea0QamYNii02Snw7U4e/gsEuRzG/32F9MWP+MKc6fvvED1lSkiL682abA4AHQ92ALc8ISIiOp3RaITBYPA9bG3cTMHudGNfaSMm5bVMZ5LJBEzKS8LPJxvabHfdgUqMzonDI//Zh7GPfo2LnvkWL3xzFC63tAsZA+6xU2ZkIPtfL7c6nrpoUUgKIsDhcsPqcAMAdB0Zim0OdvYjRyG63RBkAed1IiKiHqmgoMDv+eLFi7FkyRK/Y/VmO1xusdWQa3KMGseqTW22W1RnxqZ6C2aPzMCbN43DiVoTHv7PPjhcbvxpxsCz1uVyi3j9h1/w+Z5ylDZY4XC5/V7fvfiiDny71gIOdgAgulwwrlsP+y+ejfVUeXnQTZsGQS4PqgjyZ7K1LHOO7kCPnSo3F4JSCbfZDEdZOVRZmV1ZHhERUbdRWFiIzMyW34tq9Zl3m+goUQSSolVYNmc45DIBw7JiUWmw4l/f/dKhYPfsusN4f1sxbp7SD09+dQi3X5CHknoLviqs6NRdKQJfFXvyJIpv+QMcVVVQ9e3jOfbKq1CmpSH7Xy9DlZMTdDHk4Z1fp1HK2tzj5nSCUglVv36wHToE25HDDHZERETNdDod9Hr9Gc+Jj1JBLhNQ0+Q/TFvdZENyGwsnAM92ZEq5ALlM8B3rnxKDaqMNdqcbKsWZf39/uqsMy+cOw7RBqfjHusP41cgM5CZGY9CPOuwsasBvJ3XwC54m4DG7iscegzInBwO+2YB+H3+Mfh9/jLwN66HMykLFY48FVwX58a2IVXdsZQ1w6kbFnGdHREQUCJVChqGZsdh0tMZ3zO0WseloLUbnxrX5nrG58ThRY4b7lDl1x6tNSNGpzxrqAKDaaEN+midwRqkVvk6d6YNS8c3BqqC/S8DBzrxtO1Luuw/yuDjfMUV8PFLuvQfmbduDLoRaeINdR+bXeanzPd2+tkMHu6QmIiKinmzB5L54b1sxPtxRgqNVRjz06T6Y7U5cPcazSvaeVbuw4suW37HXn5uLRosDSz/bj1+qm7DhYCVe3HgUN07I7dDnpcdqUGWwAgByE6Lw3ZFqAMDukoYOBcP2BL6PnUoFt6n1REK32QxB2fEeJmpfUwBbnXhpBg0GAFgPMNgREREF6vIRGagz2fHM14dRbbRhcIYeK383zncHqNIGCwShZdg1I06Llb8bh7+tKcTMZ79Hml6D307qi1vP69+hz7toSBo2HavFqJx4zJ/YB3ev2oUPthWjrMGK303uG/T3CDjY6c4/DxWLH0H6o49CM3w4AMC6ezcqFi+B7oILgi6EWhhtwQS7fACe/QTdZjNkUYHtpUNERNTbzZ/YB/Mn9mnztVV/aH0DgDG58fh0YXCT4R64ZJDv75ePyEBmvBY/n6xHn8RozCgIfm+7gINd6kMPoeyBRThx3a8hKDxvF10uxEy7AKkPcsuTUPD12AUwFKtIToY8KQmumhrYjhyBdsSIriqPiIiIOsHhcuPBj/fizukDfJsaj86Jx+ic+E63HXCwk+v1yH7xBc8trI79AgBQ9+8HVW7HxpTp7LybEwcyxw4ANPn5MNXUwHrwEIMdERFRhFLKZfhyX+e2NWlP0LPzVLm50E27ALppF0CVmwvroUM4MGx4KGvrtbw9droAhmIBQDPY061rPXgg5DURERFR6Fw4JBX/218R8naD2qC4TaIIuFwha643882xC7DHTp3vCXa2g4dCXhMRERGFTt/EaDy3/gh2nKzH0MxYRKn8b/Lw20nBLaAIXbCjkGlZFRvYKmNfj92hQ7y1GBERUQRbtb0Yeq0Se0sbsbe00e81Qeimwc68bRtqX38D1v374ayuRtY/n4duxowzvse09SdUrlgO+5GjUKSnI+nWWxE350q/c+refRd1r78BZ00N1IMGIe0vD0E7vPsMExuDWDwBAKo+fSCoVBDNZjiKiznvkYiIKEL9cP+0Lmm3w106rqamMz7a2tvubNwWC9SD8pH6yMMdOt9eUoLiW29F9Ljx6PvpJ0i48UaUP/wwmr7/wXeOYe1aVC1fgaSFC9H344+gyc9H0YKb4aytDbg+qfg2KA5wjp2gUEA90LNRMfezIyIi6n06nBwOnzPO0zfYHlE88+ttiJk6FTFTpwIASjtwfsP770OVlYnUB+4HAKj794fl5x2oW7kSMVMmAwBq31qJuKuvRtzcOQCAtKVL0PTtt2j46GMk3XJzm+3abDbYbC33hzMajQF9j1ALZh87L/WgfFj37YP10EHoZ14c6tKIiIgoBP68evcZX3/i6uB2t+hwcshZ+VZQHxBK5l27EDXBf4PA6EmTUblsGQBAtNth3b/fL8AJMhmiJ0yAZdeudttdtmwZli5d2iU1B6PJ6tnuJNChWMBzB4pGADb22BEREUWsRovD77nTLeJQhREGqwMT+ycG3W6Hk0P0uHFBf0iouKproEhM8jumSEqEu6kJbqsVrkYD4HJBnuh/QeRJibAdP95uu4sWLcI999zje15aWoqCgoLQFh+Apk702HnvQGE9xJWxREREkeqVG8e2OuZ2i3jo033ITQz+7lFcNglArVZDr9f7HjqdTtJ6fPvYBdFjp873BDtneTlcDQ2hLIuIiIi6kEwmYMGUvnj9h/Y7o87aRgjr6XLy5CQ4a2v8jjlraiGLiYFMo4EiPg6Qy+E6baGEq6YWiiT/nr5I5XKLMNk9+wEG02Mn1+mgzMoCAFi5nx0REVG3UlRrhsstBv3+brWPXdTIkWj69ju/Y6ZNm6AdORIAIKhU0AwZAtPmLb5tU0S3G6YtWxA/b164yw2Kye70/T2YOXaAZwGFo6QE1oMHEH3u+FCVRkRERCHytzWFfs9FEagyWvHNwSrMHZMVdLuSBju3yQR7UZHvub2kBNYDByCPjYUyIwNVTz0NZ1UlMlasAADEXXcd6t79P1Q+8QTi5s6FacsWGL78Etkvv+xrI/Gm+Sh7YBE0Q4dCO3wY6la+DbfF0mqvu0jlHYZVyWVQK+RnObttmsGD0bRuPayFhWc/mYiIiMJuf5n/psQyQUBCtAoPzSrANWO7abCz7NuPovnzfc+rlnsCXOzs2chYvgzO6mo4ysp9r6uyspD98suoXL4c9W+/A0VaGtL/9jffVicAoL/0Ujjr6lH9/HNwVddAPXgwcl59pdsMxTYFeTuxU2mGDAEAWPcz2BEREUWi92+ZcPaTghBweii+/XYIbe5XJ0BQq6HKyYH+ssug7nf2W2FEjx+HwWe4YX3G8mVtvqffJx+fsd2E6+ch4fruMfR6Ot9dJ4KYX+elbQ529l9+gavJBHlMdEhqIyIiotAorjPD6RbRN8n/d/TxGhMUMgHZCcGtjA148YQ8RgfTlq3NvUECAAHWwgMwbd0K0eWE4YsvcHz2bJh//jmogno7c/Mcu9NvBhwIRXIyFKmpgCjCdobgTERERNK4d/Vu7DhZ3+r4ruJ63HeWzYvPJOBgp0hOgv6yWei/7mtkPf8csp5/Dv2//gqxl18OVXYO+q39HLGzZ6PqyaeCLqo3szSviO1MsAMAzdChAADr/v2dromIiIhCq7DMgLG58a2Oj8qOR2G5Ieh2Aw52DR9+hIQbb4Qga3mrIJMh/vp5aPjgAwiCgPh582A7ciToonozq9MNANAoOxnshng2WLbsY7AjIiKKNAJa5tWfymh1wt2J7U4CDnaiywV7G3dxsB8/DtHtCSUytSrg+8aSh7W5x07byWCn9S2gYLAjIiKKNOP6JuCljcf89qxzuUW8uPEoxvZJCLrdgGfox/7qVyh/6C+w/+EWaIcNAwBY9u5F7b9eQewVVwAATNu2QZ2XF3RRvZnF4Ql2ms4OxXoXUBw/zgUUREREEeaBSwbhmn9txrSnNuKc5iC37UQdmqxO/N/N5wbdbsDBLnXRA1AkJaL29dfhqvHc4UGelIiE+fORePMCAEDMpEmImTIl6KJ6M2+w62yPnSIpCYq0NDgrKmA7UIioc84JRXlEREQUAgNSdfjyT1OxctMJHCg3QKOUY86oLMyfmIu4KFXQ7QYc7AS5HEm33oqkW2+Fq6kJACCPifE7R5mREXRBvZ0lREOxAKAZOgRNFRWw7N/PYEdERBRhUvUa/L+Zg0LaZqfuFSuPiWkV6qhzrN4eu04OxQKnzLPjAgoiIqKI8sH2Yny+p7zV8c/3lOPDHSVBtxtwj52zpgaVjz8O8+YtcNbVeW5udorBhQwRneGbY6foVOb2tMEFFERERBHppY3H8NiVQ1sdT4xR4cGP9+KqIO8XG3CwK1v0IBzlZUi67Y9QJCdz9WuIeYdiO7t4AjhlAcWJE3A1NbF3lYiIKEKUNliQHd/67hKZcVqUNliCbjfgYGfZsQO57/4bmsGDg/5Qap93H7tQzLFTJCZCkZ4OZ3k5rIWFiB43rtNtEhERUeclRatwsMLY6tZhB8oNiO/E4onA7zyRnt5q+JVCJ5SLJ4CWjYo9t4AjIiKiSHD5yAws+e9+bDpWA5dbhMstYtPRGiz9rBCXj0gPut0gtjtZhKqnnkba0qVQZWUG/cHUtlAungAA7dBhaFq3Hta9e0LSHhEREXXevRfmo6TegnmvbYVC5pnW5haBOaMycd/F+UG3G3CwK73nHogWC45ddBFkGg2gVPq9nr91S9DF0CmLJ0LUY6cdOcLT7q7gbyhMREREoaVSyPDCb0bjeI0JhWUGaJQy5KfpkNXGvLtABNVjR13Ht3giVEOxQ4cCggBHWRmc1dWeBS9EREQUEfomRaNvkufuUEarA+9sOYkPthXjszsmB9VewMEu7srZQX0QdYw1RHee8JLHxECdlwfbkSOw7NkD3fTpIWmXiIiIQmPTsRqs3l6CL/dVQKdR4OIhaUG31aFgd+pWGd67TbSHW2p0TqhuKXYq7cgRnmC3azeDHRERUQSoaLTiwx3FWL2jBAaLA40WB569bhQuG54OoRNbyXUo2B0eNx4Dvv8OisREHD5nXNt714kiIAjcoLiTWhZPdH6DYi/tiBFoWP0hLLs5z46IiEhKX+wtx6rtxfjpeB3Oz0/GQ5cOxvn5KSh45EsMStN1KtQBHQx2OW+9CXlsrOfvK9/q1AfSmYV68QQAaIYP97S9bx9ElwuCPHRtExERUcfd/t5O3HpeP/zzN6MRow54RtxZdajFUze25Sa3XcftFmF1hG6DYi91//6QRUfDbTLBdvQoNPnBL6MmIiKi4F0zNhtvbz6JLb/U4cpRmbh8eAZio5Rnf2MHBRUVXQYDLHv2wlVXC9Ht9nstbvbsUNTVK9mcLdcylD12glwOzfBhMG/eAsuu3Qx2REREElk2ZxgWX16ANXvK8cH2Yvx1TSGmDkiGCM8+dp0VcLAzbvgGZX/+M9xmM2QxMf7z7QSBwa4TvMOwQGiDHeCZZ2fevAWW3bsRf+01IW2biIiIOk6jlOOqMVm4akwWjteYsHp7MfaWNuCqlzbhgkEpuHRYGmYODe7uEwEHu6oVKxA7dw5S7r4bMq02qA+ltnmDnUohg1zWucmTp9MOb96oeA8XUBAREUWKvknR+H8zB+G+i/Kx4WAVVm0vxp3v7cLhx8IU7BxVVUi44QaGui4Q6vvEnko7wrOAwn70GFwGA+R6fcg/g4iIiIIjkwmYUZCKGQWpqGmyBd9OoG+ImTwJ1n37gv5Aal+oNyc+lSIxEcrsbACAZe/ekLdPREREoZEUow76vQH32MWcdx4qn3gCtqPHoB44EILSvwndtGlBF9Pbtexh1zXbkWhHjICjuBiWXbsQM2lSl3wGERERSSfgYFf+8CMAgJoXX2z9Ijco7hTvHDu1InSbE59KO3IkDGvWwPLzzi5pn4iIiKQVcLAbfKCwK+ognDLHrot67KLGjPZ8zs6dEJ1OCIrQb4xIRERE0umariEKSlfcJ/ZU6oEDIYuJgdtshvXQoS75DCIiIjq7KY9vQL3J3up4o8WBKY9vCLrdDnXZ1L39DuKuvQYytRp1b79zxnMTbrwh6GJ6u65cPAF4NirWjh4F03ffw7JjB7RDhnTJ5xAREdGZldRb4BJb70hsd7pR2Rj8qtiOBbuVK6G//DJPsFu5sv0TBYHBrhO8Q7GaLhqKBYCoMWNh+u57mLfvQMKNN3bZ5xAREVFrXxdW+v7+3eFq6DQttxNzuUVsOlaDrPjgt5TrULDLW7+uzb9TaFmdob9P7Omixo4BAJh37IAoihCE0G6ETERERO275Z3tAAABwL2r/W8aoJTJkBWvxUOzBgfdPmfPRxBfj52y66Y+aoYNg6BSwVVbC/uJE1D37dtln0VERET+ji+bBQCYvGID/nv7ZCREq0LaflDBzlFRAeOGDXCWl0O0O/xeS130QEgK6426eo4dAMhUKmiGD4Nl+w5YduxgsCMiIpLAD/e33ve30eJArFbZxtkdF3CwM23ejOLbFkKVlQXb8eNQDxgAR2kpIIrQFBR0qpjerqtXxXpFjRkLy/YdMG/fgbirrurSzyIiIqLWXtp4DFnxWlw+IgMAcNu7O/DFvgqk6NR486ZxKMgI7tafAY/5VT39DBJ/+1v0++y/kKlUyHruWQz4ZgOizjkH+pkXB1UEeYRj8QTgP8+OiIiIwu/drSeREacBAHx/pBo/HKnByt+Ow/kDU7DsiwNBtxtwsLMfO4bY2Vd4nigUEK1WyKKjkXznHah99bWgC6Hw9dhpR40CZDI4iovhqKzq0s8iIiKi1qqNNqTHela/rj9QhVnDMzB1YDL+cF4/7C5uCLrdgIOdEBUF0eGZV6dIToa9uNj3mrMh+EIoPHPsAEAeEwN1fj4AwLJje5d+FhEREbUWq1WivNECwLPtyeS8JACACMDdenu7Dgt4jp12xAiYd+yAun9/xEydisoVK2A7fBjGr76GdsTw4CshWB2e7U40XRzsACBqzBjYDhyAeft26C+9tMs/j4iIiFrMHJqGO9/bhb5J0ag323F+fjIAYH+ZAbmJUUG3G3CwS33gfrjNZgBA8h23w202w7D2C6hyc5H6wP1BFVH37ruoe/0NOGtqoB40CGl/eQja4W2HxJM33Ajztm2tjkefNxU5//oXAKDsgUVo/PRT/9cnT0bOa68GVV+4mO1OAGEKduPOQf2//w3T1p+6/LOIiIjI38OXFSArXouyBiseuGQQotWeSFZlsOKGc3ODbjegYCe6XHBWVPiG8WRRUUhfuiToDwcAw9q1qFq+AmlLlkA7YjjqVr6NogU3o/8Xa6FITGx1ftbzz/mGggHA1dCAX2ZfCf3FM/3Oi54yBRl/f8z3XFCFdp+YrmBuXjwR1cWLJwAgetw4QBBgP3YMjsoqKFNTuvwziYiIyEMpl+GWqf1bHV8wpV+n2g1ojp0gl6Po9wvgMhg69aGnqn1rJeKuvhpxc+dAnZeHtKVLINNo0PDRx22eL4+LgyI52fcwbdoEmUbTakWuoFL5nSePjW23BpvNBoPB4HsYjcaQfb9AeBdPhCPYyePifNvTmH/a2uWfR0RERP4+/rkEV720CeMeW4eSes9o6Os/HMdX+yuCbjPgxRPqAQPgOGXBRGeIdjus+/cjeuIE3zFBJkP0hAmw7NrVoTYaPvwI+ksvhSzKfzza/NNPODxxEo7NvATlS5bAWV/fbhvLli1DbGys71Eg0X583h47bRiCHQBEnTseAGDavCUsn0dEREQe72w5iUc/P4Dz85NhsDrg9kyzh16jwBs/Hg+63YCDXfKf7kLl40/A+M03cFRVwdXU5PcIhLO+AXC5ID9tyFWelAhnTc1Z32/Zswe2I0cQd7X/JrvRUyYjY8Vy5Lz5JlLuuxfmbdtRfMsfILpcbbazaNEiNDY2+h6FhYUBfY9QsfqGYsNzp7focz2B2rRlM0SxE0twiIiIKCArN53AsjnDcPu0AZCfct/24VlxOFQR/MhhhxNE9QsvIPG3v0XxLX8AAJTcthA49QbyoggIAgYX7g+6mEA1fPgR1AMHtlpoETtrlu/vmvyBUOfn49iFF8H800+InjDh9GagVquhVqt9zw0hHGruKFEUYQ7jUCwARI0ZDSiVcJaVw1FcDFVOTlg+l4iIqLcrrjNjSBt3l1ApZL4RvGB0ONjVvPAi4q+7Djkr3wr6w1p9eHwcIJfDVVvrd9xVUwtFUtIZ3+tZjbsWyXfecdbPUWVnQx4fD/vJojaDXSSwu9xwNW9cE45VsYBn8Yt2xHBYtu+AafMWBjsiIqIwyU6IQmGZAVnx/lPJvj1UhbyUmKDb7fiYX/NQXfS4cUF/2OkElQqaIUNg2rwFuhkzPB/jdsO0ZQvi580743sNX/4Pot0O/eWXn/VzHBUVcDU0QJGSHJK6u4LllHQerh47wDMca9m+A+atWxB/7TVh+1wiIqLe6Nl1R3DL1H5YMLkvHvnPfticbogAdpU04L+7S/HixmNYPjf4fYEDm2N36tBriCTeNB8Nq1ej4ZNPYTt2DBVLlsJtsSBuzpUAgLL770fVU0+3el/DRx9BN2M6FPHxfsfdJhMqH38Cll27YC8phWnzZpTcthCqnBxET54c8vpDxdvtqpQLUMoDnvoYtOgJ5wIATFu2QvTO3CQiIqIu8ez6wzDZnbhuXA4euGQQnvrqECwOF+56fyf+vaUIiy8vwK9GZATdfkCz9I/NvOSs4S5/a2ArLPWXXgpnXT2qn38OruoaqAcPRs6rr/iGYh1l5YDgH3RsvxyHZccOJL3exr1p5XLYDh1C8aefwmU0QpmcjOhJk5B8152QRfBedr4VsWEahvXSDhsGQauFq64OtiNHoGneo5CIiIhC79SlirNHZWL2qExY7C6Y7E4kxajbfV9HBRTskm+/HTKdrtMferqE6+ch4fq2h15z33m71TF1v74YfPBAm+fLNBrktBX4IpwlzCtivQSVClFjx8L0/fcwb9nCYEdERNTFTu8i06rkIdvqLKAUoZ91aZt3g6DO895OLJzz67yizz0Xpu+/R9OmTUiYPz/sn09ERNSbXPDkRghnGQHdvfiioNrueLDrgvl11MK71Um4Nic+VfSUycATT8C89Se4rVbINJqw10BERNRb3H3hQOg0yi5pO+BVsdQ1LGG8T+zp1AMGQJGWBmdFBczbtiFmypSw10BERNRbXD4iIyTz6drS4eWXgw8Uchi2C7XcTiy8c+wAQBAEX5hr+u77sH8+ERFRb9HV45/h21eDzsjinWMX5lWxXtFTPcHO9N13knw+ERFRb9DV458MdhHCLOFQLADPHTkUCthPnoS9qEiSGoiIiHq648tmddkwLMBgFzFahmKlCXbymBhEjR4NgMOxRERE3RWDXYSwOqTtsQOAmKneeXbfSlYDERERBY/BLkJIuXjCK3rqVE8tzdueEBERUffCYBchpLql2Km8256INhvM27ZJVgcREZEU3t58ApOWb8DAv3yBK174EbuKGzr0vv/uLkOfBz7HzW9v79oCO4DBLkJYHNLdecLLb9uTb7k6loiIeo/Pdpfh0TUHcNeMAfj8jskoSNfhxte3oqbJdsb3FdeZ8ffPD2Bcn4QwVXpmDHYRQurFE14x558HAGjasAEiN6UmIqJuzmg0wmAw+B42W9tB7bUfjuO6cdm4Zmw2BqTq8NjsYdCq5Phge3G7bbvcIv60ahfuvnAAshOiuuorBITBLkJIvd2JV/TEiRA0GjjKymA7eFDSWoiIiDqroKAAsbGxvseyZctanWN3urGvtBGT8pJ8x2QyAZPykvDzyYZ22352/REkRqtw7Tk5XVF6UKSbqU9+pLyl2KlkWi2iJ09C07r1MK5bD83gwZLWQ0RE1BmFhYXIzMz0PVerW+8hV2+2w+UWW+0vlxyjxrFqU5vtbjtRhw+2FWPtXZF1G0722EUIc/OdJ7RK6bO2bvoMAIBx/XqJKyEiIuocnU4HvV7ve7QV7ALVZHPi7lW7sGzuMCREq0JQZehInyIIQOT02AHN8+zkctgOHoS9pASqrCypSyIiIuoy8VEqyGVCq4US1U02JLdxl4iTtSaU1FuwYGXLKlh387z0/g+uxYZ7z0NuYnTXFt0OBrsIYY6ADYq9FPHxiBo7FuatW2Fctw6JN90kdUlERERdRqWQYWhmLDYdrcHFQ9IAAG63iE1Ha3HjxNxW5/dPjsH//jTV79iTXx2CyebE4suHID1WG5a628Kh2AgRKativXTTpwMAmtZxOJaIiHq+BZP74r1txfhwRwmOVhnx0Kf7YLY7cfWYbADAPat2YcWXnkWFGqUc+Wk6v4deo0S0WoH8NB1UCuniFXvsIoDLLcLudAMAoiS888SpdNOnofLvf4f555/hrKuDIiEy9uchIiLqCpePyECdyY5nvj6MaqMNgzP0WPm7cUjWeYZiSxssEARB4irPLjJSRC/nXTgBRMZQLAAoMzOhLhgMW+EBNH2zEXFz50hdEhERUZeaP7EP5k/s0+Zrq/4w4YzvfeqaEV1QUeA4FBsBvAsnBAFQS9h9ezrvcKzxq68kroSIiIg6InJSRC9m8S6cUMojqptXf/HFAICmTZvgamyUuBoiIiI6Gwa7CNCycCKyRsbVeXlQDxwIOBwwrlsndTlERER0Fgx2EaAl2EXefw79pZcCAAyfr5W4EiIiIjqbyEsSvZBvc+IIuOvE6fSXXgIAMG3ZAmdtrcTVEBER0Zkw2EUA7xw7TYSsiD2VKicHmmHDALcbhv/9T+pyiIiI6AwY7CLAqYsnIpFvOHYth2OJiIgiGYNdBLBG2F0nTqe/ZCYAwLJ9BxwVFRJXQ0RERO1hsIsA3h47bYT22CnT0qAdOwYAYPjiS4mrISIiovYw2EUA3xy7CA12wCnDsZ99JnElRERE1B4Guwhg9QW7yP3Pob/kEkCphLWwENZDh6Uuh4iIiNoQuUmiF4n0oVgAUMTHQ3f++QCAxk8+kbYYIiIiahODXQSI9MUTXrFXXgkAaPzsM4gOh8TVEBER0ekY7CJAd5hjBwAxUyZDnpgIV20tmr7/QepyiIiI6DQMdhHA4nADiOyhWAAQlErEXn45AA7HEhERRSIGuwhg6SZDsQAQe+VsAIBx40Y46+ulLYaIiIj8MNhFAJsz8lfFemny86EpKAAcDhjWfC51OURERHSKyE8SvYCvxy7Ch2K9YufMAQA0fPghRFGUuBoiIiLyYrCLAN1l8YRX7GWzIKjVsB06BMuuXVKXQ0RERM0iItjVvfsujk6bjoPDR+D4NdfCsmdPu+c2fPwJDgwa7Pc4OHyE3zmiKKL6uedweMoUHBwxEid/+1vYT5zo4m8RvO6wj92p5HFxvjtRNLz/vsTVEBERkZfkwc6wdi2qlq9A0sKF6PvxR9Dk56Nowc1w1ta2+x5ZTAwGfP+d75G3Yb3f67WvvYa6d/6N9CVL0OeDVZBpo1C04Ga4bbau/jpB6S772J0q/rprAXjuHctFFERERJFB8mBX+9ZKxF19NeLmzoE6Lw9pS5dAptGg4aOP23+TIECRnNzySEryvSSKIurefhtJt94K3fTp0OTnI2PFcjirqmBct67N5mw2GwwGg+9hNBpD/TXPqLv12AGAZvhwqAsGQ7Tb0fgxtz4hIiKKBJIGO9Fuh3X/fkRPnOA7JshkiJ4w4Yxzt9xmM45Mm4Yj51+A4tsWwnbkiO81R0kJXNU1fm3KdTpohw+HZdfuNttbtmwZYmNjfY+CgoLOf7kAWJv3sesuc+wAQBAExF93HQCgftUqiG63xBURERGRpMHOWd8AuFyQJyb6HZcnJcJZU9Pme1R9+yD9sUeR/cILyHh8BeB248SvfwNHRYWnzWrP+1q3mQRnTXWbbS5atAiNjY2+R2FhYSe/WceJotjtFk94xc6aBVlMDBxFRTBt3ix1OURERL2e5EOxgYoaNQpxs2dDM3gwoseNQ9bzz0GekID6VauCblOtVkOv1/seOp0uhBWfmc3Z0tPVnebYAYAsOhqxv/oVAKD+vfckroaIiIgkDXaK+DhALofrtIUSrppav3lzZyIoldAMHgzHySJPm8me97VuswaKpOTOFx1i3j3sAECj6HY5G/G/+TUAoGn9BtiLiiSuhoiIqHeTNEkIKhU0Q4bAtHmL75jodsO0ZQu0I0d2qA3R5YLt8GEokj2hTZmVBXlykl+brqYmWPbsgXbkiPaakYx3GFYll0Eh737BTp2Xh+gpUwBRRN07/5a6HCIiol5N8iSReNN8NKxejYZPPoXt2DFULFkKt8WCuDlXAgDK7r8fVU897Tu/+oUX0PTDj7AXF8Oyfz/K/vz/4CgrQ9zVVwHwTOpPuPFG1Lz8MowbNsB66DDK7n8AipQU6GbMkOQ7nknL/DrJ/1MELeGm+QCAho8+gquxUeJqiIiIei+F1AXoL70Uzrp6VD//HFzVNVAPHoycV1/xDcU6ysoBoSX0uA0GlD/yMFzVNZDFxkIzpAB93vs/qPPyfOckLlgA0WJB+SOL4TYYoB0zGtmvvgKZWh3273c21m66cOJU0RMnQj1gAGxHjqBh9WokLlggdUlERES9kiDyZp+tlJSUIDs7G8XFxcjKyurSz9pxsg5zX9qM3MQofPvnC7r0s7pSw0cfo/yhh6BITUXeuq8hKJVSl0RERL1YOH+XR5LuO/7XQ1jsnlWx3Wlz4rboL7/Ms6VMZSUMX/5P6nKIiIh6JQY7iXXXPexOJ1OpkDDvNwCA2jffADuCiYiIwo/BTmLd8XZi7Ym77joIUVGwFR6A6bvvpC6HiIio12Gwk5i1eR+77rY5cVsU8fG+24zVvPgSe+2IiIjCjMFOYlZn99/u5FSJv70JgkoFy+7dMG/dKnU5REREvUrPSBPdmPfOE919jp2XIjkZcVdfDQCoeelliashIiLqXRjsJNaT5th5JS74PaBUwrx1K8w//yx1OURERL0Gg53EemKwU6anI272bABAzQsvSlsMERFRL8JgJ7GetHjiVIm33AwoFDD9+CPM27ZJXQ4REVGvwGAnsZ6yj93pVNnZiLtqLgCg6ulnuEKWiIgoDBjsJGZ1eO480dOCHQAk/fE2CBoNLDt3omnjRqnLISIi6vEY7CTWE+fYeSlTU5Bw/TwAQPUz/4DodktcERERUc/GYCcxqzfYqXrmf4rEBQsg0+lgO3wYhs8/l7ocIiKiHq1npoluxLuPXU/ssQMAeVwcEn//ewBA9bPPwW2zSVwRERFRz8VgJzFzD9uguC0JN94ARUoKHCUlqFv5ttTlEBER9VgMdhIz2Z0AAJ1GIXElXUcWFYWUe+8BANS+/DIcVVUSV0RERNQzMdhJrMnqCXYxaqXElXQt/eWXQzN8ONxmM6r/8azU5RAREfVIDHYSM9qag10P7rEDAEEmQ9qDiwAAjZ98AsvefRJXRERE1PMw2EnI5nTB7vRsARKj7tnBDgC0I0dCf/nlgCii8u9/5/YnREREIcZgJyHvMCzQO4IdAKTcew+EqChYdu5Ew0cfSV0OERFRj8JgJ6Gm5mHYKJUccpkgcTXhoUxLQ/KddwAAqp54Es6aGokrIiIi6jkY7CRk9C2c6B29dV4J118PdcFguA0GVK54XOpyiIiIegwGOwk19ZKFE6cTFAqkL/0rIJPB8NlnaPrxR6lLIiIi6hEY7CTknWOn62U9dgCgHTYU8fM895GtWLIUbrNZ4oqIiIi6PwY7CfXWHjuv5LvugiI9HY7iYlQ9+ZTU5RAREXV7DHYS8u1h1wt77ABAHhONjMceBQDU/9//wbRpk8QVERERdW8MdhLqLXedOJPoiRMR/5tfAwDKHvoLXEajxBURERF1Xwx2EmqyOQD07PvEdkTKvfdCmZMDZ3k5Kv++TOpyiIiIui0GOwk19dLtTk4ni45GxrK/A4KAxk8+gWHtWqlLIiIi6pYY7CTknWPX23vsACBqzBgk3voHAED5w4/AXlQkcUVERETdD4OdhHw9dgx2AIDkhQuhHTsGbpMJpXffA7fdLnVJRERE3QqDnYSaevmq2NMJCgUyn3wS8thYWPfvR9WTT0pdEhERUbfCYCehJg7FtqJMS0P6Ms8Civq330Hj559LXBEREVH3wWAnIW530jbdtAuQePPNAIDyh/4C64EDEldERETUPTDYSai3b1B8Jsl/ugvRU6ZAtFpRsvB2OOvrpS6JiIgo4jHYSch3r1gOxbYiyOXIfPIJKHNz4CgrQ+ldf4LIxRRERERnxGAnEYfLDYvDBYA9du2Rx8Yi+5//hCwqCuaffkL5w49AFEWpyyIiIopYDHYSMTUPwwJANINdu9QDBiDzH88Acjka//Mf1Dz/T6lLIiIiilgMdhIxNg/DqhUyqBT8z3AmMVOnIm3JYgBAzYsvouHDDyWuiIiIKDJFRFdR3bvvou71N+CsqYF60CCk/eUhaIcPb/Pc+g8+QON//gvbkSMAAM2QAqTcfbff+WUPLELjp5/6vS968mTkvPZql32HQHGrk8DEX301HGVlqH3pZZQvXgJZbCz0F14odVlEREQRRfKuIsPatahavgJJCxei78cfQZOfj6IFN8NZW9vm+eaftkE/61LkrnwLfd5/D8q0dBT9fgEclZV+50VPmYIB33/ne2Q+FVmb3XJz4sAl33knYufMAVwulN5zL5q+/17qkoiIiCKK5MGu9q2ViLv6asTNnQN1Xh7Sli6BTKNBw0cft3l+5pNPIOE3v4Fm8GCo+/VD+qN/A9xumDZv9jtPUKmgSE72PeSxse3WYLPZYDAYfA+j0RjS79gW3k4scIIgIP1vf4XukpmAw4GS2++AaetPUpdFREQUMSQNdqLdDuv+/YieOMF3TJDJED1hAiy7dnWoDbfFCtHpbBXczD/9hMMTJ+HYzEtQvmTJGfdBW7ZsGWJjY32PgoKCoL5PIAxWBwD22AVKkMuRuWIFYs4/H6LNhuI//pHhjoiIqJmkwc5Z3wC4XJAnJvodlyclwllT06E2qp56EoqUFERPnOg7Fj1lMjJWLEfOm28i5b57Yd62HcW3/AGiy9VmG4sWLUJjY6PvUVhYGPR36iiDxRPsYrW860SgBJUKmc/+A9ETJ0I0m1F8yy1o+v4HqcsiIiKSXLfuLqp55VUY1n6B3LdXQqZW+47Hzprl+7smfyDU+fk4duFFMP/0E6InTGjVjlqthvqU9xsMhq4tHICheSiWwS44MrUaWS+9iNI770LTt9+i5LbbkPnsP6CbNk3q0oiIqJt6e/MJ/OvbX1DdZMPgdD2W/moIRmbHtXnuez8V4eOfS3CowjN9a1hWLP588aB2zw8XSXvsFPFxgFwO12kLJVw1tVAkJZ3xvbWvv4HaV19FzmuvQZOff8ZzVdnZkMfHw36yqLMlh4y3x06vYbALlkytRtbzz0F30UUQHQ6U3HFnu3MziYiIzuSz3WV4dM0B3DVjAD6/YzIK0nW48fWtqGmytXn+ll9q8asRGXjvlnPx8W2TkB6rxQ2vb0VFozXMlfuTNNgJKhU0Q4bAtHmL75jodsO0ZQu0I0e2+77a115DzUsvIefVV6AdNvSsn+OoqICroQGKlORQlB0Sjd5gxx67ThFUKmQ+/RRir7gCcLlQ/tBDqH7hBd6hgoiIAvLaD8dx3bhsXDM2GwNSdXhs9jBoVXJ8sL24zfOfvW4UbpjQB0MyYpGXEoMVc4dDFIEfj3ZsKllXkXxVbOJN89GwejUaPvkUtmPHULFkKdwWC+LmXAkAKLv/flQ99bTv/JpXX0X1s88h/bHHoMzMhLO6Gs7qarhNJgCA22RC5eNPwLJrF+wlpTBt3oyS2xZClZOD6MmTJfmObfEunuBQbOcJCgXSly9D4i23AABqnv8nyh9+GKLDIXFlREQkNaPR6Lfzhc3WugfO7nRjX2kjJuW1jBbKZAIm5SXh55MNHfoci8MFh8uNuChpf69LPsdOf+mlcNbVo/r55+CqroF68GDkvPqKbyjWUVYOCC35s+G99yE6HCi96y6/dpIWLkTyHbcDcjlshw6h+NNP4TIaoUxORvSkSUi+607IVKqwfrczaemxk/w/QY8gCAJS7rkbyvQ0VPztUTR++BEcJ04i89l/QHHa4hwiIuo9Tt/pYvHixViyZInfsXqzHS63iKQYtd/x5Bg1jlWbOvQ5y784gFS9xi8cSiEiUkXC9fOQcP28Nl/Lfedtv+d5G9afsS2ZRoOc118LWW1dxWDh4omuEP/rX0ORloay+/4M8/btOH711cj+5z+hCcMWNkREFHkKCwuRmZnpe37qYslQeXHjUXy2uxzv33IuNEp5yNsPhORDsb2VdyiWiydCT3fBBejzwSqocnPhLCvHiV//BvUffMB5d0REvZBOp4Ner/c92gp28VEqyGVCq4US1U02JMecOQi+8t0xvLTxGN75/TgMTteHtPZgMNhJpJH72HUpdf/+6LP6A0RPnQLRZkPFI4tRevc9cIVhKxsiIupeVAoZhmbGYtMpCx/cbhGbjtZidG5cu+97+dtjeH79Uaz83TgMz2r/vHBisJOAKIot250w2HUZuV6P7JdfRsp99wIKBYxffonjV86BeedOqUsjIqIIs2ByX7y3rRgf7ijB0SojHvp0H8x2J64ekw0AuGfVLqz48qDv/Jc2HsPTXx3G41cNR1a8FlVGK6qMVpia7wUvlYiYY9fbNNmccDePCnIotmsJMhkSFyxA1DnnoPTe++AoKcHJ629A0m1/RNLNN0OIoAU1REQknctHZKDOZMczXx9GtdGGwRl6rPzdOCTrPEOxpQ0WCILgO//fW07C7nLjj+/+7NfOXdMH4O4LB4a19lMJIicetVJSUoLs7GwUFxcjKysr5O2XNlgwafkGqOQyHHp0pt8PCnUdl9GIisVLYFi7FgCgHjgQ6Y89Cu2wYRJXRkREodbVv8sjFYdiJWA4ZasThrrwket0yHjqSWQ88QTk8fGwHT6ME9deh8oVj8NtsUhdHhERUacx2EmAd52QjiAIiL38MvT7fA30l10GuN2oe/NN/PKrK2Bcv54rZ4mIqFtjsJMA7xMrPUVCAjKffAJZL78ERXo6HMXFKFl4O4p+9ztYDx2WujwiIqKgMNhJgD12kUN3/vno99lnSPzDHyCoVDBv3oLjV16J8sVL4Kytlbo8IiKigDDYScBg5V0nIok8Jhopd/8J/dZ+Dt3MmYDbjYZVq3D0wotQ9fQzcNbXS10iERFRhzDYSaBlKJa7zUQSVVYWsv7xDHL//Q40Q4dCNJtR+8orODbjQlQ9+yxcjY1Sl0hERHRGDHYS4F0nIlvU2LHos/oDZL34ItSDB8NtMqH2pZdxdPoMVD7xBBwVFVKXSERE1CYGOwn47hPLYBexBEGAbtoF6PvxR8h8/jmo8/PhbmpC3etv4OiMC1H65/8Ha2Gh1GUSERH5YbCTAFfFdh+CIEB/4YXo+8nHyHrpRUSNGwc4nTB89hmOz5mLk9ffgMbP1sBts529MSIioi7GSV4SMFi4eKK7EWQy6C64ALoLLoBl337UvfUWDF98AfP27TBv3w75o7GInT0bcddcDXX//lKXS0REvRR77CTQMhTLXN0daYcOQeaTTyBv/Tok3XE7FOnpcDU2om7lSvwy6zIcv+Za1L39Dpw1NVKXSkREvQyDnQS4eKJnUKalIXnhQuSt+xrZ/3oZMdOnA3I5rHv2oPLvf8eR885H0YKb0fDJp9wyhYiIwoJdRhLgHLueRZDLEXPeeYg57zw4a2pgWPsFGtesgXXPHph++AGmH34A5HJEjR0L3fTp0E2fBmVmptRlExFRD8RgF2ZOlxsmuwsAe+x6IkVSEhJuvAEJN94A+4kTaFzzOYxffw3boUMwb90K89atqPz736EuGAzdBdMQPWkStMOHQVDwnyIREXUef5uEmfeuEwCg4wbFPZqqTx8k374QybcvhL24GMb169G0bj3MP/8MW+EB2AoPoOaFFyCLiUHU+PGInjgB0RMnQtWnDwRBkLp8IiLqhpgswsw7DButkkMh5xTH3kKVnY3Em25C4k03wVlXh6ZvNqLph+9h3rQZrsZGNK1fj6b16wEAivR0RI0Zg6gxo6EdPQbqAXkQZPxZISKis2OwCzMunCBFQgLi5s5B3Nw5EF0uWAsPwLRpE0ybNsHy889wlpfDsGYNDGvWAABkej2iRo2CdtQoaIYNhXboUMhjYyX+FkREFIkY7MKMd52gUwlyObTDhkI7bCiS/nAL3GYzLLt3w7zjZ1h+3gHzrt1wGwxo+vZbNH37re99ypwcaIcOgWbIUGiGDoVmSAHkMTESfhMiIooEDHZh5t2cmMGO2iKLikL0hAmInjABACA6nbAePATLju2w7N4Ny779cBQV+R6GtV/43qvMyYF6wACoBw6AZuBAqAcOhCo3lwsziIh6Ef4vfpg1cqsTCoCgUEA7dAi0Q4f4jrkaGmAtLIRl335Y9+2Ddd8+OMrKfGHPO1cPAASlEqr+/T2Br19fqPr08TxycyGLipLiKxERURdisAsz3nWCOkseF4foiRMRPXGi75izvh62Q4dgO3wEtiOHYT18GLYjRyGazbAdPAjbwYOt2lGkpTUHvdyWwJedDWVGBmRabTi/EhERhQjTRZhx8QR1BUV8PBTnnovoc8/1HRPdbjjKymBrDnn2Eyd8D1d9PZwVFXBWVMC8ZUur9uRJSVBmZkCVmQVlVhaUmZlQZmVClZkJRUYGZCpVOL8eERF1EINdmPGuExQugkwGVVYWVFlZ0E2b5veaq6EB9hMnYPOGveMnYD95Eo6SEribmuCqqYGrpgbW3XvaaFiAIjkZirQ0KFNToEhNgyI1Bcq0NChSU6FMTYUiNRUyjSZM35SIiLwY7MLMu0Exe+xISvK4OGhHjoR25Ei/46Iowm0wwF5SAkdpKRwlpc1/lsBRVgp7SSlEiwXOqio4q6pgPdNnxMZCkdYc+lJTIU9MhCIpGYqkRCgSEyFPSoIiKQmymBhuyExEFCIMdmHmWzzBYEcRSBAEyGNjoY2NhXbIkFavi6IIV10dHOUVcFZWwFFZCWdFJZyVlc1/9xwTLRa4GhvhamyE7dChM3+mSgVFUpIn6CUmNv89EYrEJCgSEyCPj4c8Ls73p0yt7qqvT0TU7THYhVnLUCwvPXU/giB4wldiIjC0dfADmnv9jEZP2KuohLPKE/pcNbVw1tbC2TzM66ythbupCaLd7lnVW1bWsRqioqCIi2sJe77g5zmm8DsWD7leD0GrZa8gEfUKTBdhZuDiCerhBEGAXK+HXK+HesCAM57rtlrhrKmFq7YGzpoaOGtq4axtDn41tXDV1cHV2ABnfQNc9fWAywXRbIbDbO5wEAQAKBSQ63SQ6/WQNdcm0+sg1+khj9VDptM316zz/D1WD5lOB3lsLOQ6HQQl/70SUffAYBdmvPMEUQuZRgNVViaQlXnWc0VR9CzsqK/3PBoa4Kyvh6u+Aa6GBt8xz5/1cDY0wFXfADidgNPpe18wBK22JfhFRUMWE+N5REdDFhMNWXQ05DExkEW3HJP7Xm/5U1Cp2HNIRF2KwS6MRFH03XmCPXZEgREEwdPrptMBOTkdeo8oip75fgYDXAYD3AYDXAYj3EYDXI0GuIwGuA1Gz+tGA9yNBriMxubzDHA3NXnasVjgtFjgrKzs3JdQKiGPivILe7LoaMiioiDTaiGL0kIWFQVBq4VMG9Xuc5lW6zkWFQ2ZVgNBLu9cXUTUYzDYhZHV4Ybd5QbAHjuicBAEAUJUFGRRUVCmpQX8ftHl8vQSeoOe0Qi3yeQ51tQEt8kMd1OT52EywWVqgrvJ5DvHe9xtNnsadDh8i0pC+j3V6uZgGAUhqjkENj+XRWlbgqFGDUGtgaBRQ6bRNv+p8bxfo4Gg1niColrjOVejgUzt+VNQq9nbSNQNMNiFkXcYVi4TEK3i/8MminSCXO6ZZxcb26l2RJcLbrPZL/C5TCZPCGxqgttigdtihmixeMKixdJyzGyG22xpOWZuPmaxAKLoad9mg8tmg6uhIQTfun1+QU+jhkytgaDVeP70PtdofAFSplF7hp9VzX+qVRBUKshUKk9Q9L2mPO3YKce9x3jPY6IO4b+UMGo8ZUUs/58vUe8hyOUtw8ghIooiRJvNExjNFoiW5kBo9oQ/X1D0PbdAtFrhtlkhWm2+P0WbFW5Ly3HPOc1/Wq2Ay9XymVYrXFYrEOIexw6RyU4JfkrIfGHxzMcEhRKC8vSHotUxKE4/pmr3XKHVuUpAqeT/rlNEYLALIwP3sCOiEBEEobl3TAMkdN3niA7HKUGvJQiKNk/wE9t9zXNcdNjhttsh2u0Qbc1/2u2eUOpofUy0t5x/aqiE2w3RYoFosQAAXO3UK6nTA18bAVBQKAClwhM45XLPc4XCc65cDkGpAOSn/V2hgKCQe85r67lSAcjlnjYVzW22eq7w/7tS0ebn+/5+6nOZTOorSwFgsAsj71AsF04QUXchKJWQK5VATEzYP1t0On2hzxcOTwmAot0O96nB0N4cDG02iHYHRIcDosPe/KcDcDp9f/e9fuoxx+nHTnmvo/V53qFwH6fT897m8NmjeAOeN4B6/+73p9wTNOUyT3jsyGtyOSCXIX3xYsjj4qT+lj1CRAS7unffRd3rb8BZUwP1oEFI+8tD0A4f3u75hi+/RPWzz8FRWgpVbi5S7rsXMeed53tdFEXUPP886levhttghHb0KKQvXgxVnz5h+Dbta+R9YomIOszbc4SoKETirGTR5WodCh3O0wJhW+HRCdHlbA6CLs/rpz2Hy9l8ngui0wGcep7L1f5rp7fpO8/ZEjxPfX7aa63CqpfTCREA7Ha0c0anpD34YBe02jtJHuwMa9eiavkKpC1ZAu2I4ahb+TaKFtyM/l+s9exufxrzzztReu99SLnnbsScfz4a16xB8e13oO9HH0IzcCAAoPa111D3zr+RsXwZlFlZqH72ORQtuBn9Pl8j6e2IRmTF4W+zhyI5hrdEIiLq7gS53NPjpNFIXUrIiG53qxAIlwuiy+0Jm253SyA8/TXfc5ff3+FyQXS6AHf7r8kk6BHuqQRRbC+eh8fxa66FduhQpD3yMADPD9XR8y9A/PXXI+mWm1udX3L33RDNFmT/6+WWNq69FppBg5G+dAlEUcSRqVOReNNvkfj73wEAXEYjjkyajPRlf0fsrFmt2rTZbLDZbL7npaWlKCgoQHFxMbKyskL9lYmIiKiLlZSUIDs7u9f9Lpd0RqRot8O6fz+iJ07wHRNkMkRPmADLrl1tvseya7ff+QAQM2my73xHSQlc1TV+58h1OmiHD4dl1+4221y2bBliY2N9j4KCgs59MSIiIiIJSBrsnPUNgMsF+WlDrvKkRDhratp+T00N5IlJ7Z7vrPb82brNJDhrqttsc9GiRWhsbPQ9CgsLg/k6RERERJKSfI5dJFCr1VCfMvfOYDBIWA0RERFRcCTtsVPExwFyOVy1tX7HXTW1UCQltf2epCS4amvaPV+R7PmzdZs1UCQlh6hyIiIiosgjabATVCpohgyBafMW3zHR7YZpyxZoR45s8z3akSP8zgcA06ZNvvOVWVmQJyf5neNqaoJlzx5oR44I+XcgIiIiihSSbyedeNN8NKxejYZPPoXt2DFULFkKt8WCuDlXAgDK7r8fVU897Ts/4YYb0fTDD6h9403YfvkF1c//E5b9+xE/7zcAPLuxJ9x4I2pefhnGDRtgPXQYZfc/AEVKCnQzZkjyHYmIiIjCQfI5dvpLL4Wzrh7Vzz8HV3UN1IMHI+fVV3xDq46yckBoyZ9Ro0ch88knUP2PZ1H9zDNQ9clF9j+f9+1hBwCJCxZAtFhQ/shiuA0GaMeMRvarr0i6hx0RERFRV5N8H7tI1Fv3viEiIuopeuvvcsmHYomIiIgoNBjsiIiIiHoIBjsiIiKiHoLBjoiIiKiHYLAjIiIi6iEY7IiIiIh6CAY7IiIioh5C8g2KI5Hb7QYAlJeXS1wJERERBcP7O9z7O723YLBrQ2VlJQBg3LhxEldCREREnVFZWYmcnBypywgb3nmiDU6nEzt37kRqaipkstCMVhuNRhQUFKCwsBA6nS4kbfZkvF6B4fUKDK9Xx/FaBYbXKzBdeb3cbjcqKysxatQoKBS9px+LwS5MDAYDYmNj0djYCL1eL3U5EY/XKzC8XoHh9eo4XqvA8HoFhtcr9Lh4goiIiKiHYLAjIiIi6iEY7MJErVZj8eLFUKvVUpfSLfB6BYbXKzC8Xh3HaxUYXq/A8HqFHufYEREREfUQ7LEjIiIi6iEY7IiIiIh6CAY7IiIioh6CwY6IiIioh2CwC5MXXngBffr0gUajwfjx4/HTTz9JXZLklixZAkEQ/B6DBg3yvW61WrFw4UIkJiYiJiYGc+fO9d3urTf47rvvcPnllyMjIwOCIODTTz/1e10URTzyyCNIT0+HVqvFjBkzcOTIEb9z6urqMG/ePOj1esTFxeH3v/89mpqawvgtwuds1+umm25q9fM2c+ZMv3N6y/VatmwZzjnnHOh0OqSkpGD27Nk4dOiQ3zkd+fdXVFSEWbNmISoqCikpKfjzn/8Mp9MZzq8SFh25Xueff36rn69bb73V75zecr1eeuklDB8+HHq9Hnq9HhMmTMAXX3zhe50/W12LwS4MVq1ahXvuuQeLFy/Gzz//jBEjRuDiiy9GVVWV1KVJbsiQISgvL/c9fvjhB99rd999Nz777DOsXr0a3377LcrKyjBnzhwJqw0vk8mEESNG4IUXXmjz9ccffxzPPfccXn75ZWzduhXR0dG4+OKLYbVafefMmzcP+/fvx9dff401a9bgu+++wy233BKurxBWZ7teADBz5ky/n7f33nvP7/Xecr2+/fZbLFy4EFu2bMHXX38Nh8OBiy66CCaTyXfO2f79uVwuzJo1C3a7HZs2bcLKlSvx1ltv4ZFHHpHiK3WpjlwvALj55pv9fr4ef/xx32u96XplZWVh+fLl2LFjB7Zv345p06bhiiuuwP79+wHwZ6vLidTlxo0bJy5cuND33OVyiRkZGeKyZcskrEp6ixcvFkeMGNHmaw0NDaJSqRRXr17tO3bgwAERgLh58+YwVRg5AIiffPKJ77nb7RbT0tLEJ554wnesoaFBVKvV4nvvvSeKoigWFhaKAMRt27b5zvniiy9EQRDE0tLSsNUuhdOvlyiK4vz588Urrrii3ff05utVVVUlAhC//fZbURQ79u9v7dq1okwmEysqKnznvPTSS6JerxdtNlt4v0CYnX69RFEUzzvvPPGuu+5q9z29+XqJoijGx8eLr732Gn+2woA9dl3Mbrdjx44dmDFjhu+YTCbDjBkzsHnzZgkriwxHjhxBRkYG+vXrh3nz5qGoqAgAsGPHDjgcDr/rNmjQIOTk5PC6ATh+/DgqKir8rk9sbCzGjx/vuz6bN29GXFwcxo4d6ztnxowZkMlk2Lp1a9hrjgQbN25ESkoK8vPz8cc//hG1tbW+13rz9WpsbAQAJCQkAOjYv7/Nmzdj2LBhSE1N9Z1z8cUXw2Aw+HpmeqrTr5fXu+++i6SkJAwdOhSLFi2C2Wz2vdZbr5fL5cL7778Pk8mECRMm8GcrDBRSF9DT1dTUwOVy+f2AAkBqaioOHjwoUVWRYfz48XjrrbeQn5+P8vJyLF26FFOmTMG+fftQUVEBlUqFuLg4v/ekpqaioqJCmoIjiPcatPVz5X2toqICKSkpfq8rFAokJCT0yms4c+ZMzJkzB3379sWxY8fw4IMP4pJLLsHmzZshl8t77fVyu93405/+hEmTJmHo0KEA0KF/fxUVFW3+/Hlf66naul4A8Jvf/Aa5ubnIyMjAnj17cP/99+PQoUP4+OOPAfS+67V3715MmDABVqsVMTEx+OSTT1BQUIBdu3bxZ6uLMdiRZC655BLf34cPH47x48cjNzcXH3zwAbRarYSVUU903XXX+f4+bNgwDB8+HP3798fGjRsxffp0CSuT1sKFC7Fv3z6/+a3Uvvau16lzMYcNG4b09HRMnz4dx44dQ//+/cNdpuTy8/Oxa9cuNDY24sMPP8T8+fPx7bffSl1Wr8Ch2C6WlJQEuVzeasVPZWUl0tLSJKoqMsXFxWHgwIE4evQo0tLSYLfb0dDQ4HcOr5uH9xqc6ecqLS2t1QIdp9OJuro6XkMA/fr1Q1JSEo4ePQqgd16v22+/HWvWrME333yDrKws3/GO/PtLS0tr8+fP+1pP1N71asv48eMBwO/nqzddL5VKhby8PIwZMwbLli3DiBEj8Oyzz/JnKwwY7LqYSqXCmDFjsH79et8xt9uN9evXY8KECRJWFnmamppw7NgxpKenY8yYMVAqlX7X7dChQygqKuJ1A9C3b1+kpaX5XR+DwYCtW7f6rs+ECRPQ0NCAHTt2+M7ZsGED3G6375dOb1ZSUoLa2lqkp6cD6F3XSxRF3H777fjkk0+wYcMG9O3b1+/1jvz7mzBhAvbu3esXhr/++mvo9XoUFBSE54uEydmuV1t27doFAH4/X73lerXF7XbDZrPxZyscpF690Ru8//77olqtFt966y2xsLBQvOWWW8S4uDi/FT+90b333itu3LhRPH78uPjjjz+KM2bMEJOSksSqqipRFEXx1ltvFXNycsQNGzaI27dvFydMmCBOmDBB4qrDx2g0ijt37hR37twpAhCffvppcefOneLJkydFURTF5cuXi3FxceJ//vMfcc+ePeIVV1wh9u3bV7RYLL42Zs6cKY4aNUrcunWr+MMPP4gDBgwQf/3rX0v1lbrUma6X0WgU77vvPnHz5s3i8ePHxXXr1omjR48WBwwYIFqtVl8bveV6/fGPfxRjY2PFjRs3iuXl5b6H2Wz2nXO2f39Op1McOnSoeNFFF4m7du0Sv/zySzE5OVlctGiRFF+pS53teh09elT861//Km7fvl08fvy4+J///Efs16+fOHXqVF8bvel6PfDAA+K3334rHj9+XNyzZ4/4wAMPiIIgiF999ZUoivzZ6moMdmHy/PPPizk5OaJKpRLHjRsnbtmyReqSJHfttdeK6enpokqlEjMzM8Vrr71WPHr0qO91i8Ui3nbbbWJ8fLwYFRUlXnnllWJ5ebmEFYfXN998IwJo9Zg/f74oip4tTx5++GExNTVVVKvV4vTp08VDhw75tVFbWyv++te/FmNiYkS9Xi/+9re/FY1GowTfpuud6XqZzWbxoosuEpOTk0WlUinm5uaKN998c6v/c9Vbrldb1wmA+Oabb/rO6ci/vxMnToiXXHKJqNVqxaSkJPHee+8VHQ5HmL9N1zvb9SoqKhKnTp0qJiQkiGq1WszLyxP//Oc/i42NjX7t9Jbr9bvf/U7Mzc0VVSqVmJycLE6fPt0X6kSRP1tdTRBFUQxf/yARERERdRXOsSMiIiLqIRjsiIiIiHoIBjsiIiKiHoLBjoiIiKiHYLAjIiIi6iEY7IiIiIh6CAY7IiIioh6CwY6IiIioh2CwIyIKgCAI+PTTT6Uug4ioTQx2RNRt3HTTTRAEodVj5syZUpdGRBQRFFIXQEQUiJkzZ+LNN9/0O6ZWqyWqhogosrDHjoi6FbVajbS0NL9HfHw8AM8w6UsvvYRLLrkEWq0W/fr1w4cffuj3/r1792LatGnQarVITEzELbfcgqamJr9z3njjDQwZMgRqtRrp6em4/fbb/V6vqanBlVdeiaioKAwYMAD//e9/u/ZLExF1EIMdEfUoDz/8MObOnYvdu3dj3rx5uO6663DgwAEAgMlkwsUXX4z4+Hhs27YNq1evxrp16/yC20svvYSFCxfilltuwd69e/Hf//4XeXl5fp+xdOlSXHPNNdizZw8uvfRSzJs3D3V1dWH9nkREbRKJiLqJ+fPni3K5XIyOjvZ7PPbYY6IoiiIA8dZbb/V7z/jx48U//vGPoiiK4iuvvCLGx8eLTU1Nvtc///xzUSaTiRUVFaIoimJGRob40EMPtVsDAPEvf/mL73lTU5MIQPziiy9C9j2JiILFOXZE1K1ccMEFeOmll/yOJSQk+P4+YcIEv9cmTJiAXbt2AQAOHDiAESNGIDo62vf6pEmT4Ha7cejQIQiCgLKyMkyfPv2MNQwfPtz39+joaOj1elRVVQX7lYiIQobBjoi6lejo6FZDo6Gi1Wo7dJ5SqfR7LggC3G53V5RERBQQzrEjoh5ly5YtrZ4PHjwYADB48GDs3r0bJpPJ9/qPP/4ImUyG/Px86HQ69OnTB+vXrw9rzUREocIeOyLqVmw2GyoqKvyOKRQKJCUlAQBWr16NsWPHYvLkyXj33Xfx008/4fXXXwcAzJs3D4sXL8b8+fOxZMkSVFdX44477sANN9yA1NRUAMCSJUtw6623IiUlBZdccgmMRiN+/PFH3HHHHeH9okREQWCwI6Ju5csvv0R6errfsfz8fBw8eBCAZ8Xq+++/j9tuuw3p6el47733UFBQAACIiorC//73P9x1110455xzEBUVhblz5+Lpp5/2tTV//nxYrVY888wzuO+++5CUlISrrroqfF+QiKgTBFEURamLICIKBUEQ8Mknn2D27NlSl0JEJAnOsSMiIiLqIRjsiIiIiHoIzrEjoh6DM0uIqLdjjx0RERFRD8FgR0RERNRDMNgRERER9RAMdkREREQ9BIMdERERUQ/BYEdERETUQzDYEREREfUQDHZEREREPcT/BzayTH7jzEB2AAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 640x480 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Plotting\n",
    "fig, ax1 = plt.subplots()\n",
    "\n",
    "color = 'tab:red'\n",
    "ax1.set_xlabel('Epoch')\n",
    "ax1.set_ylabel('Training Loss', color=color)\n",
    "ax1.plot(range(1, epochs+1), train_losses, color=color)\n",
    "ax1.tick_params(axis='y', labelcolor=color)\n",
    "\n",
    "ax2 = ax1.twinx()\n",
    "color = 'tab:blue'\n",
    "ax2.set_ylabel('Test Accuracy', color=color)\n",
    "ax2.plot(range(1, epochs+1), test_accuracies, color=color)\n",
    "ax2.tick_params(axis='y', labelcolor=color)\n",
    "\n",
    "fig.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "66625c61-dcfd-4fe6-acd1-901d5980bfe2",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "prac",
   "language": "python",
   "name": "prac"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
