OpenJij/OpenJij

View on GitHub
docs/tutorial/en/physics/ClassicalSystem.ipynb

Summary

Maintainability
Test Coverage
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Numerical Simulation of Classical Ising Model using the Core Interface"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In this tutorial, we will use OpenJij's core interface (core python interface) to perform numerical simulations of the Ising model with random interactions and random longitudinal magnetic fields.\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First, we define Graph and $J_{ij}, h_i$ for the system you wish to simulate numerically."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "import openjij.cxxjij.graph as G\n",
    "# Set the problem size to 100\n",
    "N = 100\n",
    "\n",
    "graph = G.Dense(N)\n",
    "# Use below for sparse\n",
    "#graph = G.Sparse(N)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next, we set $J_{ij}, h_i$.\n",
    "We set the values generated from a Gaussian distribution with a mean of 0 and a standard deviation of 1."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Use numpy for random number generation\n",
    "# !pip install numpy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "mu, sigma = 0, 1\n",
    "\n",
    "for i in range(N):\n",
    "    for j in range(N):\n",
    "        # Jij value would be too large, so we use 1/N for standardization.\n",
    "        graph[i,j] = 0 if i == j else np.random.normal()/N\n",
    "\n",
    "for i in range(N):\n",
    "    graph[i] = np.random.normal()/N"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The longitudinal magnetic field can be accessed either by `graph[i]` or by `graph[i,i]`.\n",
    "$J_{ij}$ and $J_{ji}$ are automatically the same value by definition of the Ising model.\n",
    "Let us try the following output."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.5\n",
      "0.5\n",
      "-0.6\n",
      "-0.6\n"
     ]
    }
   ],
   "source": [
    "graph[20] = 0.5\n",
    "print(graph[20,20])\n",
    "print(graph[20])\n",
    "graph[12,34] = -0.6\n",
    "print(graph[12,34])\n",
    "print(graph[34,12])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## System\n",
    "\n",
    "Next, define the system to perform the calculations.  \n",
    "\n",
    "Here we want to perform a numerical simulation of the classical Ising model, so we create a system for that model with `system.make_classical_ising`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "import openjij.cxxjij.system as S\n",
    "\n",
    "mysystem = S.make_classical_ising(graph.gen_spin(), graph)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here, we assign a randomly generated spin to the first argument and the Graph itself to the second.\n",
    "This creates a system of classical Ising models whose initial spin configuration is `graph.gen_spin()`.\n",
    "\n",
    "We can also access the system directly and read the values."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 1. -1.  1. -1. -1. -1. -1. -1. -1. -1. -1.  1. -1.  1.  1. -1. -1. -1.\n",
      " -1.  1. -1.  1. -1.  1.  1.  1. -1. -1.  1.  1. -1.  1. -1. -1. -1. -1.\n",
      "  1. -1.  1.  1. -1. -1. -1.  1. -1.  1.  1.  1.  1.  1. -1. -1. -1. -1.\n",
      "  1. -1.  1.  1.  1.  1. -1.  1. -1.  1.  1. -1.  1. -1.  1.  1. -1.  1.\n",
      "  1. -1.  1. -1.  1.  1.  1.  1.  1.  1.  1.  1.  1. -1.  1.  1. -1.  1.\n",
      " -1. -1. -1.  1.  1.  1. -1. -1.  1.  1.  1.]\n"
     ]
    }
   ],
   "source": [
    "print(mysystem.spin)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Run the Algorithm with Updater\n",
    "\n",
    "After defining the System, we select Updater and run the Algorithm."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Updater\n",
    "\n",
    "The Updater for the classical Ising model is mainly:\n",
    "\n",
    "- [SingleSpinFlip](https://github.com/OpenJij/OpenJij/blob/ec41aecfbac7e4c895e1e7a1718f06eb7ffae0ba/src/updater/single_spin_flip.hpp#L40) (update one spin at a time using the Metropolis-Hasting method)\n",
    "- [SwendsenWang](https://github.com/OpenJij/OpenJij/blob/ec41aecfbac7e4c895e1e7a1718f06eb7ffae0ba/src/updater/swendsen_wang.hpp#L45) (cluster updates by the SwendsenWang method)\n",
    "\n",
    "To run the Algorithm, you will need a **schedule list**.\n",
    "Let us start by creating a schedule list."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Algorithm\n",
    "\n",
    "#### Schedule list\n",
    "\n",
    "The schedule list is given as a list of `(parameters, number of Monte Carlo steps)`.\n",
    "The value to be entered in the parameter depends on the System.\n",
    "For example, for the classical Ising model, the parameter is the inverse temperature $\\beta$.\n",
    "Therefore, this refers to a list of temperature schedules.\n",
    "Let us set the following example."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "schedule_list = [(0.01, 10),(10, 80),(0.1, 30)]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This means that 10 Monte Carlo steps are performed at inverse temperature $\\beta=0.01$, 80 steps at $\\beta=10$, and 30 steps at $\\beta=0.1$, for a total of 120 Monte Carlo steps.  \n",
    "In annealing, the inverse temperature is often increased proportionally, so you can easily create a schedule by using the `make_classical_schedule_list` in the `utility`.\n",
    "The temperature is changed in 10 steps from $\\beta=0.1$ to $\\beta=50$, with 20 Monte Carlo steps calculated at each temperature. A total of 200 Monte Carlo steps are calculated."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[((beta: 0.100000) mcs: 20), ((beta: 0.199474) mcs: 20), ((beta: 0.397897) mcs: 20), ((beta: 0.793701) mcs: 20), ((beta: 1.583223) mcs: 20), ((beta: 3.158114) mcs: 20), ((beta: 6.299605) mcs: 20), ((beta: 12.566053) mcs: 20), ((beta: 25.065966) mcs: 20), ((beta: 50.000000) mcs: 20)]\n"
     ]
    }
   ],
   "source": [
    "import openjij.cxxjij.utility as U\n",
    "schedule_list = U.make_classical_schedule_list(0.1, 50, 20, 10)\n",
    "print(schedule_list)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Run the Algorithm\n",
    "\n",
    "By writing `Algorithm_[Updater]_run`, the calculation is performed with the specified Updater.\n",
    "In the following example, `SingleSpinFlip` is executed."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "import openjij.cxxjij.algorithm as A\n",
    "A.Algorithm_SingleSpinFlip_run(mysystem, schedule_list)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The process is over instantly, but a total of 200 Monte Carlo steps have been computed during this time.\n",
    "> `A.Algorithm_SingleSpinFlip_run(mysystem, seed, schedule_list)` allows you to run the calculation with the seed fixed. This can be used to make the results reproducible."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We use the callback to get the system for each 1 Monte Carlo step during the execution of the Algorithm.\n",
    "For the classical Ising model, we create a function with the system and parameters (inverse temperature) as arguments.  \n",
    "As an example, below we create a callback that records the value of the energy of the system."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "energies = []\n",
    "\n",
    "def callback_log_energy(system, beta):\n",
    "    #graph is the object defined previously in the Graph module\n",
    "    energies.append(graph.calc_energy(system.spin))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The same Algorithm is executed using this callback."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Take a longer schedule (total of 20000 Monte Carlo steps)\n",
    "schedule_list = U.make_classical_schedule_list(0.1, 50, 200, 100)\n",
    "A.Algorithm_SingleSpinFlip_run(mysystem, schedule_list, callback_log_energy)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The recorded system energy is plotted with Monte Carlo steps on the horizontal axis and energy on the vertical axis as follows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "# !pip install matplotlib"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjUAAAGwCAYAAABRgJRuAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8o6BhiAAAACXBIWXMAAA9hAAAPYQGoP6dpAABiN0lEQVR4nO3dd3gU5doG8HvTC0kIpJNACL13Ir1Fiqig2BAVUPGAoHgEFT4R7CCI9aigCKigiIqoVOk1dAKEXhJqGgnpPft+f0CW3WR7Zne23L/r2otk5p2ZZ7Jk58lbFUIIASIiIiI75yJ3AERERERSYFJDREREDoFJDRERETkEJjVERETkEJjUEBERkUNgUkNEREQOgUkNEREROQQ3uQOwJqVSiRs3bsDPzw8KhULucIiIiMgIQgjk5eUhIiICLi6662OcKqm5ceMGoqKi5A6DiIiIzHD16lVERkbq3O9USY2fnx+A2z8Uf39/maMhIiIiY+Tm5iIqKkr1HNfFqZKayiYnf39/JjVERER2xlDXEXYUJiIiIofApIaIiIgcApMaIiIicghMaoiIiMghMKkhIiIih8CkhoiIiBwCkxoiIiJyCExqiIiIyCEwqSEiIiKHwKSGiIiIHAKTGiIiInIITGqIiIjIITCpcXBlFUqUVSjlDoOIiMjimNQ4MKVSoOdHWxH74RaUWzixeWXFUTz09R5UKIVFr0NERKQLkxoHVlBajrTcEmQVlCIjv8Si11qdcANHr2Qj4eoti16HiIhIFyY1JCnBihoiIpIJkxonwWSDiIgcHZMaB6ZQKOQOgYiIyGqY1BAREZFDYFLjJNj6REREjo5JjQNTb3wS7FRDREQOjkmNA1PvUuMIOU1xWQVeWXEUfyVclzsUIiKyQUxqyG4s23cZqxNuYPKKBLlDISIiG8SkxoEp4FijnzILSuUOgYiIbBiTGiIiInIITGqchCP0qSEiItKHSY0D0+gobKeDuoUQKC6rkDsMIiKyA0xqyKZNXpGA5m9twOXMArlDISIiG8ekhmxOel6xqnbm72M3AAA/7L0sZ0hERGQHmNQ4MHucpyYlpwhdP9iCbrO3aGw/evWWTBEREZG9YFIjIVuetdd2I9O050ImAOBWYZnG9qNXsmWIhoiI7AmTGokcuXILXT/cYlOz3drjPDX2F7FpDl/OwvRVJ5BdyDl3iIikxqRGIuN/OoyMvBKbmu22rEKp+tqWa5HUudjg/8iCknLJzjXim3j8cuAK3l97WrJzEhHRbTb4CLFPFUrbSxquZxepvrbF+LSxtdqlvxKuo9Wsjfh250VJz5t0k6O5iIikxqRGIgqFbT2MAc2mHGvmNHPWn8Ej3+xFablSb7kNiSn4YW+yxjZb+zH+99cEAMCH687IGwgRERnEpEYitvYwBjRjUt5pfjKUaNRUcZkSC3ZcxKHLt7DhZKresuOXHcGsv0/ibGqeydcpKa/AzL8Sse1surmh1khpuRIbElPZN4aIyIYwqZGIiw0mNep1NULc7qTadMZ6fLb5nMEjE6/nIDO/xOQrLt9/dz6ZMiMTqMyCu9cxtsbrh73J+DH+MsYuOWhagCbSFc+XW89j/LLDeGxhvEWvT0RExmNSIxFb6AtyICkLfedtw85zGdX2KYXArL9PAgA+23xe73mOX8vG/V/uRqf3N5scQ25xmeFCeuj7Keapnfv6rSI9JaWjK55/7kwKeC4t3ypxEBGRYUxqJKL+B31GXgn+OXbD4k09VT3xbTySMwvxzOID1WISwvgJ+CrnijGWrpFV5nTj0VdRs2zfFbVy0iaR7685hTnrrddvRv4UmIjI8TCpkYj6Q+qBL3fjpV+O4pvt0o6YMaRqZ2AXtQe/Ugi7mFXYRYbOSRl5JVi0OwkLdlxEfpXh27rCqWlSZQdvBRGR3WFSIxH1h1xqbjEAYNNp/R1lLU1z9JPx63TXZEVvcxKn9Sfu/pzUY1Yfkm5J6vP5KKvcgC00KxIRkXGY1DgApVJg74Wb1bYfu5Z9t4wFqwZ0JTLGTvj30767nYvVK0CuZBbWJCwiInIyTGocwDc7LuLJRfurbd93KUv1tRDCKrMK17T1SD3Ey5nSTVBXWq7EYwvjtfab0ftT0dX8JElUREQkJSY1FpR4PReFpeZNsa9UCjz53T68suKo1v2FpeX45N+zOHkjB/M2ntVaRnOeGiDtTrMYAJRXKDFl5TH8duiqWfHpop6U1DSFKtdTvWRq8rTxZCoOJGVhwQ7T+jkxeSEish9Maixsxp+JZh13KiUXey9mYnXCDa37P998Hl9svYChX+zWeY6qfWrUV77+K+EG/jhyDa/9frzacaZW6OgsbkZWI3U/YaVSIKeoTO9INH2XNCaenCorih9KzsKLyw/jhp4+QUyWiIikx6TGwlYdNW/VbkOJxckbuQbP4aY2I2BQLQ+NfSslrqGRirGjioztwDtq0X60e+dfXLqpez6ZmtYoHUzO0vj+kQXxWHciVbXEAhERWQeTGolIXcNQkxFIldQTBD8vd419+5OyqhZXO676tvIKJQ4lZ2mt8ZCyr476pT/+V3uzminiL92ec2floWsmX//298Z1qqnss3Q+7e6SD9f0TBBor0O691y4iTnrz2iMGCMishV2k9TMnj0bXbp0gZ+fH0JCQjB8+HCcPVvzh541FJdVSH5OU5MoU/IObWXfX3sajyyIx/RVJ/Qee/xajmmBVaGeiGUX1mx2YnUZecYt+VD11o35OQsAjy2Mx+ML9+HeT3eqtl/PLsI7/5zErQLj1oeqUAo8/8NBzN1Q80kAd5+/if/+mlCtaSzpZgGGfrEL606kmHXeUYv2Y8GOi/h5/xXDhYmIrMxukpodO3Zg4sSJ2LdvHzZt2oSysjIMHDgQBQXSjZCxlOZvbcC2M6YtvGhrE+UtvbOa9h9HrkEIgb8SruNixu0mnc+33F12QX3yOnNqm4zN1WpSM3bkyi2zrqkut+jufWbkleBg8i0cSK5e+7VkTzJmrDauX1X8xUxsPp2OryWYtPGp7/fjz6PXMadKgjT1t2M4eSMXLy4/UqPzX83icHsisj12k9Rs2LABY8aMQatWrdCuXTssXboUV65cweHDh+UOzSj/96f+Gg5LsNQQ7vWJqZi8IgED5u8AAHy59YKO61ePp9xAs4WxEVfUYOKdh7/ei082ncOZ1Nxq19SX4FxIz4cQAiXlFbipttinoeTtdIrh/k8AUFohfY1e1c7K+cXmjcYjIrIHdpPUVJWTc7uZo06dOjrLlJSUIDc3V+MlFzlqXtQvKeU6VEfVajqUJiQXo5ccRJcPNqOgRPeD1dhErLLmyFxfbDmPwZ/tMlhOPcmJ+2QHVh66Wq0py5z8SlvyxNmLiYhqxi6TGqVSiVdeeQU9evRA69atdZabPXs2AgICVK+oqCiLxWSoOURAVFtXyNJOqY2Q6j1vm2TnVc87dNXSqPv14BX8FJ+MnecycKuwDLvOV5/92FZVHY31xh/Wr3EjIiLj2GVSM3HiRCQmJmLFihV6y02fPh05OTmq19Wr8g1jTsstQetZG3HsarbVrnno8i3DhQCTR7KoV0ykqk3op01JeQXe+OME3vrrpGrblJUJBpuh5CSEwNWsQqvMwKyhxrMxW2fWaCIiW2V3Sc2kSZOwZs0abNu2DZGRkXrLenp6wt/fX+Mlt6+2Ga7ZsDaTkxojn5sC2vu+FJRW4C8dkwrawiN5wY5L6DV3G+ZsOGPVBqGaXEupFHjo670Y+d0+JjZE5LTc5A7AWEIIvPTSS/jzzz+xfft2NGzYUO6QzKJv6n99hBBQKBQoLC2Hj4eb0ZPUGcPFxHOpd4zVd2hOke4h2fr2ye2jOyOGFu64BD8vI35FDCQR1kgxbuQUIeFOLWBh6d0Ox1LPn1SJaRMR2SK7qamZOHEili1bhp9//hl+fn5ITU1Famoqiop0T3BmTUojKzsqk5qS8gqsPHQVKTna49do4skpRuyHW9Bm1ka0nLkRfyWYN0uxJeirFZiz/ozRtTrGjhCyRVI94NUT1V3nM2pwHimiISKyP3aT1HzzzTfIyclB3759ER4ernr9+uuvcodmkoo72c9XWy/g9d+PY6DaZG26fL7lPNLzSpB3p6Ox3NPvqycq286Y9/C9UmWek28kmJvFEiyVH2jr76R+rae/P2D2udn6RETOyq6anxxBWcXt+9h+7nYykKdj3hD1+7X0vVf9y96U62UVGjdbblW6hmTL/Tb/GH9Z43tj5sMxN+bisgp4ubuad3AVUjZHEhHZK7upqXEUpszrUqnq80ruB5h60mNo/puxSw9aOpwaKS6rwAK1WqJ5GzWX3igoNTwhnlRJZ9W3VakUOJScZdRUALpiqMn/FCEE13giIrvCpMbGVD5EDCUuUqY1pj6TTSl+QM/Cmbbgq20X8NO+y4YL6vH2P6ckiaXq5Hu/HrqKRxbEY8TXe7WWv5iRj2eXHtSYDNHgNUz4j/PIgnh0em8TioxI7IiIbAGTGonU5K/1kzduz458MSMfzWasxzv/nNR7PrkbGizRRCT1KVcfvY43jViawpjJA+Xy55HbHcLPqq38XeliRj4GzN+BrWfS8dDXezWSYH0/S23vXUl5BU7dyK32f+7w5VvILS7HocuWS0xzCsvw6soE7LlgPxMyEpHtYlIjEWMfytrK7b4zw+4XW85DKW4vgqiPpVuf5O3XIs3FX/k1AcvtbCVpU97XynW3jJFbXIbvdl7C9WztI+2eXXoQ932xC78cMH5ySqn+j3y08QxWHbmOUYv2S3NCInJqdtNR2NZlFxo374q+Ghj1/imapUzPYrLN7MDb8b1NyCq4e2x+STlqeWr+NzFn9W0yrNq7rONt35CYavhYNTNXJ2J1wg18u+sS6vh4VNu/50ImAODH+GQ8GVvfuGAlwtW+iUhKrKmRSFGZcf0OjlzJxqJdlzS2/X3sBnIKy7Bey8NKGwUUBv+qb//uJqPOVZV6QgMA+y9l4sf4ZI1tlzIKzDq3tdwqMC+hM5ZUtRSPf7vP5DmHkm8WYPyy6ivT6wpJoVCo1tqquhCnNsVlFZj08xGbmguJiMhYrKmRwftrT6NtZIDq+5M3cvHCT4d0lv/lQJVmFCt2qnnuh+px7b2YabHrSZEwZFt4tuK9F03r/5F0swCXMwvQoK6vxvZjV7MxeUUChrWvd3tD1VFuWs51Q8dkjSeu5Wjdbmpfr6V7k7HmeArWHE8x6TgiIlvAmhqZJN3UrO3YX2WUkK75ayxB7rlhbsdwOwgbCMWg/BLTRwNNWHZE577K5qSqo59M8fvha6qv1ROZcqVAplrNlaEavqo1dURE9oRJjUwMJS2jF+ufUVbKypq8YvnXYRK4PfxbipmF91+yXE2Sua7e0t13ZPyyw9h5rvrMzOoJiKG1svJLtO+vbHqqZE4CW5Nki4jImpjU2CGpHzGfbzkv8RnN89jCeJy4rr0ZxRQ/V22uk5g5P39DycTxa9nVJ1lUu1KigZ+Lell7qO0iIrIEJjV2qKRciT0S9mu5ZeZIKSltO5MudwgWZcxyC4bkFJYZnMHZEH0j10ydqbqknJPyEZFtYVJjp2r6cFOXeD0X7685hVwZm6EKazBr7eXMAry6MgHn70xSl5ZbLFVYWl26mW/yMUoDVTXaEgr1TbcKS9Hu3X8xZonhZSf0pSbn0nTHbkqn4vhLmWg2YwM+31yzWj65l/wgIsfCpIZwJasQi3YnYfa603KHYpaxSw5i1ZHrePjOcgJpuYaHLtfEsn2mN28ZSmoMlXnHwFIM6rmB1M1P4348VG0phtMpuQCATzefk/hqRETmY1JDKmdSq0/Hbw8u3RlJlmfEwo9yMab16akqs+qqJyrGzDFjKUVlFXhIx/pTRES2hEkNqRy9ki13CDX2mY3WHFQohd5+NQqFcYmPMWoyRF/qxiBzVqUnIjIXkxpyKJ/VsI+HJTV/a71J5a09lLq0wrx+Wvk6asgKS8vR86OteOmXozUJi4jIaExqiKykrELfyuvVE5grJqyLJEV/20sZBdh0Os3k4yZoWbYBADadSsONnGL8c+xGTUMjIjIKkxoiG2VSUiNRrY6+db10NSXtOn8TN/Pl6/NDRFSJSQ2RDbCHkc2PLNDdWfjNP09YMRIiIu2Y1BDZgDIJ5x2y1JTCR/R0JD9/Z/6bWX8lYvoq4xMcO8jliMiOcJVuIhswf5N0o7b2mLiKuBRSc4vR8b1NqgUx/3tvE6NGYXFsFBFJiUkNkQNQb756cbnuFcGrSriaLcn1C0srNGaFtoWV34nI+bD5ichJKZUCw7/aY5Fz38wvwYIdNV9xnYjIFKypIXJSlqxMeXH5EVzONH70FhGRFFhTQ+SkLNlJlwkNEcmBNTVETqq43PyV0WtKCIESKUd8ERGBSQ2RQ1CYMdFNy5kbLRCJccYsOYgd5zLQMtxfthiIyPGw+YnIAew+nyF3CCbZce52vKdSclXbhBC4kV0EwaFTRGQmJjVEDsARFsN+/Nt96D5nK97++6TcoRCRnWJSQ0Q24UBSFgDgh/jLMkdCRPaKSQ0RERE5BHYUJiKrWXP8BgpL5Bt1RUSOjUkNEVmFUikw6eejcodBRA6MzU9EZBUO0JeZiGwckxoisoriMvObndYcv4Gvt1+otn33+Zv4fPN5KB1h+BcR1Ribn4jI4masPoFl+66YfXxls1X3RkFoH1Vbtf2p7/cDAHKKytAqwh8jOkXWKE4ism9MaojI4mqS0KjLKijRun3xniQAQGSgN2Jj6kpyLSKyP2x+IiKbZsoMw5duFlgwEiKydUxqiMimbTqVJncIRGQnmNQQkU1LvKG+PpSMgRCRzWNSQ0QOg0kPkXNjUkNEto2ZChEZiUkNEdmc6GlrUVahrLb9cmYh/vPTISRczTb6XKZ0NCYi+8akRgL80CSS3p4LNwFojmh6d80pbDyZhuFf7THqHNmFpeg9bxs+2nDGIjESkW1hUkNENqnyb4U1x1PMPsfiPcm4mlWEb7ZflCgqIrJlTGokwIoaIum9u+aU2ceWVyix7Ww6bhWUShgREdk6zihMRDYpqQYT6X2/Owmz17PJicjZ2F1NzVdffYXo6Gh4eXkhNjYWBw4ckDskrj5MZCPEnd/Gf47fkDkSIpKDXSU1v/76K1599VXMmjULR44cQbt27TBo0CCkp6fLHRoR2RAFFHKHQEQysKuk5pNPPsG4ceMwduxYtGzZEgsWLICPjw8WL16stXxJSQlyc3M1XpbA0U9E1vfqrwk69ymY0xA5JbtJakpLS3H48GHExcWptrm4uCAuLg7x8fFaj5k9ezYCAgJUr6ioKGuFS0QWturodZ37rJnTfLfzEt788wT/uCGyAXaT1Ny8eRMVFRUIDQ3V2B4aGorU1FStx0yfPh05OTmq19WrVy0SGz/KiCyjQmnmb5cVq2o+WHcay/dfwVETJgQkIstw6NFPnp6e8PT0tPh1+AcakWWsOHhF7hCMVlRaIXcIRE7PbmpqgoKC4OrqirS0NI3taWlpCAsLkykqIrKkLafNHASg5S+NCcsOa116gYgch90kNR4eHujUqRO2bNmi2qZUKrFlyxZ069ZNxsjuDiMlImltPSPdyMb1ialYW4PZiYnI9tlV89Orr76K0aNHo3PnzujatSs+++wzFBQUYOzYsXKHRkQ2wFBTcEFpuXUCISJZ2FVS8/jjjyMjIwMzZ85Eamoq2rdvjw0bNlTrPGxt7FNDZBu+2X4RT93TQLK60+KyCmw5nY5eTYPg7+Uu0VmJyFLsKqkBgEmTJmHSpElyh0FENuh6dpGk53trdSJ+O3wN3WLq4pcX7pH03EQkPbvpU0NEZCypak9/O3wNABB/KVOaExKRRTGpISKHom8SPDYVEzk2JjUS4Aclke2Ys/4MbuaXyB0GEcmASY0EOKSbyHYs3HkJKTnFcodhlLTcYrz6awISOBsxkSSY1BARyWTqb8ew6uh1DP9qj9yhEDkEJjUSYPMTEZnjUkaB3CEQORQmNUTkNK5kFRoscykjHw/+bzf+Pal9oVwisl1MaiTAihoi+3A6Jddgmf/+moDj13Lwwk+HrRAREUmJSQ0RkZpj13LkDoGIzMSkRgL65sUgIiIi62BSQ0RkBUIIfLjuNFYcuCJ3KEQOy+7WfrJFrKchIkMOXb6Fb3deAgA80bW+zNEQOSbW1EiArU9E9mXvxZtaJ7w7l5ZnsWvmFJZZ7NxEdBuTGiJyKhl5JXjyu/1aJ7wzZnSULmdSLZcQEZFxmNRIgTU1RHYjLffuEgpKpZCso/97a05p3Z5dWIpVR66hoLRckusQkW7sU0NETivm/9YBAJJm3weFQmGwfEpOEcL8vYwqW+m5Hw7h8OVbqOXJj1siS2NNjQS4oCWR/dh3KbPattUJ1w0et/LQVXSbvRUzVieadL3Dl28BAPJLWFNDZGlMaojIqfxz7Ea1befT8g0eN3fDGQDA8v1XkFPETr9EtohJjQQ4+onIvn29/SIeXxhv9O/yO3+ftGxARGQWNvISkdPYdf6mzn37k7LQo3GQzv3qCU/Ctewax5KaU4zr2UU1Pg8R3cWaGgmwoobI8WUWlEp6voe/rj6knIhqhkmNBLj2E5GTEUB5hbJGp7iRU2y4EBGZhM1PREQmunSzAE1nrMeLfRvLHQoRqWFNjQRYT0PkGI5cuWV0WaUA/rftgs79ucUcIUVkbaypkcCljAK5QyAiCWw/myHJedafSMGE5UcwqR9rcoisiTU1EvgxPlnuEIjIhsy8M+RbX02OLkIIvLLiKD5Yq33ZBSLSjUmNBFhTQ0RSOZ+ej9UJN/DdriS5QyGyO0xqJMA+NUQkldLymo2qInJmTGokwCHdRERE8mNSQ0QkkePXso36I6dCyT+EiCyBSY0EWFFDRADw4P/2YPPpdCgNJC0tZm6wUkREzoVJjQQEe9UQ0R3rTqQYXFKB/WaILIPz1EiANTVEVElh5nErDlyBi0KBlhH+ksZD5EyY1BARSWjV0etmHTdt1QkAwMr/dJMyHCKnwuYnCbCihoikkp7HhS6JzMWkRgIc0k1EUpn081G5QyCyW0xqJMCUhoiISH5MaoiIiMghMKmRAqtqiIiIZMekRgLMaYiIiOTHpEYC7ChMRHIQQhicvZjImTCpkQA/U4hIDk99vx/3fbGLa0kR3cGkxoqGtY+QOwQisjNnUnPxxZbzKCqtqLZvz4VMnEnNw/n0PBkiI7I9TGokYGjtpye6ROHhjvUw8/6WVorItm2d0kfuEIjsxuDPduGTTefw2eZzGtsX706SKSIi28WkRgKGutR0bVgHnzzWHnVreVolnhEdI61yHXPFBNdCryZBcodBZFdOXM9RfV1QUo5315ySMRoi22RWUtOnTx/8+OOPKCoqkjoeu2Rr/YQf62zbSQ0ADGwVZlL5RsG+FoqEyP6UV2h+6ExYdgTJNwtkiobIdpiV1HTo0AFTp05FWFgYxo0bh3379kkdl4bk5GQ899xzaNiwIby9vdGoUSPMmjULpaWlFr2upc17pK1Zx/VsrL+Wo0t0HbPOa8uWPR8rdwhENivpZgHG/XhIY1tJeQW+352EC+xvQ07ErKTms88+w40bN7BkyRKkp6ejd+/eaNmyJT7++GOkpaVJHSPOnDkDpVKJhQsX4uTJk/j000+xYMEC/N///Z/k1zJHjJZahDHdow0e92jnKCTNvs/k600d1Kzatq4N7yYyCgUweUATk89ry0L8vOQOgcjqrmffrQ1XrxHW1o/vcmahxvff7riE99acQtwnOy0WH5GtMbtPjZubGx5++GH89ddfuHbtGp588km89dZbiIqKwvDhw7F161bJghw8eDCWLFmCgQMHIiYmBg8++CCmTp2KVatW6T2upKQEubm5Gi9LCA+o/sD19nBVfR3g7a7zWIVCYfL12kUGaHzfup5/tSTGxlrEiMgM/12RoPr6VEouPlx3GjlFZUYde+TKLQtFRWS7atxR+MCBA5g1axbmz5+PkJAQTJ8+HUFBQbj//vsxdepUKWLUKicnB3Xq6G9mmT17NgICAlSvqKgoi8TSuYH2OOaOaItnujVAv2Yhkl3r4of3VUuEGtT1hempkX1xdXH0OySqTr2mJqeoDN/uvIQP157We8zSPUn4evsFS4dGZJPMSmrS09Mxf/58tG7dGr169UJGRgZ++eUXJCcn45133sGiRYvw77//YsGCBVLHCwC4cOECvvzyS/znP//RW2769OnIyclRva5evWqReOoFegMAwvzv1tgoADzWJQrvDmsNFwkfyLb6cP/umc5am+GISFqnU3XXOH+78yLe/ucU5m44i9TcEitGRWQbzEpqIiMjsWjRIowePRrXrl3D77//jsGDB2vUILRt2xZdunTRe55p06ZBoVDofZ05c0bjmOvXr2Pw4MF49NFHMW7cOL3n9/T0hL+/v8bLEirbumv73G1mMqNVqUaqTShq5SFZ97YMxcMd6hldfmibcJMTtD9f7G5qWEQORwjtv96lFUp8uO7u52VxWfXJ+ogcnZs5B23ZsgW9evXSW8bf3x/btm3TW2bKlCkYM2aM3jIxMTGqr2/cuIF+/fqhe/fu+Pbbb42OVw4KKzYIKQAo1T7lFAqFxfvU/PhsVzyz+IDGNlNqpOr4euDUu4Pg7uKCZxYfwO4LNw0e06F+oMlxEjka9flqiEiTWUmNoYTGWMHBwQgODjaq7PXr19GvXz906tQJS5YsgYuL7cwbaGhGYWtQVvnTrer3UvP1dK22zcXE6ilPt9vnaBbmZ1RSQ+Rs1PvUqDPmt9s2G6qJLMuspKZDhw5aR+0oFAp4eXmhcePGGDNmDPr161fjAIHbCU3fvn3RoEEDfPzxx8jIyFDtCwszbRI3S1L/mVi7+anqh5wc69vZaHcfybSLDMCxa/wrmeRnzB8B6h8Bmfkl1WY0X3HgCqLq+KCHgXmviOyJWdUdgwcPxqVLl+Dr64t+/fqhX79+qFWrFi5evIguXbogJSUFcXFx+OuvvyQJctOmTbhw4QK2bNmCyMhIhIeHq162QFuliLWf78oqWYwcsxybWlMjh/F9GqFpaC2zjo2o7S1xNETmScowbfbgT6usG3XiWg6mrTqBUYv2SxkWkezMSmpu3ryJKVOmYNeuXZg/fz7mz5+PnTt3YurUqSgoKMC///6LGTNm4L333pMkyDFjxkAIofVlCyqj0HikW/kBX7VmxtKX1/ajt4ekBgCe6RZt1nF2cnvkBLIKTBvZVFCi2WlYV7MWkb0zK6lZuXIlRo4cWW37E088gZUrVwIARo4cibNnz9YsOjsj10NPoVBU60PzfM+GVo/D1pqfgmp5VNuWnlssQyRE0voh/rLBMnnFxk3SR+RIzEpqvLy8sHfv3mrb9+7dCy+v23O1KJVK1deOTluNkTWf7yM61qtWc6Left6mXgBq6vXB1ZdmqKqTjkkIDTH0szr4ZpzR51o8prPe/auOXjf6XObydq/eiVoKtpY0km27ma9vbTzbqOUmkppZSc1LL72E8ePHY/LkyVi2bBmWLVuGyZMnY8KECXj55ZcBABs3bkT79u2ljNXmqdfUWGsiupf7N0bfZiEWH+30Yt/GGt9ru1qbyAD8+sI92P2GNB3EASB5zlAE+3kaLgjA18O1yuzN2rMAS/ykourc7W8zrpdlasncbGjEH9mXxOs5+GjDGRSUlMsdCpFFmTX6acaMGWjYsCH+97//4aeffgIANGvWDN999x2efPJJAMD48eMxYcIE6SK1YeoPyd/Gd8Phy7fwQNsIq1w7Jvh2p1djk5pODQJx+LL2NWHubxuONcdTahRPbExdk49pFKK9466nm2kP8TeGNDe4llYdX80mqQNvDkDXD7YYdf66vrqTK/X+RJ4WqqkhMtf59HycT89HSZkSMx9oKXc4RBZj8p9+5eXlePfdd9GnTx/Ex8cjKysLWVlZiI+PVyU0AODt7e00zU+VWY0CCnSJroPxfRqZvTRCYx0PeEPaRdY2qlzvJnfnBWpdT3OG5f892dGsa9fUY50tsyaXQgEsfz5WY9sDbcPhpvbeGLP6d5foQAxsGYpJ/RsbLEtkyyoXubSRMRZEkjM5qXFzc8PcuXNRXs5qzKrk6ChcmQRF1fHBv//trbX/ifrkgM3C7iZNxjzQrUHXcgmm/jy1Fa96boVCgeHt66F5mJ+qmejwjDjsmdZf53mHta+Hb5/pjFqeZlVsEtmMC+n5codAZFFmfUoPGDAAO3bsQHR0tMTh2CcpZxQ29jm+7uVeuHarEK3VOgE3DfWT8Ap3ff5Ee43vza1NMlVxmdKk8treBW1/kXp7uGLDK71V31edlKyqER0jAVRPsgJ93HGrsAx9mgYjOfPuvCH9moVg3kbnGvlH9iH/Tp8aTk9AjsqspGbIkCGYNm0aTpw4gU6dOsHXV7NT7IMPPihJcPaivOL2k/P6LevN/dAywh8tIyyzQGdVnRporrk0omOkXVRfa/vcNmduI28P7X1kBrYMw0sDGiM8wBsD5m9XbbfY+8IHEUlg57kMw4WI7JRZSc2LL74IAPjkk0+q7VMoFKiocK7VYZfvvwIAyCzQN4TSOF0a1sF5tSpid1cFyirMyyCevqcBftp3GVMHNsOYJQcBaP6FZuwzsrLz7W/ju2HbmXQ82zMax66at1yAv1fNmnDmP9oOU347prdMt5i6iL+UiZFd61t0GLSLCxAZ6GPWsVPubYr5m84ZLqgmJsgXZ1LzzLoeUaUjV26hmVG1ukT2x6wxokqlUufL2RIaAIi/mCnZuV6q0hm1ogaLOL07rBWOzRqIvhrDnO8y9syVeUGX6Dp4fXBz1UKU+vjd6X/y37imGtvdXGs2LHlEp0jMGNoCvZpUX6+mMs7vx3TGz8/H4qX+jeFrwX4wmmt9mZY9vTSgSY2uR2QpKTlFWL7/MorLnO+znOxfjSe+KC7mDK2mCDEw50rVhOG7Z/RPJqePQqFAgLe75jYDxzx1T30AwIPt7g5JN/QsfbRTZLVtB2fE4chb96Kulll9a+r5XjH46bnYatsrkzQfDzd0bxykNYGSstVMvRaoQV3zamxMuZatLAtCjm3oF7vx5p+J7BdGdsmspKaiogLvvfce6tWrh1q1auHSpUsAgLfeegvff/+9pAE6mmXPx6Jvs2D8PalHtX0tw/01ko65j7TFgBahFotFW67y9gOtsOrF7nj7wVZq5fRnNR881KbaNi9312pzwtiCmuQFVUdSqc9NExMkbedpL3fNX82RXetLen5yXkLoT+6z7jSjs+8N2SOzkpoPPvgAS5cuxdy5c+HhcffB1bp1ayxatEiy4BxR01A/LB3bFW21zCtT20ezVqWbGRPZGWKoCcPN1QUd6wfCVaNppSbXM65cw6DqMzBbYgh1TUaqebq5Yv6j7VTf61vAc0z3aLOvU9Xw9hF4635OmEbWdZ7Dv8kOmZXU/Pjjj/j2228xatQouLrebS5p164dzpw5I1lw9qK0wrShx1XNGNoCdX098O6wVvBU+wu9apIjFZ87o3l6Nw3WWUb94S/VKCJ9lj8fW63/TdWmM3PUr9IsVNOwR6g1telL2NRrunQxthNzXMtQeFl5lmIpl7og28PeWeSozEpqrl+/jsaNq8+uqlQqUVbGlWFN9XyvGByaEYfGIX7w8XDD50+0x2ePt4efl/RJjQLAtql98fWojnjqngY6y2k8/A18AppSk/P+8NZat0fU9sbkONM7zxri7+WuMbGeFIlSJWNncdZFX36l3uRX+bUlu9Q0D9McDWPuqC6yfQpFlaVdDl2VLRYiqZmV1LRs2RK7du2qtv33339Hhw4dahyUM1JvFhrWvh6Gd6gn6fnjWoSiXm1v9GwShFB/L9zXJlznTL4ANGqMarLqtHozVuI7g3Bfm3Cjj5Vq/cZ6tb3xyWPt0K9ZMCb0bWTUMS3Cdc81s+m/vTH3kbYanamtQcpJHqvqWGUuInIer/1+XO4QiCRjVqeFmTNnYvTo0bh+/TqUSiVWrVqFs2fP4scff8SaNWukjpEk8N0znaAUupckqMrHww1fjOwApVJorTEy9vE6rH09LNmTjB6Ng0zuI2Oog7IpHu4YiYc7Vh+lpcvEfo0w6eejWvc1CfVDEyvO81GZF1qypkb93P/+t7fugmT3OIiOHJlZfwsPGzYM//zzDzZv3gxfX1/MnDkTp0+fxj///IN7771X6hhJAgqFwuiEptKD7SKMqjHSd1ZvD1ds/G9vo1cGVl+7ytQOyvo67pqirq+HRg2Tpeh7uFRdbBQAOkdbsjblbjCVy208GcsRV46KiQ05KrMr+Hv16oVNmzYhPT0dhYWF2L17NwYOHChlbGTDLPXID1abx8fUJOXhjtI02SkUQCMrrW9VKcTPE4vU5iRSnzTQ/c58O/+9t2m14yzpQy1D9cn+FZaW462/EuUOg8giajRmtrS0FOnp6VAqNUf/1K/Pv/AcnTX+0DMlpVkypgt8PKQZAq5QKNA01A9LxnRBqH/NVzJ/oksUVhys3hlzSOswrE9MRasIf6x9uVe1/RP6NsKJazno1+z2KDVLjoDiX+7O47tdSVq3bzqVBjdLritCZAVmPQXOnz+PZ599Fnv37tXYLoRwyrWfnJ2lpu835bSWWCm9X3Pty0uYqlujupgc1wQfbzyHP45cU23/6JG26NE4CENah2k97o3BzSW5PpEhOUVlGPfjIbnDIKoxs5KaMWPGwM3NDWvWrEF4eDjXpHFC1vjL3tr/r14b1AzzNp7FnBGmN7s80ikSi/ckoUP92lr3hwd4o+qqDf5e7jqH1Wu7c0v+NNpEBmitTSLnkF9SLncIRJIwK6lJSEjA4cOH0bw5/5Ik6R+2M4a2wOz1ZzDnYev26ZjYrzGe69nQrGaelhH+OPhmHAL1TJgYE2yZfjrLn4/FqEX7a3SOJ7rUh1Ip0LWh9LNYk+0bs/iA1u2Tfj6CER0jJau1JLI0s5Kali1b4ubNm1LHQgTg9mSEY7pHm7Sit1Q1RzXptxKsY7HSsDv9csb2iEZOURn6m/mA0HWLPRrfXbG8Rbg/TqfkmnxuVxcFnu4WbVZcUvt6VEe8uPyI3GE4FV1LIqw5noI1x1OQPGeolSMiMo9Zo58++ugjvP7669i+fTsyMzORm5ur8SKqKVMSGlv1w7Nd8db9LRF7Zw0vTzdXvDG4ObpE17HYNUd2jcLpdwdb7PzmUh+qb4gpEzSSdSiVAiO+2YsJyw7LHQqRXmbV1MTF3f6A6t+/v0a/B3YUdh5KtaoRFxsYMWGL3br6NA1GHz3ra1lCg7q+8PZwxedPtMfkFQlWvXbbyAAcv5ajdZ+vp3E1YCteuEfKkEgip1NzcfjyLbnDIDLIrKRm27ZtUsdBRmgaat25U/SpUMo/BjiuRSg2n06TOwyb8Nv4bjidkoveTW43RQ1rXw+ebi4Yv6x6M87DHethzbEU1K3lgZScYr3nnXJvU8zfdM6oGP6e1BPR09aaHrya6LrVV2sn+XHIP9kLs+r4+/TpAxcXF3z33XeYNm0aGjdujD59+uDKlSsaq3aTtKSah0UKtpDUfPJ4O9XXjvaha+rIry7RdfBMt+gqNafay37yWHucfHeQUXPwdG0oTVOZhwM0JxKR7TPrk+aPP/7AoEGD4O3tjaNHj6KkpAQAkJOTgw8//FDSAOkuTzfbeTDYQlLjb4FVzG2F0JKRuEu1widuz1JsrSa7YD9Ph+gjRUS2z6xPmvfffx8LFizAd999B3f3uw+WHj164MgRjlqwlIVPd5I7BJVyG0hqnI23hyvmjmiLDx5qLcn5rFW71TDI+CYlHyP73pB1vfPPSblDIDKKWe0ZZ8+eRe/e1VfyDQgIQHZ2dk1joiqS5wxVdcK2FUoba++xsXBqTNd7/ViXKABAcZkS7605hdcGNdN5Dil+JM3Dqy+sqU0XPYttmrI6uyPXvtmzg8nsJEz2wayamrCwMFy4cKHa9t27dyMmJqbGQVF1tpTQAJBkTSQy33M9G+LQjDhM7NfY7HMY818qwNsdR9+612C53k10j/Ly87KdvmBE5NjMSmrGjRuHyZMnY//+/VAoFLhx4waWL1+OqVOnYsKECVLHaPMCvJ3vr8tODQLx9gMtsXRsF7lDcVpBtbRP9mescb1u/wES10L/ZICBvh41uo6+eXn8mfAQkYTM+kSZNm0alEolBgwYgMLCQvTu3Ruenp6YOnUqXnrpJaljtHnjejXEx/+eQ1cLTqpmi8b0aCh3CA7LGvVy97UJx67X+yGitrfBsh5uLigtV+rcr6+pa2TX+jr3NQvzQ8/Gwfh0s+aw8cVjOuPZpVxgkYhMY1ZNjUKhwJtvvomsrCwkJiZi3759yMjIwHvvvSd1fHbB9c6olPp1fWSOxHnVCzT8YLYn1uoiFFXHB65GTJ645dU+Gt8vGdsFP4+LNeoahs6vbYV1dz2jpeY/2k7nPiJybjUaZ+nh4YGWLVuia9euqFXLdiaGs7bKD2Xb6vXiHH594R589nh7tDCyQyuZJ6qOj0aNS79mIeje6O6aU7r+79dTqwX6v/uqL4DbKiLA5E7eIzpFYvcb/TC4VZhpB5Jk8orLsHRPEtJy9U/eSGRtbNCWQOWHso315XUKlesqORqp/yuF+nsiLbcEDWpQm6ht7hzVPi3btk3ti4jadzuUv9C7EUbFNoCnmwvOp+djfWIq/tM7Bt/uvGRyLJGBPljwdKcaz2BMphNC4Mnv9uPE9Rws3pOMna/3kzskIhUmNRJSsK6GbIh6DrLihW74dudFjO/TyOzzRZsw3wxwO5HydNOcd8b3zvDuFuH+rF2zU8v3X8GJ67fX+LqSVShzNESamNRIQHlnIjrW1JCtahjki9kPt63ROcb2iMatwlL0b6Z/tFSlqgmNLlL2H/LzckNecbmEZ6SqZqxO1Pje1ubQIufGucslULng34qDV2WOhByFLT4jPN1cMX1IC40mv8c6R8LP003rCCdjOiAbo2fjIHz3TGejyi58ynZm3XYWey9myh0CkQqTGic3tG243CGQFlLMkKxtVJHU5j7SDkdn3otgvxrMmWPgZu+JqYNAH+ebC8peVNaMlVUo8eR3+zBn/RmZIyJnxqTGydWyoZW/yT7VdLFKbSlNgzrG9d9ZwskfZTdv4xmsPHQVW06nY+/FTCzYcVHukMiJMalxcm6uNtjOQTbZ/GRNxs751K9K/x4HWwLMLlzMKMDrvx9HcVmF3KEQMalxdpPjmqBhkC+mD6k+hwjZN3tZ5LPXnXWj9CVy+m5lGv/v2oTtZ9PlDoGIo5+cXYifF7ZN7St3GOTEujasgz9f7I6oOtprZxrU1d8U5VolG2ocUgsX0vMli4+Mszrhhs59xWUVmL3uNAa2CkOPxkE6yxHVFGtqiEhysx5oaVL5DvUDqy3Q+esL92DakOYY2sb4zuwuCgVWT+yBVS92V9tmUih6tY0MwO43ONmcqRbsuIgf4i9j1KL9codCDs7ukpqSkhK0b98eCoUCCQkJcodDZLOah/nJdm0phnPHxtTF+D6N4GLgXOojr7o2rINanm7oWD+wxtfXJTKQa7yZipP0kbXYXfPT66+/joiICBw7dkzuUIhsWpNQP/w8Lhah/l6GC9uxB9pFIOFqNro2rKM1mVIoFNU6GL0S1wSfbT5v8rWcvP82kc2zq6Rm/fr1+Pfff/HHH39g/fr1BsuXlJSgpKRE9X1ubq4lwyOSkDSPT/VFJ63Jmp2UXV0UePvBViYdo28VcL2cfVgakY2zm+antLQ0jBs3Dj/99BN8fIyr/p09ezYCAgJUr6ioKAtHSUS25vleDfXu71i/tnUCISKLs4ukRgiBMWPGYPz48ejc2bjp0gFg+vTpyMnJUb2uXuUyBkTWYEsVGsPa1cPw9hGSnMuGbouItJA1qZk2bRoUCoXe15kzZ/Dll18iLy8P06dPN+n8np6e8Pf313gR2bLR3RoAuN3ng6Th4aYwOCzcVHV8PSQ9HxFJQ9Y+NVOmTMGYMWP0lomJicHWrVsRHx8PT0/NIZ+dO3fGqFGj8MMPP1gwSiLreWdYa0y/rwW83I1b4Zp0+0+fGGTll6JRcK1q+xQKoF5tb1zPLsLg1mE4ciVb53mejK2Pn/dfUR0H3K49JiLbI2tSExwcjODgYIPlvvjiC7z//vuq72/cuIFBgwbh119/RWxsrCVDJLI6R0hobOGZP31IC9XX2sL556WeOHz5Fvo1C8aH63Qvwvhcz4bwcXfFot1JeH0QZy82h4INd2QldjH6qX79+hrf16p1+y+vRo0aITIyUo6QiEiLJ2PrY8fZDDzcsZ6k57VEklTH1wP3tgw1quyM+1vi1YFN4cMFYM2ivmJ8bnEZ/L246jpZhl10FCYi+/DhQ22w+41+8LOzh5a+js3hAbfn+VFPaGygIsqmJd8s0Lmv7dv/orxCacVoyJnYZVITHR0NIQTat28vdyhEVIXCloY+Ganq+lGVDvzfAK21M7bQvGbL+n68XfV1hVKgrELzB1bIFb3JQuwyqSEiMoWbgaUWPN20fxSGmDkbc08u2oh9lzIBAHGf7MA/x3QvdkkkJSY1ROTwRneLRkyw7mHdpla8GBr99N0zndG9UV0Tz+pYnvh2HwAgSU9TFJHUmNQQkcML8HHH1il9jSr7bA/9MxADhpMgO2yBsyohgCNXbiGnsEzuUMjBsCs/Edk8S88Lo56DGLXAOPvUGCU1p1jr9u1n0zF5RQIAILquD5aPuwf1antbMTJyVKypISKSGDsS35aRV6J1+78n01RfJ2cWYva609YKiRwckxoicjqcDM46jG2GK+MQb5IIkxoisnm2NkycfWqM8+6aU1q3rz2RYuVIyFkwqSEiMpExfXz6Nw8BAPh62P+yF+Y6kJRlVDk215FU2FGYiGye1B2F69bSXGXb1JogY6IZ0z0a4QHe6NigNrrN3mrS+Z1NNkdBkUSY1BCR0/hiZAfsu5SJhzvoXptKqqYjN1cXDG0bDqWS1RCGHEg2rkaHyBAmNUTkNB5sF4EH20XoLWNMpZB6GW93VxRVmfZffQZj9q8hsh72qSEiMlHn6EAAgL+X5t+Fm1/tg+1T+8LN1fiPVkNJljP5KT4Zgz7dibRc7fPbEBnCpIaInJ56ZYoxNSufPt4eE/o2wt+TempsbxxSC9FBmssxKBQKfP5Ee53n+mJkBxMidWxv/XUSZ9Py8NGGM3KHQnaKSQ0RkYmCannijcHNER3ki04NtNfaqBvWXncfHqqupJzz1pB52KeGiGyeNbvamjoS6tPH22PR7kt4okt9C0XkHJ5ZfODuN+xbTWZiUkNEpMbU4ePBfp6YPqSF5HE0C/VDdlEp0nK1LzXgaHaey5A7BHIAbH4iIqfX785EeQ3q+sgcyV0b/9sbMUG15A5DFoJVNWQmJjVE5PQ+eKg13n6gJVb+p5vFl2T4cmQHDG0TbtFr2Lt1J1IRPW0trmQWyh0K2Rk2PxGR0/PzcseYHg0teo1jswYit6gMUXV8sP2scU0tzj7HTe9525A8Z6jcYZAdYVIjAX8vN+QWl2N4e843QWQJ7q7We7o3C/WzyHkDvN0R4O1ukXMT0W1MaiTQvVEQNpxMRafoOnKHQuSQOkQFol+zYDSo62u4cA091KEesovK0OXOBHuW4Ow1MESWwqSGiGyei4sCS8Z2tdq1nutp2aaoXk2C8Pvha3AxkNwE+nroL+BEsgpK8fP+y3i4YyQianvLHQ7ZKCY1EuIfX0RkjAfbRaCWpxtaRQToLTfz/pbILizFnguZVorMdr3yawJ2nsvAykPXsPP1fnKHQzaKo58kwOGHRGQKhUKBAS1CERbgpbdcqL8Xlj9/j5Wism27zt/uXH0l6+6IqMz8EpRVcPZhuotJDRER2Z3kmwXo9P5mDPl8l9yhkA1hUiMhdv4jIrKMqhM9r09MBQBcSM+XIRqyVUxqJGDirOpERGSk73ZekjsEsiNMaoiIyGZ9sO40Eq/nSHa+w5dvYdhXe3Dkyi3Jzkm2g0mNhBQc/0REJLn7v9xdbZt6c/+eCzeNPteIb/bi2NVsPPLNXilCIxvDpEYCbH0iIpLPqEX7sdeExAYAlPzgdkhMaoiIyK6cTc2rVi9+IDlLlljItjCpISIiu1JYWl5tG5v/CeCMwpLikG4iqqk6vh64r02Y3GHYHX7+EsCkRhIc0k1EUjn0ZhxcDC0KRdXwJ0YAm5+IiGQXVOv2wpUhfp5mJTSDWoUitmEdqcOyWQpWy5AOTGokxF8zIjLHihfuwbD2Efh5nHnrPPVuGuxUzS8FJVr61FS5/7IKJQSr0Z0OkxpJ8BeHiMzXOMQPnz/RAY1Damndv3RsF/h5uWHBUx2tHJltGrVof7WFLNVrb/KKy9Dh3U0YveSgtUMjmbFPDRGRjevbLATHZg7U2TTl6eZq5Yjk9/G/53Tu23I6Hfkl5dh5LsOKEZEtYE2NhJyp+peIrEtbQvPaoGbo1SQID7aLkCEiItvDpEYCbLYlIjlM7NcYPz0XCw83F415WhY901n19QNOkvDo+qPy2NVsnE/Ls24wJBsmNUREdqR302AAQJ87/2oT1zLUWuHYDF2T7w37ag/u/XSnlaMhubBPjYQ4oyURWdqXIzvg35OpGNSaE/SpExB4888TaBJSC4G+HnKHQzJhUkNEZEcCvN3xaOcoucOwOfsvZWHHnY7Bnz/Rvtr+DYmpCA/wsnJUZG1sfpIAu9QQkS17Mra+3CFYXF5xmd7945cdxraz6VaKhuTCpIaIyMG9P6w1tk7pgwZ1feQOhciimNRIiV1qiMgGubgoEBOsfWI/R3HkSrbq66yCUvkCIVnZVVKzdu1axMbGwtvbG4GBgRg+fLjcIQEAp+ImIrugdJLPqvfXnpY7BJKJ3SQ1f/zxB55++mmMHTsWx44dw549e/Dkk0/KHRYRkU0wZvJP9ZymQV0fvHV/S8sFJKMKpXMkb1SdXYx+Ki8vx+TJkzFv3jw899xzqu0tW9rWLyRbn4jI1ri73v1kUk9qdrzWD8euZls/ICILsouamiNHjuD69etwcXFBhw4dEB4ejiFDhiAxMVHvcSUlJcjNzdV4ERE5g1kPtESjYF+8Pqi5alvVpvI29QI4zJkcil0kNZcuXQIAvP3225gxYwbWrFmDwMBA9O3bF1lZWTqPmz17NgICAlSvqCjLzO3Aik4isjVjezTElil9EaaWtFT9rHJxUeCXcfdYNzAiC5I1qZk2bRoUCoXe15kzZ6BU3l5i/s0338SIESPQqVMnLFmyBAqFAr/99pvO80+fPh05OTmq19WrVy16PwquaElEMjHm48fYjsLbp/bFz8/H1jAiIuuTtU/NlClTMGbMGL1lYmJikJKSAkCzD42npydiYmJw5coVncd6enrC09NTkliJiOydsf1no4N8kV9SbtlgbMiGxBRsSEzF7IfbwtvDVe5wqAZkTWqCg4MRHKx7UbZKnTp1gqenJ86ePYuePXsCAMrKypCcnIwGDRpYOkyDnGSUJBHZOW2fVfz4AsYvOwIAiAmuhZcHNJE5GqoJuxj95O/vj/Hjx2PWrFmIiopCgwYNMG/ePADAo48+KnN0d7HxiYhsmbPPqbUhMVXv/oy8EitFQpZiF0kNAMybNw9ubm54+umnUVRUhNjYWGzduhWBgYFyh0ZEJDuFEX9WxQT7IrPKbLuBPu6WCsnmnEnNkzsEsjC7GP0EAO7u7vj444+RlpaG3NxcbNq0Ca1atZI7LACsviUi+/D5Ex0wrH0E/p7UQ7Wtto8Hfny2q+r7dlG1ZYiMSBp2U1NjDzj4iYhsWURtb3z+RIdq23s3Ndy3URdfD1cUlFbUJCwiydhNTQ0REVle5d9mdXw9DJYd2bU+Rt0j/2CNmtiQmKL6+uqtQhkjISkwqSEicgCT426P2hnZVZpJRm/X6rTHkjFdJDmfLTqYnKUa+QQAh5JvyRgNSYHNTxL48KHWKCytQKg/pxsnInl0ia6DxHcGwVfCeVaGta+nd7+nm4tdj/p8dEG8xvf2fC90G2tqJBAZ6IOmoX4I8HaeUQREZHtqebpZfGbzVhH+eGNwczQL9cOk/o1Ry5N/G5Pt4P9GIiIy2tqXewEAJvRtBAB4tmdD7EvKxJ4LmXKGRQSANTVERKTG1IoeX083LH/+7qKYLcL9JY7IivTce2pOMRbtuoTc4jLrxUMmY00NERGhYZAvkm4W4P62ETU6j13PWqwn9EcX7sXVrCIkXM3G/57saL2YyCRMaoiICKtf7IGEa9no2ThI7lBs0tWsIgDAjrMZMkdC+rD5iYiIEODjjj5Ng+HqUvOOxtOGNJcgIhlw+JPdY1JDRESSEQIY2DJU7jAsh4mPTWNSQ0REkhEQXA+PZMOkhoiIjBLXwnANjD33E1avhBFCoIhrWtkdJjVERKTXFyM7oEt0IP73ZPXFMKsSsO8WmiNXbuFGdhHG/XgYLWZuwDWuB2VXOPqJiIj0erBdBB5sZ/xQ76qVNaH+nkjLLZE2KAvILS7Hw1/v1di28tA1vHpvU5kiIlOxpoaIiCQTHuBga+AJgZWHrqq+tedaKGfApIaIiGrs53GxuLdlKD4a0dau+9VUJQC8988pucMgI7H5iYiIaqx7oyB0b3R74r4L6fkyRyMtpSNlaQ6ONTVEREQ6CAEUcBSU3WBSQ0REsqtfx0fuEIyiMHXFT7IqJjVERGRRY3s0NFjmKxtdJJJTCdoXJjVERCSxu4nA6ok98EKvGINHNA2rhe6N6loyKEnkFJVV21ahFNh9/iZyi6vvI+tiUkNERBbTLjIALkYskunp5opgP08rRGQaY/oIL9mThKe+349Hv4m3fECkF5MaIiKyuKkDmyKolgcGtwrTWea+NuFWjMg4GXn6Jw2sUAqsTrgOADiblmeNkEgPDukmIiJJNQyqhaahtRDg7a7aNql/E0zs1xiz15/ReZwtru792+FrOvf1n78dlzIK4GZETRRZB5MaIiKSlKuLAhsm94ZCoTlayNDIIXsbWXQpowAAUK5kZ2JbwaSGiIgkZ0w/mkpxLUIsGIllCE7IZ5PYp4aIiGQV18L2mp30efvvk7icydW7bRFraoiISFb2VuexdG8y3F2110QJIeyuGc2RsKaGiIjIRDdyirVu33gyDZczC1BcVoHLmQVWjopYU0NERGQiXXUxb/2VqDEM/PMn2mNY+3rWCYpYU0NERNYTFehdbZs99rl10dHEVHVem+93J1kjHLqDNTVERGQ1T3Stj2vZRejVOBhPfb9f7nDMxm4ztolJDRERWY27qwumD2mhsc0eF43MLy6XOwTSgs1PRERkM7pG15E7BKNsOZNuVLnj13KQx4UurYZJDRERyap9VG3V1/ZYa2PIf389JncIToPNT0REJIs90/rjRnYRWkUEaN3fNboODiRnWTkq6W0+nYb03GKE+HvJHYrDY00NERHJol5tb3TR09w0/7F26NUkyO5mHNam64db5A7BKTCpISIimxRVxwc/PReLXk2C5A7FYnIKyzB3wxmcT8uTOxSHwOYnIiKyGV7urtW2OcrikZN+PoKGQb6YMrAZDl/Owve7k5CRV4KDybfw9faLSJ4zVO4Q7R5raoiIyGa8N6w1YoJ9MXdEW9U2fSnNomc6Wz4oiaw5noIvt14AAIz4Jh7rTqTiYPItrWWVSuEwyZw1saaGiIhsRnSQL7ZO6auxTdezvX/zEHRrVNfyQUnMULJSoRSI+2QHgmp54Lfx3a0UlWNgUkNERDatd9NgAICfpxvySu5Oemevk/qWlCv17l915BqSbhYg6SYXxDQVm5+IiMimNQ6phV2v90P8/w1AeMDdYdH2ulTBxpOpevd/sO606ms2QZmGSQ0REdm8qDo+qOXphp2v99PYbo+P/MkrEvTuV89jmNOYhkkNERHZDXfXu48thb1W1egwZ/0ZrDx0VWNbSm4xRi8+gG1n7y7LkHyzADvOZVg7PLtgN0nNuXPnMGzYMAQFBcHf3x89e/bEtm3b5A6LiIhk4lgpDbBgx0W8/vtx5BTdXStqwrLD2HEuA2OXHFRt6/vxdoxefACHL9/C4cu3sJMJjordJDX3338/ysvLsXXrVhw+fBjt2rXD/fffj9RU/W2TRERE9ur4tRzV1zP/SsQ2tYU0T1zLxohv9uKZxQeQllssR3g2xy6Smps3b+L8+fOYNm0a2rZtiyZNmmDOnDkoLCxEYmKi3OEREZEMFArAw9UuHmOS+DH+MsYuvVtjo97dJj23xPoB2SC7+N9Qt25dNGvWDD/++CMKCgpQXl6OhQsXIiQkBJ06ddJ5XElJCXJzczVeRERk3yq70vRoHAQPNxf8PamHvAHZAAfrXmQ2u5inRqFQYPPmzRg+fDj8/Pzg4uKCkJAQbNiwAYGBgTqPmz17Nt555x0rRkpERJa2+43+OJSchfvbRgAA2kbWRkyQLy452bwuxo6MqlAKuLrczXp+2ncZMUG+6NHY8dbUkrWmZtq0aVAoFHpfZ86cgRACEydOREhICHbt2oUDBw5g+PDheOCBB5CSkqLz/NOnT0dOTo7qdfXqVZ1liYjIPtSr7Y1h7etpPKhN4eXugveGtZI4Kuu7VViqd39xWQW+2nYBrWdtxOmU2y0Vh5Kz8NbqRIxatN8aIVqdQsg4s09GRgYyMzP1lomJicGuXbswcOBA3Lp1C/7+/qp9TZo0wXPPPYdp06YZdb3c3FwEBAQgJydH4zxERGTf+n+83eiamn3TB2DjyVTM+vukhaOynjB/LzQM8kW3RnXxyaZziKrjjatZRar93WLq4pcX7sH3u5Pw3ppTAGBXC2ga+/yWtfkpODgYwcHBBssVFhYCAFxcNCuWXFxcoFTqn26aiIgc37jeMZi+6gTubRmKTafS9JYNC/CC0sFmtUvNLUZqbjHiL92uKFBPaIDbfW6KyypUCY2jsos+Nd26dUNgYCBGjx6NmTNnwtvbG9999x2SkpIwdKj9ZJpERGQZT3SJQpfoQETX9cWuCzfx78lU/HJAd5cDB8tpDHJRKHAhPV9j21OL9qN5mB+GtAnH9ewiPNguwqhznUnNxdI9yXh5QBNE1PYGACzadQl7L2ZiwVOd4OEmX88Wu0hqgoKCsGHDBrz55pvo378/ysrK0KpVK/z1119o166d3OEREZHMFAoFGof4AQD6NQtBv2YhepMaR6upMWTvxZs4cuWWxrbdF25i94WbWLQ7CQAQE+SLVhH+BmdqfuDL3SirEDibloc/X7w98uz9tbfXq1p99Doe6xJlgTswjl0kNQDQuXNnbNy4Ue4wiIjITix8uhO+35WEA8lZqm317tQsxDasK1dYslAKYOZf+vsQvf33SSTeyMGvL3RD83A/rDx4FT2bBMNVoUD9uj4AgO1n01FWcTshPHmj+jQpBaXl1bZZk90kNURERKYY1CoMg1qFIXraWtW2FuG3O5m2iQzA4jGd8ezSQ6p9ie8Mwu7zGRi/7IjVY7UFhy7frskZ9tUerfuTZt+HMWrLNZSWK1FWodRYj0vuCjAmNURE5NB+H98NPx+4Aj9PN7w8oIlqe//moRrlanm6YXDrcDQP88OZ1Dxrh2nznll8oNq2Jm+u1/i+tELewTt2MaMwERGRuTpH18Enj7XHO8Nao24tT4PlX+rfxGAZZ7Tr/E2DZeasP2OFSHRjUkNERKTGx8NV7hDsWraBSQEtiUkNERE5rVD/6jU3As41MkpqP8Vflu3a7FNDREROa+uUvvhm+0UMaROm2ubtzkdjTaTlFct2bb5zRETktHw93TB1UDONbffE1MGIjpFQCoFxvWLg5e6CrIJSnLyRi70XbyLYzxOnU/IwdWAzjF58QNU51tPNBTte64fNp9OweHcSBrcOw9fbL2qcu15tb7QI98Pm0+lWu0dre21Qc9muLevaT9bGtZ+IiIjsj7HPb/apISIiIofApIaIiIgcApMaIiIicghMaoiIiMghMKkhIiIih8CkhoiIiBwCkxoiIiJyCExqiIiIyCEwqSEiIiKHwKSGiIiIHAKTGiIiInIITGqIiIjIITCpISIiIofApIaIiIgcgpvcAViTEALA7SXMiYiIyD5UPrcrn+O6OFVSk5eXBwCIioqSORIiIiIyVV5eHgICAnTuVwhDaY8DUSqVuHHjBvz8/KBQKCQ7b25uLqKionD16lX4+/tLdl5b4uj3yPuzf45+j45+f4Dj3yPvz3xCCOTl5SEiIgIuLrp7zjhVTY2LiwsiIyMtdn5/f3+H/I+qztHvkfdn/xz9Hh39/gDHv0fen3n01dBUYkdhIiIicghMaoiIiMghMKmRgKenJ2bNmgVPT0+5Q7EYR79H3p/9c/R7dPT7Axz/Hnl/ludUHYWJiIjIcbGmhoiIiBwCkxoiIiJyCExqiIiIyCEwqSEiIiKHwKRGAl999RWio6Ph5eWF2NhYHDhwQO6Qqpk9eza6dOkCPz8/hISEYPjw4Th79qxGmb59+0KhUGi8xo8fr1HmypUrGDp0KHx8fBASEoLXXnsN5eXlGmW2b9+Ojh07wtPTE40bN8bSpUstfXsAgLfffrta/M2bN1ftLy4uxsSJE1G3bl3UqlULI0aMQFpamsY5bPn+oqOjq92fQqHAxIkTAdjf+7dz50488MADiIiIgEKhwOrVqzX2CyEwc+ZMhIeHw9vbG3FxcTh//rxGmaysLIwaNQr+/v6oXbs2nnvuOeTn52uUOX78OHr16gUvLy9ERUVh7ty51WL57bff0Lx5c3h5eaFNmzZYt26dxe+xrKwMb7zxBtq0aQNfX19ERETgmWeewY0bNzTOoe19nzNnjk3co6H3cMyYMdViHzx4sEYZe34PAWj9nVQoFJg3b56qjK2+h8Y8F6z5uSnJs1RQjaxYsUJ4eHiIxYsXi5MnT4px48aJ2rVri7S0NLlD0zBo0CCxZMkSkZiYKBISEsR9990n6tevL/Lz81Vl+vTpI8aNGydSUlJUr5ycHNX+8vJy0bp1axEXFyeOHj0q1q1bJ4KCgsT06dNVZS5duiR8fHzEq6++Kk6dOiW+/PJL4erqKjZs2GDxe5w1a5Zo1aqVRvwZGRmq/ePHjxdRUVFiy5Yt4tChQ+Kee+4R3bt3t5v7S09P17i3TZs2CQBi27ZtQgj7e//WrVsn3nzzTbFq1SoBQPz5558a++fMmSMCAgLE6tWrxbFjx8SDDz4oGjZsKIqKilRlBg8eLNq1ayf27dsndu3aJRo3bixGjhyp2p+TkyNCQ0PFqFGjRGJiovjll1+Et7e3WLhwoarMnj17hKurq5g7d644deqUmDFjhnB3dxcnTpyw6D1mZ2eLuLg48euvv4ozZ86I+Ph40bVrV9GpUyeNczRo0EC8++67Gu+r+u+tnPdo6D0cPXq0GDx4sEbsWVlZGmXs+T0UQmjcW0pKili8eLFQKBTi4sWLqjK2+h4a81yw1uemVM9SJjU11LVrVzFx4kTV9xUVFSIiIkLMnj1bxqgMS09PFwDEjh07VNv69OkjJk+erPOYdevWCRcXF5Gamqra9s033wh/f39RUlIihBDi9ddfF61atdI47vHHHxeDBg2S9ga0mDVrlmjXrp3WfdnZ2cLd3V389ttvqm2nT58WAER8fLwQwvbvr6rJkyeLRo0aCaVSKYSw7/ev6sNCqVSKsLAwMW/ePNW27Oxs4enpKX755RchhBCnTp0SAMTBgwdVZdavXy8UCoW4fv26EEKIr7/+WgQGBqruTwgh3njjDdGsWTPV94899pgYOnSoRjyxsbHiP//5j0XvUZsDBw4IAOLy5cuqbQ0aNBCffvqpzmNs5R51JTXDhg3TeYwjvofDhg0T/fv319hmL+9h1eeCNT83pXqWsvmpBkpLS3H48GHExcWptrm4uCAuLg7x8fEyRmZYTk4OAKBOnToa25cvX46goCC0bt0a06dPR2FhoWpffHw82rRpg9DQUNW2QYMGITc3FydPnlSVUf95VJax1s/j/PnziIiIQExMDEaNGoUrV64AAA4fPoyysjKN2Jo3b4769eurYrOH+6tUWlqKZcuW4dlnn9VYnNXe379KSUlJSE1N1YglICAAsbGxGu9X7dq10blzZ1WZuLg4uLi4YP/+/aoyvXv3hoeHh6rMoEGDcPbsWdy6dUtVxhbuGbj9e6lQKFC7dm2N7XPmzEHdunXRoUMHzJs3T6Nq39bvcfv27QgJCUGzZs0wYcIEZGZmasTuSO9hWloa1q5di+eee67aPnt4D6s+F6z1uSnls9SpFrSU2s2bN1FRUaHxZgJAaGgozpw5I1NUhimVSrzyyivo0aMHWrdurdr+5JNPokGDBoiIiMDx48fxxhtv4OzZs1i1ahUAIDU1Veu9Vu7TVyY3NxdFRUXw9va22H3FxsZi6dKlaNasGVJSUvDOO++gV69eSExMRGpqKjw8PKo9LEJDQw3GXrlPXxlr3J+61atXIzs7G2PGjFFts/f3T11lPNpiUY81JCREY7+bmxvq1KmjUaZhw4bVzlG5LzAwUOc9V57DWoqLi/HGG29g5MiRGosBvvzyy+jYsSPq1KmDvXv3Yvr06UhJScEnn3yiug9bvcfBgwfj4YcfRsOGDXHx4kX83//9H4YMGYL4+Hi4uro63Hv4ww8/wM/PDw8//LDGdnt4D7U9F6z1uXnr1i3JnqVMapzQxIkTkZiYiN27d2tsf+GFF1Rft2nTBuHh4RgwYAAuXryIRo0aWTtMkw0ZMkT1ddu2bREbG4sGDRpg5cqVVnsYW8v333+PIUOGICIiQrXN3t8/Z1ZWVobHHnsMQgh88803GvteffVV1ddt27aFh4cH/vOf/2D27Nk2P93+E088ofq6TZs2aNu2LRo1aoTt27djwIABMkZmGYsXL8aoUaPg5eWlsd0e3kNdzwV7w+anGggKCoKrq2u1nuBpaWkICwuTKSr9Jk2ahDVr1mDbtm2IjIzUWzY2NhYAcOHCBQBAWFiY1nut3KevjL+/v9UTi9q1a6Np06a4cOECwsLCUFpaiuzs7GqxGYq9cp++Mta8v8uXL2Pz5s14/vnn9Zaz5/evMh59v1thYWFIT0/X2F9eXo6srCxJ3lNr/Q5XJjSXL1/Gpk2bNGpptImNjUV5eTmSk5MB2Mc9VoqJiUFQUJDG/0lHeA8BYNeuXTh79qzB30vA9t5DXc8Fa31uSvksZVJTAx4eHujUqRO2bNmi2qZUKrFlyxZ069ZNxsiqE0Jg0qRJ+PPPP7F169ZqVZ3aJCQkAADCw8MBAN26dcOJEyc0PoQqP4RbtmypKqP+86gsI8fPIz8/HxcvXkR4eDg6deoEd3d3jdjOnj2LK1euqGKzl/tbsmQJQkJCMHToUL3l7Pn9a9iwIcLCwjRiyc3Nxf79+zXer+zsbBw+fFhVZuvWrVAqlaqErlu3bti5cyfKyspUZTZt2oRmzZohMDBQVUaue65MaM6fP4/Nmzejbt26Bo9JSEiAi4uLqtnG1u9R3bVr15CZmanxf9Le38NK33//PTp16oR27doZLGsr76Gh54K1PjclfZaa1K2YqlmxYoXw9PQUS5cuFadOnRIvvPCCqF27tkZPcFswYcIEERAQILZv364xrLCwsFAIIcSFCxfEu+++Kw4dOiSSkpLEX3/9JWJiYkTv3r1V56gcujdw4ECRkJAgNmzYIIKDg7UO3XvttdfE6dOnxVdffWW1Ic9TpkwR27dvF0lJSWLPnj0iLi5OBAUFifT0dCHE7aGJ9evXF1u3bhWHDh0S3bp1E926dbOb+xPi9oiA+vXrizfeeENjuz2+f3l5eeLo0aPi6NGjAoD45JNPxNGjR1Ujf+bMmSNq164t/vrrL3H8+HExbNgwrUO6O3ToIPbv3y92794tmjRpojEcODs7W4SGhoqnn35aJCYmihUrVggfH59qQ2Xd3NzExx9/LE6fPi1mzZol2XBgffdYWloqHnzwQREZGSkSEhI0fi8rR43s3btXfPrppyIhIUFcvHhRLFu2TAQHB4tnnnnGJu5R3/3l5eWJqVOnivj4eJGUlCQ2b94sOnbsKJo0aSKKi4tV57Dn97BSTk6O8PHxEd9880214235PTT0XBDCep+bUj1LmdRI4MsvvxT169cXHh4eomvXrmLfvn1yh1QNAK2vJUuWCCGEuHLliujdu7eoU6eO8PT0FI0bNxavvfaaxjwnQgiRnJwshgwZIry9vUVQUJCYMmWKKCsr0yizbds20b59e+Hh4SFiYmJU17C0xx9/XISHhwsPDw9Rr1498fjjj4sLFy6o9hcVFYkXX3xRBAYGCh8fH/HQQw+JlJQUjXPY8v0JIcTGjRsFAHH27FmN7fb4/m3btk3r/8nRo0cLIW4P637rrbdEaGio8PT0FAMGDKh235mZmWLkyJGiVq1awt/fX4wdO1bk5eVplDl27Jjo2bOn8PT0FPXq1RNz5sypFsvKlStF06ZNhYeHh2jVqpVYu3atxe8xKSlJ5+9l5dxDhw8fFrGxsSIgIEB4eXmJFi1aiA8//FAjKZDzHvXdX2FhoRg4cKAIDg4W7u7uokGDBmLcuHHVHlL2/B5WWrhwofD29hbZ2dnVjrfl99DQc0EI635uSvEsVdy5MSIiIiK7xj41RERE5BCY1BAREZFDYFJDREREDoFJDRERETkEJjVERETkEJjUEBERkUNgUkNEREQOgUkNEREROQQmNUTk9BQKBVavXi13GERUQ0xqiJzAmDFjoFAoMH78+Gr7Jk6cCIVCgTFjxkh6zbfffhvt27eX7Hzbtm3Dfffdh7p168LHxwctW7bElClTcP36dcmuYQnJyclQKBSqBUaJyHKY1BA5iaioKKxYsQJFRUWqbcXFxfj5559Rv359GSMzbOHChYiLi0NYWBj++OMPnDp1CgsWLEBOTg7mz59v9nlLS0sljJKI5MakhshJdOzYEVFRUVi1apVq26pVq1C/fn106NBBo2xJSQlefvllhISEwMvLCz179sTBgwdV+7dv3w6FQoEtW7agc+fO8PHxQffu3XH27FkAwNKlS/HOO+/g2LFjUCgUUCgUWLp0KQAgOzsbzz//PIKDg+Hv74/+/fvj2LFjOuO+du0aXn75Zbz88stYvHgx+vbti+joaPTu3RuLFi3CzJkzAQCZmZkYOXIk6tWrBx8fH7Rp0wa//PKLxrn69u2LSZMm4ZVXXkFQUBAGDRqk9ZonTpxA//794e3tjbp16+KFF15Afn6+zhhv3bqFUaNGITg4GN7e3mjSpAmWLFkCAGjYsCEAoEOHDlAoFOjbt6/quEWLFqFFixbw8vJC8+bN8fXXX6v2VdbwrFixAt27d4eXlxdat26NHTt26IyDyNkxqSFyIs8++6zqYQsAixcvxtixY6uVe/311/HHH3/ghx9+wJEjR9C4cWMMGjQIWVlZGuXefPNNzJ8/H4cOHYKbmxueffZZAMDjjz+OKVOmoFWrVkhJSUFKSgoef/xxAMCjjz6K9PR0rF+/HocPH0bHjh0xYMCAaueu9Ntvv6G0tBSvv/661v21a9cGcLvWqVOnTli7di0SExPxwgsv4Omnn8aBAwc0yv/www/w8PDAnj17sGDBgmrnKygowKBBgxAYGIiDBw/it99+w+bNmzFp0iQdP1XgrbfewqlTp7B+/XqcPn0a33zzDYKCggBAdf3NmzcjJSVFlVQuX74cM2fOxAcffIDTp0/jww8/xFtvvYUffvhB49yvvfYapkyZgqNHj6Jbt2544IEHkJmZqTMWIqdm8rreRGR3Ro8eLYYNGybS09OFp6enSE5OFsnJycLLy0tkZGSIYcOGidGjRwshhMjPzxfu7u5i+fLlquNLS0tFRESEmDt3rhBCiG3btgkAYvPmzaoya9euFQBEUVGREEKIWbNmiXbt2mnEsWvXLuHv7y+Ki4s1tjdq1EgsXLhQa+wTJkwQ/v7+Zt330KFDxZQpU1Tf9+nTR3To0KFaOQDizz//FEII8e2334rAwECRn5+v2r927Vrh4uIiUlNTtV7ngQceEGPHjtW6LykpSQAQR48e1djeqFEj8fPPP2tse++990S3bt00jpszZ45qf1lZmYiMjBQfffSR7psmcmJusmZURGRVwcHBGDp0KJYuXQohBIYOHaqqUah08eJFlJWVoUePHqpt7u7u6Nq1K06fPq1Rtm3btqqvw8PDAQDp6ek6++gcO3YM+fn5qFu3rsb2oqIiXLx4UesxQggoFAqD91ZRUYEPP/wQK1euxPXr11FaWoqSkhL4+PholOvUqZPe85w+fRrt2rWDr6+valuPHj2gVCpx9uxZhIaGVjtmwoQJGDFiBI4cOYKBAwdi+PDh6N69u85rFBQU4OLFi3juuecwbtw41fby8nIEBARolO3WrZvqazc3N3Tu3Lna+0BEtzGpIXIyzz77rKop5auvvqrRudzd3VVfVyYeSqVSZ/n8/HyEh4dj+/bt1fZVNiNV1bRpU+Tk5CAlJUWVOGkzb948fP755/jss8/Qpk0b+Pr64pVXXqnWGVg9WZHKkCFDcPnyZaxbtw6bNm3CgAEDMHHiRHz88cday1f2z/nuu+8QGxursc/V1VXy+IicBfvUEDmZwYMHo7S0FGVlZVo7yjZq1EjV56RSWVkZDh48iJYtWxp9HQ8PD1RUVGhs69ixI1JTU+Hm5obGjRtrvKrWGFV65JFH4OHhgblz52rdn52dDQDYs2cPhg0bhqeeegrt2rVDTEwMzp07Z3S8lVq0aIFjx46hoKBAtW3Pnj1wcXFBs2bNdB4XHByM0aNHY9myZfjss8/w7bffArj9cwCg8bMIDQ1FREQELl26VO3nUNmxuNK+fftUX5eXl+Pw4cNo0aKFyfdF5AxYU0PkZFxdXVXNF9pqBXx9fTFhwgS89tprqFOnDurXr4+5c+eisLAQzz33nNHXiY6ORlJSEhISEhAZGQk/Pz/ExcWhW7duGD58OObOnYumTZvixo0bWLt2LR566CF07ty52nmioqLw6aefYtKkScjNzcUzzzyD6OhoXLt2DT/++CNq1aqF+fPno0mTJvj999+xd+9eBAYG4pNPPkFaWppJiRgAjBo1CrNmzcLo0aPx9ttvIyMjAy+99BKefvpprU1PADBz5kx06tQJrVq1QklJCdasWaNKPEJCQuDt7Y0NGzYgMjISXl5eCAgIwDvvvIOXX34ZAQEBGDx4MEpKSnDo0CHcunULr776qurcX331FZo0aYIWLVrg008/xa1bt1QdsolIE2tqiJyQv78//P39de6fM2cORowYgaeffhodO3bEhQsXsHHjRgQGBhp9jREjRmDw4MHo168fgoOD8csvv0ChUGDdunXo3bs3xo4di6ZNm+KJJ57A5cuXdSYMAPDiiy/i33//xfXr1/HQQw+hefPmeP755+Hv74+pU6cCAGbMmIGOHTti0KBB6Nu3L8LCwjB8+HCj463k4+ODjRs3IisrC126dMEjjzyCAQMG4H//+5/OYzw8PDB9+nS0bdsWvXv3hqurK1asWAHgdj+YL774AgsXLkRERASGDRsGAHj++eexaNEiLFmyBG3atEGfPn2wdOnSajU1c+bMwZw5c9CuXTvs3r0bf//9t85aLSJnpxBCCLmDICIiTcnJyWjYsCGOHj0q6czMRI6MNTVERETkEJjUEBERkUNg8xMRERE5BNbUEBERkUNgUkNEREQOgUkNEREROQQmNUREROQQmNQQERGRQ2BSQ0RERA6BSQ0RERE5BCY1RERE5BD+H+qb57a0GniZAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "import matplotlib.pyplot as plt\n",
    "plt.plot(range(len(energies)), energies)\n",
    "plt.xlabel('Monte Carlo step')\n",
    "plt.ylabel('energy')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The energy is gradually decreasing as the annealing proceeds.\n",
    "Thus, the callback is useful to know how the system looks like while the Algorithm is running."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Result\n",
    "\n",
    "With `result.get_solution` we get the spin configuration that is the result of the calculation.\n",
    "For the classical Ising model, we can also directly refer to `mysystem.spin` to get the spin configuration.\n",
    "However, `result.get_solution` is a convenient method to do so for other systems as well."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[-1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, 1]\n"
     ]
    }
   ],
   "source": [
    "import openjij.cxxjij.result as R\n",
    "print(R.get_solution(mysystem))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This spin configuration is the answer obtained by annealing.\n",
    "It is expected to be the ground state (close to the ground state) of the Hamiltonian."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.15"
  },
  "vscode": {
   "interpreter": {
    "hash": "2e8d7574d7ec71e14cb1575cf43673432d6fae464c836a7b3733d4f6c20243fb"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}