{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Complexity Analysis\n",
    "\n",
    "*Performance* refers to how fast our code run; we've been measuring it and thinking about it at an intuitive level.  *Complexity analysis* is a formal theory for thinking about some aspects of performance.\n",
    "\n",
    "Here are a few things that often affect performance:\n",
    "* speed of the computer (CPU, etc)\n",
    "* speed of Python interpreter (quality+efficiency of interpretation)\n",
    "* algorithm: strategy for solving the problem\n",
    "* input size: how much data do we have?\n",
    "\n",
    "Computers and the Python interpreters that run our programs may tend to get faster over time, and our code will run faster as a result.\n",
    "\n",
    "Complexity analysis is interested only in those last two parts and the relationship between them.  *How much work does a given algorithm need to do to complete a task, as a function of the input size?*\n",
    "\n",
    "An *algorithm* is a bit more general than code.  It's a description of the steps that must be performed to complete the task.  We might *implement\" an algorithm in different languages.  For example, here's an algorithm for finding the biggest number in a list:\n",
    "\n",
    "<pre>\n",
    "Take a list, and set x to be the first item in that list.\n",
    "Iterate over each item in the list, putting each value in y:\n",
    "    if y is bigger than x, then set x equal to y\n",
    "Output x, as the biggest number in the list\n",
    "</pre>\n",
    "\n",
    "We could convert that to Python code:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "9"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nums = [5,3,2,9,8]\n",
    "x = nums[0]\n",
    "for y in nums:\n",
    "    if y > x:\n",
    "        x = y\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The algorithm is more general than this specific Python code -- you could imagine implementing the same algorithm in the code of another programming language (C, Go, JavaScript, etc).\n",
    "\n",
    "Complexity analysis is interested in how much \"work\" needs to be done, as the \"input size\" increases.  We'll postpone talking about how to measure \"work\" in terms of \"steps.\"  Input size can be defined on a case-by-case basis.  Here, we could say the input size is $N$, where `N = len(nums)`.  We could also use other variable names (though N is most common), or multiple variables.  For other algorithms, there might be other ways to measure the input size that make more sense, like the size of a file, length of a string, or number of entries in a dictionary."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Big O\n",
    "\n",
    "Big-O notation is a mathematical way of communicating how quickly the outputs of a function grow as the inputs grow.  This will be useful because we will eventually have functions like $y = f(x)$, where $f$ is a function that tells us how much work our algorithm must do ($y$ will be the number of \"steps\" -- defined later; $x$ will be the size of the input, such as the length of a list).\n",
    "\n",
    "Big-O notation allows us to broadly categorize functions into sets, so we'll use set notation.  For example, $f(x) \\in O(N^2)$ means that the $f$ function is in the $O(N^2)$ set (to be defined soon).  Confusingly, other resources you might find use the notation $f(x) = O(N^2)$, replacing the $\\in$ with $=$.\n",
    "\n",
    "Big-O sets are fairly broad.  For example, all straight lines belong to the same set.  Lets see this intuitively before we give a definition:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "plt.rcParams[\"font.size\"] = 16\n",
    "\n",
    "# add functions to DataFrame\n",
    "df = pd.DataFrame({\"N\": range(1, 7)})\n",
    "df[\"A(N)=N\"] = df[\"N\"]\n",
    "df[\"B(N)=N+15\"] = df[\"N\"] + 15\n",
    "df[\"C(N)=3*N\"] = 3 * df[\"N\"]\n",
    "df[\"D(N)=5*N\"] = 5 * df[\"N\"]\n",
    "df[\"E(N)=N**2\"] = df[\"N\"] ** 2\n",
    "df.set_index(\"N\", inplace=True)\n",
    "\n",
    "# plot functions A to E\n",
    "ax = df.plot.line()\n",
    "ax.set_ylabel(\"y\")\n",
    "\n",
    "# clean up plot...\n",
    "for label, y in df.iloc[-1].items():\n",
    "    ax.text(6.1, y, label, va=\"center\")\n",
    "ax.spines[\"top\"].set_visible(False)\n",
    "ax.spines[\"right\"].set_visible(False)\n",
    "ax.get_legend().remove()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Even though function B and C are \"bigger\" than function A, Big O will categorize them as being in the same set of functions, as they are all the same shape (straight lines).  Big-O notation **does not care** about the following:\n",
    "\n",
    "* if you add a fixed amount to a function (for example, line B is just line A shifted up)\n",
    "* if you multiple a function by a constant (for example, line C is just line A multiplied by 3)\n",
    "\n",
    "To formalize this a bit, Big-O analysis says if we want to claim function $y=f(x)$ belongs to the same set as as $y=g(x)$, we can multiply the g function by some constant to create a new function, then show that $y=f(x)$ is beneath the new function.  For example, line D is line A multiplied by a constant (in this case 5, though we could have chosen any constant we liked).  E is above line C, therefore C is in the same complexity set as A.  We're also allowed to only look at large N values (above a threshold of our choosing), so B is also in the same complexity set as A because the B line is beneath the E line for all N values of 4 or greater.\n",
    "\n",
    "In contrast, E is not beneath line D.  Of course, we could have used a different constant multiple on the A line to produce the D line, such as $D(N) = 999999*N$.  However, it doesn't matter what constant we use.  We'll still end up with a straight line, and no matter how steep it is, the E line will eventually surpass it because E's line keeps getting steeper and steeper.  E is NOT in A's complexity class -- it's y values fundamentally grow faster as N increases.\n",
    "\n",
    "Let's write a more precise mathematical definition to capture this intuition:\n",
    "\n",
    "**Definition:** If $f(N) \\le C * g(N)$ for large N values and some fixed constant C, then $f(N) \\in O(g(N))$.\n",
    "\n",
    "How does categorizing functions into complexity classes/set relate to algorithm performance?  Let's look at the previous plot again, with some new labels:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAeIAAAEfCAYAAACd5cVkAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/MnkTPAAAACXBIWXMAAAsTAAALEwEAmpwYAABunElEQVR4nO3dd3iUZdb48e9J7yENQgKh944oJSqoiIoNVCy7ShFRcd13xd19Xbe6bpN1Xd1dd9/fakCiKIqKWFBELChNRXov0kPLpPdk5v798UzCMJkkE0gyKedzXbnCPM8zz5wJkDN3O7cYY1BKKaWUb/j5OgCllFKqLdNErJRSSvmQJmKllFLKhzQRK6WUUj6kiVgppZTyIU3ESimllA9pIlZKKaV8SBOxUkop5UMB3lwkIsnA1cAoIAkIBTKBPcAqYJUxxtFYQSqllFKtldRWWUtExgI/B64B/IFjwBmgGIgFUoAw4ATwIvB3Y0xeI8eslFJKtRo1JmIRWQZcAbwPvA58ZYzJdLvGDxgI3Aj8AGgP3G2M+bgxg1ZKKaVai9oS8bPAXGPMSa9vJnITEGKMWdxA8SmllFKtWq1d00oppZRqXDprWimllPKhGmdNi8hU18fGmJcbPxyllFKqbaltjNh1OZIxxvg3TUhKKaVU26FjxEoppZQP1dY1/VuXh8YY84cmiEcppZRqU2rrmj7o8tAYY7o3TUhKKaVU26Fd00oppZQPeVVruiW69tprzfLly30dhlJKtSTi6wDaIq/WEYvIGBG5weVxnIgsEpFtIvI3EWl2M6ozMzPrvkgppZTyMW8LejwFXOTy+GlgIrAXmA38soHjUkoppdoEbxNxP2ADgIgEArcBc4wxtwK/wtrwQSmlVAsxa9YsRIQ5c+Z4PC8iT4iITyYRicg4ETEiMs7l2CMicouHa59wXtvkQ60iMt352p6+cry9j7eJOAKo3N7wEiAc+MD5eCPWdohKKaVagOLiYhYvtvbmee2116ioqPBxRNVsBEY7v1d6BKiWiJuJKVjxun6N9/bJ3ibi48AQ55+vA7YbY047H8cARd6+oFJKKd9aunQpeXl5TJw4kdOnT9NcJraKiL+IBBhj8owx61vQ/vabnfG6fm3w9sneJuJFwJ9F5C3gUWChy7nhwD7v41VKKeVL6enpxMTEsGDBAkJDQ0lPT/fqeSKS4Jyomyci2SLykojc5KEbWURkjojsEZEyETkhIs+LSJTb/YyI/ElEfuGsXVEGDHLvmhaRQ0AX4IcuXb8L3MLrJiLLRKRARA6LyG9FxM/ltSrvOUlE/isiWSKSIyLPOT8AXCwiq0WkUER2iMg19f25ni9vE/ETwFwgGGvi1rMu54YAbzZsWEoppRpDRkYGK1eu5I477iAhIYFJkybx/vvvk52d7c3Tl2D1ij4O3AmUA//ycN2fgL8DnwA3An8FpgPLXJOj03TgeuBnzu8ZHu43GTgJfMzZrl/3ao/vAJ8Bk4ClwO+BaR7u9RxQCNzhjP0nzmMvA/Oxur+zgCUiEu/h+Z74i0iA25f3uxsaY1rl10UXXWSUUkqda+7cuQYwa9euNcYYs3z5cgOY//u//zPG5XcoVgPMuDyeABjgdrfr3nMeH+d8HAuUAgvcrrvbed1NLscMVuINdbt2nOs9nccOAQuN2+/6yjiBGW7HtwErPNxzvtt1G53HL3U5Nth5bJr767k9d7rzOk9fH9T2XNeveu1HLCI9ReQHIvJz5/ce9Xm+UkqpxnPy+1w2fXKk1mvS09Pp1asXo0ePBmD8+PEkJSV50z09CrBjtTxdveXhuiDOHcIEeB2oAMa6HV9ujCmu68W9sMzt8XY8TyT+yO3xbqDQGLPa7RhAZy9fezJwsdvXI14+17vKWiISAvwHuAdwLd5hF5F04EfGmFJvX1QppVTDOnUwj/f/uZnQyCAGXJZEUEj1X+8bNmxg586dPPbYY+Tk5FQdv+WWW3j++ecRkd7GmL01vERHINsYU+7+0m6PY53fT7geNMZUiIjN5TyerrsAWW6PS4EQD9e598GXATmuB4wxZSJCDc/3ZLsxZr+X11bjbYv4b8APgd8BPYFI5/cnsJLz0+cbgFJKqQtz5kg+7/9rMyERgdw8Z5jHJAxUtXrnzp1LTExM1dfzzz9fecnUWl7mBBDjrCXhqoPb48qEmOh60LnON47qCbPNb3jg7QLoO4HfG2P+7HLse+BPzk8Nc4D/aeDYlFJK1SHzWD7vPreJwBB/bn5kGJGxnhtxZWVlLFq0iJEjR/LUU09VOz9nzhw2b958j4j8xhiPuwGtx+oRnQwsdjk+xcN1ZVh541OX43dg5ZwvvHxr7kqB0PN8brPmbSIOBr6p4dzXWOMBSimlmpDteAHvPreZwGB/Js0ZTlR8zXlq2bJl2Gw2nnnmGcaNG1ft/AMPPMDs2bNTsCY1fe5+3hizQkTWAC84ZxPvx6qyWFljwuG8LktEngEeF5FC4EOs6ox/BFZTfSzXWzuBy5z7HpwEMo0xh87zXg1taA0zrDcYY+qsluJt1/RKrBlznkzAmjKulFKqiWSdKOTd5zbh5y/c/MgwohNqbyymp6cTGRnJlCnuDVjLXXfdBVCM5yU/lSYDy7GWsy7GGkP9jfNcrst1v8KqOXEdVhXGX2AtD7reGOOo463V5HFgj/N1v8UaGm0u3gTWefhq582TvdqPWEQuA17B+iTzJtbgfAfgdqzNH+7GZe2XMeb7eryBRjFixAizYYPXhU2UUqrFyDlVxDvPbMQAkx8dRkxieEPdut7bIIrI88AMIFYn7Z4fb7umVzm/zwYedDkubucrNbttEZVSqjXIPVPE0mc3YYxh0pzhDZmE6yQi04FoYAfWkOS1WHnhaU3C58/bRDyjUaNQSilVp7zMYpb+fRP2cgeTHh1GbFLTJWGnQqz1sT2w5g4dxNoGV1fOXACvErExxrtCpEoppRpFflYJS5/dRHmpnZsfGUZcckSTx2CMeRMtadzg6ltZy09EBorIWBFp8o9iSinVFhVkl7D07xspLargpp8MJSEl0tchqQbkdSIWkR9hTRnfijVLuo/z+FIR0TXESinVCApzSln67CaKC8q58X+G0L5LVN1PUi2KV4lYRGYB/8Da0eJ2zp1Z9xVwa4NHppRSbVxRXhnvPreJwtwybnx4CIndon0dkmoE3raIHwWeMcbcT/WC37txto6VUko1jOJ8KwnnZ5Vw48OD6dizna9DUo3E20TcDWsfSE8K8XLRslJKqbqVFJTz7nObyT1TzPUPDSapV4yvQ1KNyNtEnAl0reFcH+B4g0SjlFJtXElhOe/+YxM5p4qYOHsQnfq6b1akWhtvE/EHwG9FpLvLMeOsrTkHa+xYKaXUBSgtruD9f24m60Qh1z4wkJT+cb4OSTUBbxPxr7F2vtiOVXfaAP8EdmFtFP1ko0SnlFJtRJkzCWceLeDa+wfRdZCnPQRUa+RVIjbGZAIjgL8AgcABrGIgzwOjjTG5tTxdKaVULcpKKvjg31s4fTifCbMG0G2wJuG2xNsSlxhj8oE/OL+UUko1gPIyOx/+ZysnD+Ry9cwB9BjW3tchqSbm7Tri70VkSA3nBoqIz3dbUkqplqbCmYQz9uUwfkZ/eo3o4OuQlA94O0bcFavAtychQJcGiUYppdqIinI7H/2/bRzbk82VU/vR+5JEX4ekfKQ+taZr2rh4BJBz4aEopVTbYC93sPyF7RzZmcUVd/el7+iOvg5J+VCNY8QiMgdraRJYSfh9ESlzuywUiAVeb5zwlFKqdbHbHXyctp3D22yM/UEf+qcm+Tok5WO1Tdb6HvjU+edpwAbgjNs1pcBOIK3hQ1NKqdbFbnfwSdoODm7J5LI7ejPw8mRfh6SagRoTsTHmXeBdABEBeNIYc7CJ4lJKqVbFYXfw6Us7ObDpDKm39WTwFZ18HZJqJrxavmSMmeF+TERisWpQbzfGlDZ0YEop1Vo4HIZPX97Fvg2nGT25B0PHp/g6JNWMeLt86dci8heXx5cDh4BvgH0i0qtxwlNKqZbNOAyfv7KLvV+fYuRN3Rl+jS4yUefydtb03VhjxpXmAluAScAptMiHUkpVYxyGL17bw+51J7n4+q6MmNjV1yFVmTVrFiLCnDlzPJ4XkSdEpKbVMo1KRMaJiBGRcS7HHhGRWzxc+4TzWq8LVDUUEZnufO3Kr0IROSQi74jI7eIc162Lt4k4GdjnfOEE4BLgN8aY94GngMvO500opVRrZYzhy9f3snN1BsOv7cLFN3TzdUhViouLWbx4MQCvvfYaFRUVPo6omo3AaOf3So8A1RJxMzEFK96JwG+wJjIvAj4RkdC6nuxtIrYDQc4/Xw6UAGucj89gLWHyiohcIyKfichJESkVkWMislhE+rtd11lE3hKRXBHJE5ElIqIDK0qpZs8Yw+rF+9j+5XGGXp3CqJu742XjqEksXbqUvLw8Jk6cyOnTp1m+fLmvQwJARPxFJMAYk2eMWW+MyfN1TF7a7Ix3lTHmFWPMncDtwJXAX+t6sreJeAdwt4hEAPcCq4wx5c5znYHT9Qg4FvgOeBiYADwODADWi0gXABEJAz4D+mItnboH6AV8LiLh9XgtpZRqUsYY1r69n62fH2PwlZ0Yc0uPZpWEAdLT04mJiWHBggWEhoaSnp7u1fNEJEFEFjkbR9ki8pKI3OShG1lEZI6I7BGRMhE5ISLPi0iU2/2MiPxJRH4hIgeBMmCQe9e0iBzCquD4Q5du4AVu4XUTkWUiUiAih0XktyLi5/JalfecJCL/FZEsEckRkeecHwAuFpHVzu7lHSJyTX1/rq6MMW9jrTya5cxpNfK2T/1J5w1/CJQDrgFO5Nzug7qCW4TVZK8iIt8Au4HbgGeAWUB3oI8xZr/zmq1Y3eMPAH/39vWUUqqpGGNY/+73bF55lEFjk7l0Sq9ml4QzMjJYuXIls2bNIiEhgUmTJrFkyRKys7OJiYmp6+lLgEFYDaj9wK3Avzxc9yfnNf8G3gf6Y80lGiIiY40xDpdrp2PNQfoZUAhkANFu95sMfIg1N+kJ5zH3uhbvAC8BzwI3Ar8HjjqPuXrO+T7uwOrh/TXgD4wHngaOO48tEZEuzt0Hz9eHWHOpRgBf1nSRt8uXPhaRfsBwrCb4AZfTX2L9cC6Ezfm9cqDiJmB9ZRJ2xnBQRNYAN6OJWCnVDH3zwUE2Lj9M/8uSuOyO3s0uCQMsXLgQu93O1KlTAZg2bRqLFi3ijTfe4MEHH6zxeSIyAbgUuMMYs9h5+GMReQ9IcbkuFvgpkG6MedjlujPAK8ANwHuutwYmGGOKXe7Rz/W1jTGbRKQUyDTGrK8hxGeMMZVJd6WIXAncRfVE/Jkx5lHnnz8RkeuxemgvM8asdr7+Cay8dj3gXXeBZ0ec32utYep1rWljzEFjzNtuSRhjzH9r+cHUyNkVEORc+vRf4CRnW8oDgO0enrYD65OVUko1Kxs+PMiGZYfoO6Yj4+7qg/g1bRJ2lJaSvXgxJ//051qvS09Pp1evXowePRqA8ePHk5SU5E339Cis+ULvuB1/y8N1QcBCt+OvYzW2xrodX+6ahC/AMrfH23H5gODiI7fHu4HCyiTscgysodcLUfmPoNbZ57XVmr7c9bExpsZm9Xn6GrjI+ef9wJXGmMqx5lgg28NzsoAa+05E5H7gfoCUFJ3XpZRqGhs/PszX7x2kz8hErri7b5MmYXteHtmvv0HWKy9jP5NJyMCBOEpL8QuuvmHehg0b2LlzJ4899hg5OTlVx2+55Raef/55RKS3MWZvDS/VEch2mR9U6ZTb48rJuydcDxpjKkTERvXJvSdoGFluj0uxdgd0555bynDbuMgYU+bszfD0/PqoTOS1vsfauqa/wMri4vzuf4EBubsHiMIaC/4ZVhfBpcaYQ+d7Q2PMC8ALACNGjPDJ+jelVNuyeeUR1r1zgF4j2nPltH74NVESLj91iqz0l8l54w0chYWEjxlD3F//StioUTV2iVe2eufOncvcuXM9XTIVa3zUkxNAjIgEuiVj902UKxNiIlYvJgDOdb5xVE+Yrfl39fVYq4y+q+2i2hJxoy56M8bscv7xaxH5CKtS1y+AB7E+sXhq+dbUUlZKqSa39fOjrHlrPz2GJzB+Rv8mScKl33+Pbd48ct97H+x2oq69ltiZ9xI6YECtzysrK2PRokWMHDmSp556qtr5OXPmsHnz5ntE5DfGGE/JcT1Wg2wysNjl+BQP15UBd3J24yCwJkcFYDXyzkcp1o5/LYKI3Io13+kfxpii2q6tLRG79uMbrEH2RmGMyRGR/UBP56EdWOPE7vpj7faklFI+tf3L43z1xj66DYnn6pkD8POvz/bu9Ve0aRO2tHkUfPopEhxMzJTbiJ0xg6DO3g1jLlu2DJvNxjPPPMO4ceOqnX/ggQeYPXt2CjAO+Nz9vDFmhXPC7AsiEo81pHgbMMR5icN5XZaIPAM8LiKFWDOH+wF/BFZTfSzXWzuBy0TkBqw5RZkX0oPawIY6fyZBWOPSN2B9QPkEa/Z4rWpLxAtc/tyoiVhEOmCtGX7Veeg94G8i0t0Y873zmq5AKlarWSmlfGbn6gxWvbaHroPiuGbWQPwbKQkbYyhYtQpbWhrFG77DLzqa+IdmE3P33QTEel1HCbC6pSMjI5kyxb0Ba7nrrruYPXt2MVbthmqJ2Gky1nKluVgTt97DqiS1AMh1ue5XWMuLHgQewloZ8zLwuNvSpfp4HHgRqzUeijWbefp53quhven8XoJVV2MjVo/AWzX0LpxDvLimQYnIO1hBbgXygN7AHKzxhEuMMXudRTu2AMVY4xUGaw1aJDDYGFNQ1+uMGDHCbNiwoXHehFKqzdq97gSfvryLlP6xTHxwMP6BDZ+ETXk5ucuWkTVvPqX79hHQsSNx06fR7rbb8Atv1JpG9e5bF5HngRlArO7Ed36avEg21vjB7VjrzIKwFlx/AfylspvBGFPoXAP2LFZLXLDGGh7xJgkrpVRj2PP1ST59eRed+sRw3QODGjwJOwoLyXnrLWwL0qk4cYLgXr1ImvsUURMnIoGBDfpa50NEpmMV29iB9fv7WmA28LQm4fPX5C3ipqItYqVUQ9q34RSfzNtBUq92XP/wEAKDGm4hSYXNRtbChWS/tghHbi6hIy4i7r77iBg7tqmLgtT6YiIyBavbuQcQDBwE5mMl4vPtcm7zfNEiVkqpFuXAxtN8Mn8niT2imfjQ4AZLwmVHj5L10kvkvL0EU1pKxPiriJs5k7Bhwxrk/g3NGPMmZ8dDVQPRRKyUUrU4uOUMK9J20KFrJDc8PISgkAv/tVmycye2tDTyln8M/v5E33QjcTNnEty9ewNErFoaTcRKKVWDQ9syWf7CduJTIrnhx0MvKAkbYyhavx7bi2kUrl2LX3g4sTOmEzt1GoEd2jdg1Kqlqa3E5RLgf40x+0VkKrDMGGOr6XqllGpNjuy0sfy/24lLjuCm/xlCcOj5JWFjt5O/YgW2tHmU7NiBf3w8CY8+Ssydd+AfFVX3DVSrV9u/rJuByvIrLwGjObtLklJKtVpHd2fx4f9to11iGDf9ZCjBYfWfsewoKSF36VJs81+i/MgRgrp0IfHJ3xN9880e60Crtqu2RHwKK/l+w9l600op1aod35vNh//eSnRCKDf/ZCgh4fVLwvbcXLIXLSLrlYXYbTZCBg2i/T/+QeT4qxD/hi7Zr1qD2hLxYuBZEfk7VhJeX8s0emOM0fFmpVSLlrE/hw/+vZXIuBBufmQYoZFBXj+3/MQJaxOGxYtxFBURftllxN13H2GXXNws9yVWzUdtyXMOsAarvvPvsEqYHW+CmJRSqsmd/D6XD57fQkS7YG6eM4ywKO+ScOn+/djS5pH7wQdgDFHXXUfcfTMJ6du3kSNWrUWNidhZH/NNqKqm8g9jzJYmiksppZrM6cN5vP/PzYRGBnHzI8MIj657DLfou++sTRg+/xwJCSHmzjuJnT6doE7JTRCxak286k42xjTqlohKKeUrZ47k894/NhMcHsikOcOIiKk5CRuHg4IvvsD2YhrFmzbhHx1N/I9+RMzdPyQgxtPOrUrVzetxXRHpiFUfeizWvsBZWDt0/N0Yc7JxwlNKqcaTeayAd/+xicAQfybNGUZkbIjH60xZGbkfLMM2fx5l+w8QmJREh1/9ina33oJfWFgTR61aG68SsYj0xtpHsh3WuPF+rN2SfgJMFZHLjDH7GitIpZRqaLaMAt59bhMBgVYSjoqvvue8vaCQnMWLyUpPp+LUKYL79CHp6b8Sde21zWITBtU6eNsinou11+Qlrhsxi0gXYIXz/C0NHp1SSjWC7JOFvPvcZvz8hUlzhhGdcG6rtiIzk6xXFpK9aBGOvDzCLrmEjn/8A+GXXqozoFWD8zYRXwE86JqEAYwxh0XkCeA/DRyXUko1ipxTRSx9dhMYw6RHh9Ouw9kkXHb4MLb5L5H7zjuY8nIir76auPtmEjp4sA8jVq2dt4k4CMiv4Vy+87xSSjVruWeKefe5TTjshkmPDiMmMRyA4m3bsaWlkb9iBRIQQPSkScTeO4PgbjpPVTU+bxPxZuDHIvKR656TYvXRPOQ8r5RSzVZeZjFLn91IeZmdSXOGEdsxnILVa7ClpVG0fj1+ERHE3TeTmHvuIbC9bsKgmo63ifhJ4ANgl4i8AZzAmqw1BegFXN844Sml1IXLzyrh3ec2UV5i56YfDyJw85cc/PE8SnftIiAhgfY//xnt7rgD/4gIX4eq2iBv1xEvF5EbgD8Cv+Js7envgBuMMSsaL0SllDp/BdmlLH12EyUF5Yzre4q8WX+g/Ngxgrp1o+Mf/0DUTTfhF6Sja8p3vF5HbIxZDiwXkTAgBsg2xhQ1WmRKKXWBCnNLWfrMBoqyihi2J42K5VsJHTKEDr94jIgrr0T8/HwdolLeJ+JKzuSrCVgp1azl7j3Cu//cSlGpP0O2/puOQzsR99TLhI4YoUuQVLOiOyYppVqVkj17+f6F11ln60dZYCSpUZvp/fLfCenT29ehKeWRJmKlVItnjKF4wwYy09I4vD2LHf1nEBjux03Te5F88bW+Dk+pWmkiVkq1WMbhIP/TT8lKm0fRli0c630j+wbdTnxSGNf/eHitGzgo1VxoIlZKtTiOsjLy3nsP27z5lB08iH+nLhy642kOngqjx/AErpren8Agf1+HqZRX6kzEIhIErAd+ocuUlFK+ZM/PJ+eNN8hKf5mKM2cI7teP2D//jTUHOnDiQB4jru/KJdd3Q/x0MpZqOepMxMaYMhHpBlQ0QTxKKVVN+enTZL/yCtmLXsdRUEDY6FF0fOovlHQZzIf/t42i3AImzBxAr4s7+DpUperN267pT4AJwGeNGItSSp2j9OBBsubPJ3fpuxi7ncgJE4ibOZPQQQM5tC2TFX/bSGCQP5N/OpwO3aJ8Ha5S58XbRPwvYKGIBABLsUpcGtcLjDHfN2xoSqm2qnjrVmwvppG/ciUSGEj0rbcQN2MGQV26YIxh88ojrHl7P/GdIrj+ocFExIT4OmSlzpu3iXiV8/ujwJwartGZEUqp82aMofCrr7ClzaPom2/wi4oi7v77ib3nbgLi4wGwVzhYtWgPu9acoPuwBMZP709gsP7qUS2bt4l4RqNGoZRqs0x5OXnLl2NLm0fpnj0EdOhA+8ceo92UKfhHhFddV1xQxvL/bidjXw4XXdeFkTd210lZqlXwdtOH9MYORCnVtjiKish5622yFiygPCODoB496PjnPxN9w/WI2yYMWRmFLPvPFgpzyrj63v70viTRR1Er1fDqtY5YRPyA/kAcsMEYU9goUSmlWq2K7GyyF75K9quvYs/JIXT4cDr8+tdEjBvrcROGw9ttrEjbjn+QP5MeHUZi92gfRK1U4/E6EYvIj4DfAfFYE7UuBjaKyFLgM2PMPxslQqVUq1B27DhZCxaQ89ZbmJISIq68krj7ZhI2fLjH640xbP3sGGve2kdssjUpKzJWJ2Wp1serRCwis4B/APOBFcBil9NfAbcCmoiVUtWU7N6NLW0eeR99BH5+RN9wA3Ez7yW4Z88an2O3O/jy9b3s/CqDbkPiGT+jP0EhWghQtU7e/st+FHjGGPOYiLhPUdwN/Lxhw1JKtWTGGIq+/gZbWhqFq1fjFxZG7NSpxE6bSmBi7eO7JQXlLH9hG8f35jD82i6MukknZanWzdtE3A34uIZzhUC7BolGKdWiGbud/JWfYktLo2TbNvzj4kh45BFi7roT/+i6x3azTxbywb+3UpBdwvjp/egzqmMTRK2Ub1WfGeFZJtC1hnN9gOMNEo1SqkVylJaSvXgx30+8nuM/+Qn23FwSn/gdPT9dSfyDD3iVhI/stPHW3O8oL6lg0pzhmoQb2axZsxAR5szxXBpCRJ4QEePxZCMTkXEiYkRknMuxR0TkFg/XPuG8tsnHLkRkuvO1K7/sInJcRBaLSB9v7+Nt4B8AvxWRL4DDzmNGROKxCnwsrU/wSqnWwZ6XR/brb5D1ysvYz2QSMmAAyc89S+TVVyP+3hXaMMaw7YtjrF68j9ikcCY+NJiouNBGjrxtKy4uZvFia6rPa6+9xtNPP01AQLMag98IjAZ2uhx7BFgNLPFFQHWYAhzDKmzVA/gN8KmIDDDG5Nb1ZG9/8r8GrgC2A19jzZr+J9AXOA08Wf+4lVItVfmp02S9nE7O62/gKCwkPDWVuL/+lbBRoxDxfjzXbnfw1Rv72PHlcboOjufqe3VSVlNYunQpeXl5TJw4kQ8//JDly5dzww03+DosnHOQxBiTh7XrX0ux2Riz3/nnNSKSgbVHwxjgo7qe7FXXtDEmExgB/AUIBA5gJfHngdHeZHylVMtX+v33ZPzqV+wfP56slxYQMXYs3Za8Tcq8NMJHj65XEi4pLOf9f25hx5fHGTYhheseHKRJuImkp6cTExPDggULCA0NJT3du5pNIpIgIotEJE9EskXkJRG5yUM3sojIHBHZIyJlInJCRJ4XkSi3+xkR+ZOI/EJEDgJlwCD3rmkROQR0AX7o0g28wC28biKyTEQKROSwiPzWWfui8rUq7zlJRP4rIlkikiMiz4mIv4hcLCKrRaRQRHaIyDX1/bm6yHN+D/TmYq//1Rtj8oE/OL+UUm1I0aZN2ObNo+DTz5CgIGKmTCF2xnSCOnc+r/tlnyxk2X+2km8r4app/eg7WseDm0pGRgYrV65k1qxZJCQkMGnSJJYsWUJ2djYxMTF1PX0JMAh4HNiPtXT1Xx6u+5Pzmn8D72MVgvoDMERExhpjHC7XTge+B36GNfk3A3CfVDAZ+BDYAjzhPHbG7Zp3gJeAZ4Ebgd8DR53HXD3nfB93AJdj9fj6A+OBp7HmPP0aWCIiXZwN0br4O8eo/YHuwJ+xeou/8OK59a6sFQUMBJKx+sO3OxO0UqqVMcZQsGoVtrQ0ijd8h190NPGzHyTm7rsJiI097/se3ZXFxy9uR/yEm+cMI6lnu4YLWtVp4cKF2O12pk6dCsC0adNYtGgRb7zxBg8++GCNzxORCcClwB3GmMpaEh+LyHtAist1scBPgXRjzMMu150BXgFuAN5zvTUwwRhT7HKPfq6vbYzZJCKlQKYxpqYu62eMMZVJd6WIXAncRfVE/Jkx5lHnnz8RkeuBh4HLjDGrna9/AivpXw94012w2+1xBnCDs4u9TvWprPVbrB9uBNYPDiBfRJ42xvzR2/sopZo3U15O3ocfWpsw7NtHQMeOdPjl47S79Vb8wsPrvkEttn1xjK8W7yMmMYzrHxpMVLxOyqoXhwOKbFB4GgpOQYHrd+ef/QLgnprnM6Wnp9OrVy9Gjx4NwPjx40lKSiI9Pb3WRAyMAuxYLU9Xb2G1QF2vCwIWul33OlZSHMu5iXi5axK+AMvcHm8Hhnm4zn3MdjfQuzIJuxwD8LbLZzJW41SAJKzE/qGIXG6M2VXXk72trPV7rFlgaVg/zFNAB6xPG78XkQBjzBNe3Oc253NGAO2BI1hdBH92bVmLSAxWF8EkIBRYB8wxxmzzJl6lVP05CgvJeestbAvSqThxguBevUia+xRREycigV4NddV8b7uD1Yv3sW3VcboOiuPqmQN0PLiSMVCS65JUT0HhGc+JtvAMGHv1ewSEQmQHCG8PMV1qfKkNGzawc+dOHnvsMXJycqqO33LLLTz//POISG9jzN4ant4RyDbGlLsdP+X2uLK75MS5b9NUiIjN5TyerrsAWW6PSwFPNVGz3R6XATmuB4wxZc75Dt7WVN3uMlkLEVmB1S3+BFYXeK28/Z8wC6vZ71pBawfwmYjkAvdztt++Nj/DSr6/xPr0MMz5vCtEZIwxxiHWu38fa93yj7F+aI8Dn4vIUGPMMS9jVkp5oSIri+yFC8l69TUcubmEjRhBxyd+R/jll9dr8lVNSgrL+fjF7Rzbnc3Qq1MYPbkHfm2hUlZZoTOJnjmbYAtOO1uzbi1ae1n15/sFQkR76ysqCZKGWok2ooPzeIez54MiwIu/q8pJWXPnzmXu3LmeLpmKNT7qyQkgRkQC3ZJxB7frKhNiIlaeAMA5hhpH9YTpk7XKjckYUywi3wODvbne20QcTc2VtZYDs728z43GGNcB9lUikoXVBz8O+Ay4CUgFrjTGfA4gIuuAg8D/Av/j5WsppWpRdvQoWS+9RM7bSzBlZURcdSXx991H6NChDfYaOaeKWPafreRlFnPFPX3pn5rUYPf2iYpSD63VGhJtWYGHGwiEJ5xNovG9XZJqh3PPhcZ4lVy9VVZWxqJFixg5ciRPPfVUtfNz5sxh8+bN94jIb4wxnpLjeqzJSJM5d7+BKR6uKwPuBD51OX4HVs754jzfQilWD2mzJyJhWOuJd9R1LXifiL/G2m1ppYdzFzvP18ktCVf61vk92fn9JiCjMgk7n5crIu8DN6OJWKkLUrJzp7UJw/Ll4O9P9M03EXfvvQR3796gr3NsdxbLX9iOiHDzI0NJ6lXnjFzfcNihMNMtkdYw/lqS4/keoTHO1mp7SBruTKYJbq3XDhAWB37eFTppaMuWLcNms/HMM88wbty4aucfeOABZs+enYLVKPrc/bwxZoWIrAFecBZz2g/cBgxxXuJwXpclIs8Aj4tIIdZs537AH7EKcriP5XprJ3CZiNwAnMSauHXoPO/V0IY6fyaC1YX/MFYXvKcZ5dXUmIhd119hJb93RKQCeJOzY8S3A/diJcjzNdb5vXJAewDWILu7HcBUEYkwxnj6qKmUqoExhqL167G9mEbh2rX4hYcTO2M6sVOnEdihfYO/3vYvj/PV63uJ7mBNyopOaOKGjDFQnF29C7hat/BpKMqEc1bTOAVFnE2i7ftCt8vdEmvC2VZsQHDTvr/zkJ6eTmRkJFOmuDdgLXfddRezZ88uBqbhIRE7TcZKLnOxJm69hzV/aAHgWk/iV1jLix4EHgJswMvA425Ll+rjceBFrNZ4KFZP6vTzvFdDe9Plz2ewcti1xpiaepLPIZ57IEBEHJzbdy947ssXwGGMqffMCxFJBjYBW4wxVzuP7QU2GmPudLv2Pqy/hBRjzNG67j1ixAizYcOG+oakVKti7HbyP/kE24tplOzYgX9CPLFTpxJz5534R0Y2+Os57A7WvLWfrZ8fo8vAOCbMHEBQaANNyjIGSvNduobdWqtVyfaM9WeH+5wiwD+4htZqe7fx1/YQdGEzxFuoeveFi8jzwAwg1hhT2vAhtX61/Q95kkYcRBeRCOBdoALrL7Eh7nk/1sQxUlJS6rhaqdbLUVJC7tKl2Oa/RPmRIwR16ULik78n+uab8QtunNZbaVE5K9J2cGRnFkOu6syYW3t6NymrvPjchOqp1Vr55woPq1zE3zm26kykHQae21qNTDzbbRwS3aDjrm2NiEzHmjO0A2uJ0rVYc4Se1iR8/mpMxN4sRzpfIhKKNTO6OzDWbSZ0NuBpMCnW5bxHxpgXgBfAahE3TLRKtRz23FyyF71O1iuvYLfZCBk8mPY/+ymRV13l9SYM5yPndBEf/mcruaeLueLuvvQfnQAFJzwnU/dEW1pDzYOwuLMt1M4jzx1rrWrRdoDQWPDzdiM5dYEKsTZf6AEEY02i/SXWclN1nnyxbVQg1gLwEcDVHtYG7wAmeHhqf+CIjg8rVV35yZNkLUgnZ/FiHEVFhF9+GXH33UfYxRc3yBIk4GwxCbdW6/GDZXz09UAwDm7qspDkNethpfsKFafg6LNdv4mDaugW7gDh8eB/YWuXVcMzxrzJueOhqgHUp7JWP6wZcp2pvsjZGGOmeXEPP+BV4Eqs8l+eSpW9B8xw1iNd5XxeFFbllte8jVeptqB0/35s8+aT+8EH4HAQNXEicffNJKSPl1uhGmPNBK5xrLVyLPaMx2ISO4qu5su8+4kOyuT6Pu8QHR8EEZPPJttzluW0h8AWsfpEqSblbWWtqcB8rDHj01hrxFx52w38b6w1Z38CCkVklMu5Y84u6vewKmktFJGfc7aghwB/9fJ1lGrVijZuxPZiGgWff46EhhJz553ETptGUCfnKsDSgtrHWl0TrcdiEgFnW6iRSdBx6Dndwo6w9qz9Kogta/NJ6R/LhFlXEhz6gyb9GagLM2vWLNLS0njkkUd49tlnq50XkSeA3xljmnxQ3bnr0ufAFcaYL5zHHsHqFV3idu0TwO+AQGNMRVPG6RLDaGAOVi3ueCAfa0/lhcBCYzyVQ3N5fk2zpt1eZB+wFZhpjMm5gGAPYW1l5cnvK8elnUXD/4ZV4jIEKzE/aozZ4u1r6axp1dqYsmIKlr+PLX0hxTv24R8RSsy4PsRcHE8A2S6FJU5DeaGHO4jLpKaaZgs7v4e0q3HctbS4wpqUtcPG4Cs7kXprT/z8dYy2JSkuLiYxMZG8vDzat2/P8ePHCQgIAJdZ0z5OxFFYw5E7KzdOcOaP1caYu92ufQIfJmLnB4S/YxWkSgcOY81zmoA1EfkuY8y7td3D267pRODBC0nCAMaYrl5el4W1PvneC3k9pZo9e4W1jrWWCk0m9yS5W7OwbfOjLC+QwPAKOgwvoF33E/gFHICD7c4m0OSLak60YXHgf2HTQnLPFLPsP1vJPVXE2B/0YeDlyXU/STU7S5cuJS8vj4kTJ/Lhhx+yfPlybrjhBl+HhYj4YzUQ87AqdDVrInI5VhJ+3hjjXmzqXRH5O1DnOjhv/1euwaqM8mldFyrV5jkcznHXuta6nrIqOnka2QmKwB6UQM6BMLK+K6MiL5jgTrEk3Z1K1PjLkeiOTV5MImNfNh/9v+0YY7jxJ0Pp1KeZVspSdUpPTycmJoYFCxbQpUsX0tPTvUrEIpIA/BNre0A7sBRrN6Z3ObcbWbBmVz8IdMMq6PE28EvXrQFFxGDt3ZsPPIC1neIIEYnGpWvapTe1i4j8sPJtGGOmu4TXTUSewyoSZQPmAX+sLCDi0t09GbgOa5jUD6sYyU+B4Vh7GQ8DDmH1wtZVkOMxrNrZ/+vppDHmQB3PB7xPxA9jbZJsA1bgYQnRBVRLUar5qywm4XGt66lzu4ULT4PDQw+Zf/DZ1mq7FOg04uz6Vpfx14oSf7LeeIfsRYtw5GUTNnIkHe+7j/BLUxtuBnQ97VyTwarX9hAVH8r1Dw2mXYcwn8ShLlxGRgYrV65k1qxZJCQkMGnSJJYsWUJ2djYxMXV+uFoCDMKat7MfuBXPZRz/5Lzm31hLVfsDfwCGOCfiuuaL6cD3WJsCFWLt5Rvtdr/JWKUyt3B2gyH3ksnvYG2z+CzW5N7fY+2A5L4f8XPO93EHcDnWJhf+wHisZVjHnceWiEgXY0ympx+Es/V+BbDUGFPi6RpveZuIj2FVwHLfX7KSqce9lGo+you92CHHed6rYhIDah5/raOYRNnhw9j+8RK577yDKS8n8uqriZt1H6GDBjXiD6B2Dodh3ZL9bF55lM79Y7nmvgEEh+myoubMGFPrB7aFCxdit9uZOnUqANOmTWPRokW88cYbte5HLCITsCYj3WGMqdz04WMReQ+rJVt5XSxWCzPdGPOwy3VngFeAGzh3P2IBJrjuSexcpeP6njaJSClWfemauqyfMcZUJt2VInIl1ra77on4M2PMo84/fyIi12M1Ni+r3JNYRE5gJf3rscZ9PYnHKrV5uIbzXvM2eb6I9elhKdaGyR6mWSrVTNjLa97P1T3R1lVMIjwBOo+qvu1cAxaTKN6+A1taGvkrViD+/kRPnkzsjOkEd+t2Qfe9UGXFFayYv4PD22wMGteJS6fopKzm6mjeUVZnrGbt8bVkl2azcGJNbSarW7pXr16MHj0agPHjx5OUlER6enqtiRgYhdUd/Y7b8bewWqCu1wVRveH2OlZSHMu5iXi5axK+AO6bSWzH6mZ295Hb491A78ok7HIMrOW6jc7bRHwz8HNjzD8aMxilauSwQ1FW3RunF5yC4tqKSSScLYPYM9Fl2zmXJBue0OjFJIwxFK5Ziy0tjaL16/GLjCRu5kxip95DQEJCo762N/IyrUlZ2SeLGHtXbwaO7eTrkJSLwvJCvjnxDWsy1rA2Yy1H863y+8kRyVyafCkVjgoC/Kr/et+wYQM7d+7kscceIycnp+r4LbfcwvPPP4+I9DbG7K3hZTsC2W57EYO1CZCryiqIJ1wPGmMqnMObsW7Xn6BhuP/HL6V6zQuoPrRaBuS4HjDGlDl7FTw9v5INKKbmlUBe8zYRF2JtQaVUw/G6mMRpa1KTp6V4AaFnW6hxPaDLaLcKTe3PJthmUEzCVFSQt/xjbPPmUbprFwHt29P+5z+n3R234x8R4evwAMjYn8NH/28bxmG48cdD6NzP/femamoO42BP1p6qxLvp9CYqHBWEBoRySeIl3N3vblKTU0mJTKm1Wzo93eplnTt3LnPnzvV0yVSs8VFPTgAxIhLolow7uF1XmRATcdmPV0QCgDiqJ8wWWY7Y+cHiC+BqEQm+kFrb3ibil4AfAJ+c7wupNuSCi0kEnk2eUcluxSTcluYERbSIIv6O4mJyliwh66UFlB87RlD37nT80x+JuvFG/IKCfB1elV1rT/DFq7t1UlYzYCu2se7EOtYeX8vajLXYSmwA9Inpwz397yE1KZVh7YcR5O/dv5+ysjIWLVrEyJEjeeqpp6qdnzNnDps3b75HRH5jPBeYWI81qWky1laEldz3VVyP1cq8k3NX2tyBlXO+8Crg6kqxxmSbk6ew3s9fgZ+4nxSRbkCkMWZrbTfxNhEfBu4SkU+A5XieNT3fy3uplqii9GxCrW3j9DqLSTgL9if08dBqdSbX0JgWkVy9Yc/JIeu118h+ZSH27GxChw6lw+O/IOKKK5BmtFGBw2FY/84BNn1yhE59Y7hm1kBCwnVSVlMqd5Sz5fQW1masZU3GGnbarE7IdsHtGJ00mtSkVMYkjSEh7PyGLpYtW4bNZuOZZ55h3Lhx1c4/8MADzJ49OwUYh4f9iI0xK0RkDfCCiMRjzZq+DRjivMThvC5LRJ4BHheRQqzZzv2APwKrqT6W662dwGUicgNwEmvi1qHzvFeDMMZ8KSKPAn8Xkf5YS6GOYBX0uAq4D6sR2yCJ+P+c37s4b14tHqwSmKolqSom4TZD2NP4a0mO53uExpyd1JR8kVur1WVSU1gc+DXe7j/NTXlGBrYFC8h5621MURERY8daM6AvushnS5BqUlZSwSfzd3JoayYDxyZz6e298NdJWU3iWP4xK/EeX8PXJ7+msLwQf/FnSMIQHh76MJcmX0q/uH74yYX/faSnpxMZGcmUKe4NWMtdd93F7Nmzi4FpeEjETpOxlivNxZq49R7wG6wElOty3a+wlhc9CDyENZ76MvD4BSx1fRxr4vBirJZxOtbSJ58yxjwnIt9glbj8G2dLXG7AWhv9fl338LbEZZ2D0caYC57C3ZDabIlLY6A4+wKLSURWT6burdbKSU1NVEyipSjZs5es+fPIXfYhANHXX0/szHsJ6d3bx5F5lmcr5sP/bCXrRBGX3d6LQeN0UlZjKiovYsOpDaw5voY1GWs4nGf92kwKT2JM8hguTbqUSzpeQmRQpK9CrPenRBF5HquUY6zuSXx+vGoRN7ck2+a4FpOoq1u41mISziTargt0utglobZ3bp7uXA8bVGdFNuXCGEPxhg1kpqVRuOpLJCyM2B/+gNhp0whMSvJ1eDU6cSCXj/7fVuwVhhsfHkLn/jopq6EZY9ibvbeq1bvx9EbKHeWE+IcwInEEd/a5k9TkVLpGdW12PSWeiMh0rGIbO7CWKF0LzAae1iR8/rQIhy+VF3vXLVxwuuZiEq7JtMPAGta7tofgqFYz7tpcGIeD/E8/JSttHsVbtuAfG0vCT/6HmLvuwr9dO1+HV6s960/w2cLdRMaEcP2PBhOTqB++GkpOSQ7rTqxj9fHVrMtYx5liqwBUz3Y9+UHfH5CanMrwDsMJ9m+RvUmFWKUrewDBwEHgl1gVqdR58nYbxIPUMcXcGNO9QSJq6aoVk6hpWU5txSTizybSlFE175DTAMUkVP05ysrIe+89bPPmU3bwIIGdOtHht7+h3S234BdS27JD3zMOw/p3v2fjx4dJ7tOOa+8fpJOyLlCFo4JtmdtYfdwqqLHDtgODISoo6pxJVh3C3Vf5tDzGmDeBN30dR2vjbYt4FdUTcRwwBijA2v6p9XI4oMjmXbdwkc3zPYKjzybRxME1bJzeAcLjG72YhDo/9vx8ct54g6z0l6k4c4bg/v1I/vszRE6YgAQ0/86lspIKVr60k4NbMhlwWRKX3dlbJ2Wdp4yCDGtN7/G1fH3ia/LL8/ETPwbHD2b20NmkJqUyIG4A/m1ogqI6f96OEU/3dFxE2mEtZ1rZcCH5kDHw6e+rJ9rCMzUXk4h0TmSK6wFdxpxdnuO67jW8PQQ275aSqln56dNkv/IK2Ytex1FQQNjoUXR86i+EjxnTIsb1AHJOFbH8xe1kHS/gsjusSVktJfbmoLiimA0nN1QtLTqYexCADmEdmNB1AmOSxjCy40iig933KlCqbhf0Md4YkyMiT2PttPFaw4TkQyKwaSH4BzmLSSRB0lDP3cItqJiEOj+lBw+SNf8lcpcuxdjtRF4zgbiZ9xE6cICvQ/Oaw+5g88qjfPPBQQIC/bj+4SF0GRDn67CaPWMMB3IOsCZjDWuOr+G7U99R5igj2D+YER1GcFuv20hNTqV7dHf9QKMuWEP0p5UArWfNw8/2aXJt44q3bsX2Yhr5K1cigYFE33oLcTNmENTlgkvKNqnMY/l89vJuzhzJp9uQeMbe1Yfwdi1yglCTyC3NrapktSZjDaeLTgPQI7oHd/S9g9SkVC7qcBEhAdq7pRrWeSdiZ93QgVh7Q+6o/eoWRJNwm2SMofCrr7ClzaPom2/wi4oi7oH7ib37bgLi430dXr3Yyx1s+OgQG5cfJjg8gGtmDaTH8ARtubmxO+xsy9xW1d28PXM7DuMgMiiSUR1HkZqUSmpyKonhib4OVbVy3s6adlDzrOk8rD0blWpxTHk5ecuXY0ubR+mePQQkJtL+F4/R7rYp+Ee0vCU9J7/P5bOXd5F9sog+oxK59LZehETo5L9KJwtPVq3pXXdiHfll+QjCoPhB3D/4flKTUhkYP9DjzkVKNRZv/7U9SfVEXIJVg/ojY0xu9aco1Xw5iorIeettshYsoDwjg6CePej4l78Qff1EpBltwuCt8lI76989wNbPjxHRLpgbHh5Cl4E6FlxSUcLGUxurxnoP5B4AoH1oe65KuYrUpFRGdRxFu5B2vg1UtWnezpp+opHjUKpJVGRnk73wVbJffRV7Tg6hw4fT4de/JmLc2Ga1CUN9HN2VxecLd5NvK2HQ2GRGTe5BUEjbbNEZYziYe9BKvBlr2HByA6X2UgL9Armow0VM6jmJ1ORUerbrqV31qtlom/9bVZtTduw4WS+9RM7bb2NKSoi48kri7ptJ2PDhvg7tvJUUlrP27f3sWnuC6PahTP7pcJJ6tfN1WE0uryyPr098XVW/+WThSQC6RnXltt63kZqUyojEEYQGNLcd9JSyeJ2IRWQscBeQArhPGzTGGE+7MinlUyW7d2NLm0feRx+Bnx/RN95I3L0zCO7Z09ehXZDvN51h1aI9FBeUM/yaLlx8fVcCgtpG8Qi7w85O205WZ1iVrLZlbsNu7EQERjCy48iqsd6kiOZb51spV95O1noAayvELGAv1gbN51zSwHEpdd6MMRR9/Q22tDQKV6/GLyyM2KlTiZ02lcDElj0DtiivjC9f38uBjaeJ7xzBDQ8PISHFZzv1NJnTRadZc3wNazPWsu7EOnJLcxGE/nH9mTloJqlJqQxKGESgn05MUy2Pty3in2IV7LjXGFPWiPEodd6M3U7+yk+xpaVRsm0b/vHxJMyZQ8ydd+Af3bIrHhlj2PP1SVYv3kd5mZ2RN3dn2ISUVluissxexnenvqtaWrQvex8A8aHxjO00ltSkVEYnjSYmJMbHkSp14bxNxMnAS5qEVXPkKC0ld+m7ZM2fT9nhwwR2SSHxiSeInjwJv+CWX8AiP6uEL17dzZEdWSR2j+bKqX1b3W5JxhgO5x2umt284dQGiiuKCfAL4KL2FzHnojmkJqXSO6a3TrJSrY63ifg7oDvwaSPGolS92PPyyF70OlmvvII9M5OQgQNJfu45Iq8ej/i3/PFS4zBs//I46945gAGrRvTYTohf60hEBWUF1iSrDKvL+XjBcQC6RHWxZjcnpXJx4sWEBYb5OFKlGpe3ifh/gFdFZI8x5svGDEipupSfOkVW+svkvPEGjsJCwi+91JoBPXJkq2ktZZ8s5POFuzmxP5fO/WIY98O+RMW37Fm/DuNgl21XVat3y5kt2I2dsIAwRnYcyYwBMxiTPIbOkZ19HapSTcrbRPw+EAV8LiJFQLbbeWOMaVmFeFWLU3rgALZ588l9/32w24m67jri7ptJSL9+vg6twdjtDjZ/coRvPzhEQJAfV03rR59RiS32A0ZmcebZSlYZ68gutX519Ivtx4yBMxiTNIahCUMJ1K0/VRvmbSL+lJpLXCrVqIo2bcKWNo+CTz9FQkKImTKF2HtnENSp9ew1AnDmSD6fvbKLzKMF9BiWwGV39iY8umWNcZfby9l0elNVq3dP9h4AYkNiSU1OZUzSGEYnjSY+tGXV71aqMV3QfsRKNRbjcFCwahW2efMo3vAd/tHRxD/0EDF3/5CA2Fhfh9egKsrtbFh2iI0rjhASEci19w+kx/D2vg7La0fyjlQl3m9OfmNNspIAhrYfyk+G/4TUpFT6xPbBT1rnDG+lLpRW1lLNiikvJ3fZMrLmzaN0334CkjrS4ZeP0+7WW/ELb10zhQFO7M/hs1d2k3OqiL6jE0m9rRch4c27m7awvJBvTnxTlXyPFRwDoFNEJ27qcROpSalc0vESwgNb39+XUo2hxkQsIrcYY5bU52Yi0hHoYoxZf8GRqTbFUVhI9ptvkpX+MhUnThDcuzdJf51L1HXXIYHNOzGdj7KSCtYv/Z5tq44RGRPCjf8zhJT+zXOTBodxsCdrT1Xi3XxmMxWOCkIDQrkk8RKmDphKalIqKVEpvg5VqRapthbxv0Tkt8D/AxYbY7JqulBELgPuAX4IzAE0ESuvVNhsZC1cSPZri3Dk5hJ28cV0fOJ3hF9+eYudoFSXIztsfP7qbgqySxk8rhMjb+7e7DZpsBXbWJuxtuorq8T67983ti9T+1uJd2j7oQT5t7ydqpRqbmr7398L+BnWFoj/EpFdwBbgDFaJyxistcUjgGjgS+BqY8zaRo1YtQplR49imz+f3CXvYMrKiBx/FXH33UfokCG+Dq3RlBSWs+bNfexef5KYxDBu+elwOvZs5+uwACh3lLP59OaqGc67snYBEBMcw+ik0VUTrXSSlVINT4ypfTK0iAQBk4FrgFFAEtamDzZgN1YCfsMYs7txQ62fESNGmA0bNvg6DOWmZOdObGlp5C3/GPH3J3rSzcTOuJfg7t18HVqjOrDxNKte30tJQTnDr0lhxMSuBAT6tujI0fyjrD1ulZD85uQ3FJYX4i/+DEkYQmpyKqlJqfSL66eTrNqW1tkN1czV2R/mLGv5hvNLqXozxlC0bh22tHkUrl2LX0QEcffOIOaeqQR2aDmzg89HYW4pX76+l+83nSG+cwQ3/ngICZ19s0lDUXkR3578tqqS1eG8wwAkRyQzsdvEqklWkUGtfxMJpZqT5jUwpVoVY7eTv2IFtrR5lOzYgX9CPAk/fZSYO+/EP7J1/7I3xrB73UnWvLWPijIHoyf3YOj4zvg14SYNxhj2Zu+1Eu/xtWw8vZFyRzmhAaGM6DCCu/rexZikMXSN6tpqx+OVagk0EasG5ygpIfedd7DNf4nyo0cJ6tqVxD88SfTNN+MX1Pon9+RlFvPFq7s5uiubjj2jueLuptukIbskm3UZ66pavZnFmQD0iunFD/v9kDFJYxjeYTjB/i2rUIhSrZkmYtVg7Lm5ZC9aRNYrC7HbbIQMGUz7//05kVde2So2YaiLw2HY9sUx1r/7PQJcfmdvBl6e3KibNFQ4Kth6ZmvV0qKdtp0YDNHB0YzuOJoxSWMYkzSGDuEdGi0GpdSF0USsLlj5iRNkLUgn+803MUVFhF9+GXH33UfYxRe3mS7PrBOFfP7Kbk5+n0vKgFjG/bAvkbEhjfJaGQUZVd3N60+sp6C8AD/xY3D8YGYPnc2lSZfSP64//n6t/8OPUq2BJmJ13kr378eWNo/cDz4AY4i6fiJxM2cS0qePr0NrMna7g00fH+HbDw8SGOzP+On96D2yYTdpKK4oZsPJDazNWMvq46s5lHcIgMTwRK7peg2pyamM7DiSqKCoBntNpVTT8SoRi0iQc/Z0Tec7GmNONFxYqjkr+u47axOGzz9HQkOJuesu4qZPIzA52dehNakzR/L59OVd2I4V0POi9lx2R2/Coi58DNwYw/6c/VWJd+OpjZQ5ygj2D2ZEhxHc3ud2UpNS6Rbdrc30OCjVmnnbIn5NRKYYD4uOnWUtPwf6NmhkqlkxDgcFX3yB7cU0ijdtwj8mhvgfP0zMD35AQEyMr8NrUhVldr5ddpBNnxwlNCKQ6x4cRPehCRd0z9zSXNadWMea49Ykq9NFpwHoEd2DO/rewaVJlzK8w3BCAhqnu1sp5TveJuJLgeeBH7keFJFE4DOsSlteEZFOwGNYFbmGAKFAN2PMIbfrQoA/AHcD7YDNwGPGmC+9fS114UxZGbnvf4Bt/nzKDhwgMDmZDr/+Ne1uvQW/0Ja9Uf35yNiXzWev7Cb3dDH9Ujsy5pae57VJQ4Wjgu2Z26vGerfbtuMwDiKDIhnd8Wwlq8TwxEZ4F0qp5sTbRHwD8JmInDLGPAkgIh2wkrADuKoer9kTuB34DvgKmFDDdfOA64GfA99jfQj4WERGG2M21+P11HmwFxSQs/hNstLTqTh1iuC+fUn629+IuvYaJKDtTS0oK65g3dIDbF91nKj4EG76yVA696vfdownC09WdTevP7Ge/LJ8/MSPgXEDeWDwA4xJGsPA+IEE+LW9n69SbZm3+xFvEJHbgPdF5CSwBCsJC3CFMSazHq/5pTGmA4CI3IeHRCwiQ4AfAPcaY15yHlsF7MCqfX1TPV5P1UNFZiZZL79C9qJFOPLzCRs5ko5//CPhl6a22fHIw9ttfPHqbgpyShlyZWdG3tydwOC6ZySXVJSw8dRGVmesZu3xtRzIPQBA+9D2jE8Zz5jkMYzuOJro4OjGfgtKqWbM64/expgVInIv8BLwC6AMGGeMOVWfFzTGOLy47CagHJeymsaYChF5HfiFiAQbY7zuDld1Kzt8GNv8l8h95x1MeTmREyYQd99MQgcN8nVoPlNSUM7qN/ex5+uTxHQM59afDySxe81J0xjD97nfV43zbji1gVJ7KUF+QVzU4SIm95rMmKQx9GzXs81+qFFKVVfbfsTdPRxeB/wXuAO4FQirvM4Y830DxjUAOGiMKXI7vgMIwure3tGAr9dmFW/bji0tjfwVK5DAQKInTyZuxnSCunb1dWg+Y4xh/3en+eqNvZQWVjBiYldGXNcV/8Dq5SnzyvJYn7He2rUoYw0nC08C0C26G1N6T2FM0hhGJI4gNKDtjacrpbxTW4t4P1DT1kwCfOF2rCGrB8QC2R6OZ7mcr0ZE7gfuB0hJ0U3Ka2KMoXDNWmxpaRStX49fZCRxs2YRe8/dBCRc2Ozflq4wp5RVi/ZwcEsmCSmR3PSTfsR3iqg6b3fY2WHbUTXJalvmNuzGTkRgBKM6juL+wfeTmpRKUkSSD9+FUqolqS0Rz2iyKBqIMeYF4AWwtkH0cTjNjqmoIG/5x9jmzaN01y4COnSg/f/+L+1un4J/RETdN2jFjDHsWnuCNW/tx17hYMwtPRlyVSf8/P04XXS6qrt53Yl15JbmIggD4gYwc9BMUpNSGZQwiEC/+s+eVkqpGhOxMSa98s8iEg2UNOG4bDbQxcPxypZwlodzqgaO4mJy3l5C1ksvUX78OEHdu9PxT38i+sYbkDawCUNdcs8U8/nC3Rzfk01Sr3Zc+oMe7Dc7eXbTm6zJWMO+7H0AxIfGM7bTWFKTUhmdNJqYkLa1flop1TjqnKwlIgGADZgMvN/oEVl2AJNFJMxtnLg/1iSx/U0UR4tWkZ1N9muvkb3wVezZ2YQOHUqHXz5OxBVXIH662bvDYdj2+THWv3sAxBB6ZS6fxLzFXz7bQHFFMYF+gQxvP5w5F80hNSmV3jG9dZKVUqrB1ZmInbOVTwH2Join0vvA74EpQDpUfSC4A1ihM6ZrV378OLYF6eS89RamuJiIceOIm3UfYRdd5OvQmo2jh0+zIn0bJRnCqfgDrEhJp7A4ly6BXZjUcxKpSalcnHgxYYFhvg5VKdXKebt8aSFwH/BhQ7yoc00yQGVmuE5EzgBnjDGrjDGbROQN4DkRCQQOArOBbsAPGyKG1qhkz15s89LIW/YhiBB9ww3E3juDkN69fR2azzmMg122Xaze/g0n1pYRe7QbZf4lbOjzAe0HhzAn+ceMSR5D58jOvg5VKdXGiIfy0dUvEpkN/BI4CbwLnMBtRrUxZr7XLypS04uuMsaMc14TCvwJq7BHO2ALVonLL7x5jREjRpgNGzZ4G1KLZYyh6Ntvsc2bR+GqL5GwMGKmTCF2+jQCO3b0dXg+lVmcaS0rOr6GvbuO0uPQJXTLHozdrxzpm8dF16dwcdfhBPrrJCulnHTsxQe8TcR1FeEwxphmtflpa0/ExuEg/9NPsaWlUbJlK/6xscROvYeYO+/Ev107X4fnE+X2cjad3sSajDWsOb6GPVl7Scnpz8UnriEhtwt+IYZ+lycy8upehEbqJDWlPNBE7APedk13a9QolNccZWXkvvsuWfPmU3boEIGdO5P4u98SPXkyfiFtb2eeI3lHqhLvNye/obiimCATzBVlN3PlofswWUFExAYzdEoK/VI7EhSidZyVUs2Lt7WmDzd2IKp29vx8ct54g6z0l6k4c4bg/v1I/vszRE6Y0KY2YSgsL+TrE19XdTkfKzgGQKeITtyUMom+p0aRvyGIopwyYpLCGT6jCz1HtMffX2eJK6Wap3r9BheRgcBYrPW8WcAXxhgtNdmIyk+fJvvll8l+/Q0cBQWEjxlN0tynCBs9uk0spXEYB7uzdlcl3s2nN1NhKggNCOWSxEuYOmAqI6JGYvvWsP2d45wqqiCpVxhX/LAvXQbGtYmfkVKqZfMqETuXDi0A7uLcMQQjIq8B040xTbm8qdUrPXiQrPnzyV36LsZuJ+raa4idOZPQAQN8HVqjsxXbWJuxtuorq8Sq39I3ti9TB0wlNSmVoe2HUpxlZ/MnR/h03RHsFQ66D0lg2ISUWjdmUEqp5sbbFvHvsPYQ/i3WUqaTQCJwt/Pc987v6gIVb9mCLW0e+StXIkFBRN92K3EzZhDUimtnlzvK2Xx6c1Wrd1fWLgBigmMYnTSa1ORUxiSNIT40HoAzR/L5/KW9HPjuNOIv9BmZyLCrU4hJDPfl21BKqfPi7azpg8BLxpgnPZz7LTDDGNOsJnS1pFnTxhgKv/oK24tpFH37LX7R0cT84C5i776bgLg4X4fXKI7mH2XtcWvHom9OfkNheSH+4s+QhCGkJqeSmpRKv7h++Ik1tmuM4djubDZ+fJhju7MJCvFnwOXJDLmyM+Htgn38bpRqNXQsxwe8bREnAWtrOLcW+FXDhNO2mPJy8j76CFvaPEr37iUgMZH2v3iMdrdNwT+idbXuisqL+Pbkt9auRRlrOZxnzf9LjkhmYreJpCalcknHS4gMijzneQ67gwObzrBpxRHOHMknLCqI0ZN7MODyZIJD284kNaVU6+Xtb7IMIBVY6eHcGOd55SVHURE5b72NbcFLVGScILhXTzo+9ReiJ05sNZswGGPYm723amnRxtMbqXBYk6xGdBjBXX3vYkzSGLpGdfU4oaqizM7udSfY9MkR8jJLaNchjCvu7kufkYke9wVWSqmWyttE/CrwK2dhj1exKmslAnditYbnNk54rUtFdjbZrywk+9VXsefmEnrRRST+5jdEjB3bKjZhyC7JZl3GuqpWb2ZxJgC9Ynpxd7+7GZM0huEdhhPsX3NXcklhOdtXHWPr58cozi+nQ7coUm/tRdch8fj5aa+ZUg1l1qxZpKWl8cgjj/Dss89WOy8iTwC/M8Y0+X88ERkHfA5cUVlNUUQeAY4YY5a4XfsE1hylQGNMRVPG6RbHi1iloJ8zxsyp13O9HCMOAF7GSryuTxBgETDNlz8AT5rTGHHZsWNkvbSAnLffxpSUEHHVVcTNnEnY8GG+Du2CVDgq2Hpma1Wrd6dtJwZDdHA0ozuenWTVPqx9nffKzyphy6dH2bE6g4pSOykD4hh+TQpJvdrpEiSlGlhxcTGJiYnk5eXRvn17jh8/ToBVj6DqP5uPE3EU1m57O40xec5jh4DVxpi73a59Ah8nYmdJ5pNAFHAaSK5PLN4W9KgAfiAifwYu4+w64i91HXHNSnbvxvZiGnnLl4OfH9E33kjczHsJ7tHD16Gdt4yCjKrE+/WJrykoL8BP/BgcP5iHhj5EalIq/eP64+/nXcVTW0YBm1ccYe83pzBArxHtGTahC/GdIhr3jSjVhi1dupS8vDwmTpzIhx9+yPLly7nhhht8HRYi4o/VQMwD1vs6nnqYhJWEPwQmAtcCH3j75BoTsYh8A6wCvgK+MsZkG2O2A9svJNrWzhhD0dffYEtLo3D1avzCwoidNo3YaVMJ7NDB1+HVW3FFMd+e/LZqadGhvEMAJIYnck3Xa0hNTmVkx5FEBUXV674Z+3PY9PFhDm2zERDkx8CxyQwZ35mouNBGeBdKKVfp6enExMSwYMECunTpQnp6uleJWEQSgH8C12NtjbsUeAdrMyDXbmQBHgEexCqRbAPeBn5Z2cJ1XmeAPwP5wANACjBCRKJx6Zp2toa7AF1EpHIHvnRjzHSX8LqJyHNYRadswDzgj8YYh/O1xjnvORm4DmubXT+sGhk/BYYDzwLDgEPAo8aYj+v8oVimAdnAdOCw8/GFJ2KsLopHnAE6RGQH8CXwBVZiPu3ti7QFxm4n/5OV2ObNo2TbNvzj40mYM4eYu+7EP6p+ScqXjDHsy9lXtbRo46mNlDnKCPYPZkTiCG7vczupSal0i+5W7y5j4zAc3JrJphVHOPl9LiHhgVxyYzcGje1ESITugKRUU8jIyGDlypXMmjWLhIQEJk2axJIlS8jOziYmJqaupy8BBgGPA/uBW4F/ebjuT85r/o21v3x/4A/AEBEZW5kcnaZj1aL4GVCINfnXvSrPZKzW5hbgCeexM27XvAO8hJVMb8Ta0/6o85ir55zv4w7gcuDXgD8wHngaOO48tkREuhhjMj3/KCwikuR87ovGmDMishS4RURijDHZtT23Uo2J2BhzsYiEY82WHovVJX0f8COsilr7sFrMX2J1UR/15gVbG0dpKblL3yVr/nzKDh8msEsKib//PdGTbsYvuGWsb80tzT07yer4Wk4XW5+xerbryZ197yQ1KZXhHYYTEnB+m0rYKxzs/eYkm1YcIftkEZFxIVx2R2/6pXYkMKhZbdqlVItWVuEgt7ichMiaf/csXLgQu93O1KlTAZg2bRqLFi3ijTfe4MEHH6zxeSIyAbgUuMMYs9h5+GMReQ+rJVt5XSxWAy7dGPOwy3VngFeAG4D3XG8NTDDGFLvco5/razv3qC8FMo0xNXVZP2OMqUy6K0XkSqxqkO6J+DNjzKPOP38iItcDDwOXGWNWO1//BFbSvx5Ir/GHYrkbK5G/7Hyc7nzdO4D/V8dzgTrGiI0xhcAK5xciEgyMwkrKl2PtFXwf1gSuNrWo056XR/ai18l65RXsmZmEDBxI8nPPEXn1eMS/eSeXCkcF2zO3VyXebZnbMBgigyLPmWSVGJ54Qa9TVlzBjq8y2PLpEQpzy4jrFMHVM/vTc3h7/HQTBqW8YncYsgrLOJNfypmCUs7kl5Lp/F75lVlgncspKqdDVDBf/3J8jfdLT0+nV69ejB49GoDx48eTlJREenp6rYkY63e/Havl6eotrBao63VBWFUYXb2OlRTHcm4iXu6ahC/AMrfH27G6md195PZ4N9C7Mgm7HAPo7MXrTgP2GWPWOR+vxGrVT6MhErE7Y0ypiKwByrH+QgS4EqufvU0oP3WKrAXp5LzxBo6iIsIvvZS4++4jbOQlzXp278nCk6w5voY1GWtYf2I9+WX5+IkfA+MH8uCQBxmTNIaB8QMJ8Lvwz1NFeWVs+ewo21cdp6y4guQ+7bhyaj86949t1j8jpZqKMYbc4vKzybSg1C3RllWdyyosxeFhcUtooD8JkcEkRAbTIyGCUd3jiI8IJjG65tbwhg0b2LlzJ4899hg5OTlVx2+55Raef/55RKS3MWZvDU/vCGQbY8rdjp9yexzr/H7C7T1XiIjN5TyerrsAWW6PSwFP3Xju3cVlQI7rAWNMmfN3Va3dgCIyAqvbfa6ItHM5tQR4uI6fZ5U6f+uKSAhW0Y7LnV8jsT7tbAdWAy9iTehq1UoPHMA2bz65778PdjtR111H3H0zCenXr+4n+0BJRQnfnfquqtV7IPcAAO3D2jM+ZTxjkscwuuNoooMbboOEnFNFbFp5hD3rTmK3O+gxLIFhE7rQoWvLGSNX6nwZYygss5PpmljdW68FpVXny+3Vs2uQvx/xEUEkRAaT3C6EoZ2jiY+wkm2C83vl4/Dg+n9oTk+3elnnzp3L3Lkeyz9MxRof9eQEECMigW7J2H0WamVCTASqVtU4l8HGUT1h1r2Gtvma5vz+mPPLXW0/zyq1zZp+CivxDsf6QX2LlXCfBta4znxrzYo2bcKWNo+CTz9FQkKIuf12YmdMJ6hTJ1+Hdg5jDN/nfs+a41YxjQ2nNlBqLyXIL4iLOlzE5F6TGZM0hp7tejZ4q/T04Tw2fnyYA5vO4O/vR5/RiQwbn0K7DmEN+jpK+UJJuf2cZFrVWi0oqdZ6LS6vvgmdn0BcxNlE2qt9ZFVL1kqsQbSPDCYhIoSo0IBG6zUqKytj0aJFjBw5kqeeeqra+Tlz5rB58+Z7ROQ3xnOBifVYY6GTgcUux6d4uK4Mq+7Epy7H78DKOV+c51soBZrNsgoRCcIaC/4a+IWHS54Favt5VqntI9X/Ys1g+w/wd2PMsfOMt8UxDgcFq1ZhS5tH8Xff4R8dTfxDDxFz9w8JiHXvVfGd3NJcvj7xtbW0KGMNJwtPAtAtuhtTek9hTNIYRiSOIDSg4f/tGmM4ujOLjSsOc3xPDkGhAQy/pguDr+hEeC1dY0o1BxV2Bza3cddqLVjn9/wSz3UZYsICq1qow1LaVWuxVn7FhAXh3wyqwi1btgybzcYzzzzDuHHjqp1/4IEHmD17dgowDmuZzzmMMSucQ5MviEg81qzp24AhzksczuuyROQZ4HERKcSa7dwP+CNWL6r7WK63dgKXicgNWMUzMo0xh87zXg3heqwW/k8rl225EpH/Av9HDT9PV7Ul4sexJmXNAH4iIntxrinGWr506DwCb9ZMeTm5y5aRNW8epfv2E5DUkQ6//CXtbrsVvzDft+7sDjs7bDuqCmpsy9yGwziIDIxkZMeRPDD4AcYkjSEpIqnRYnDYHezfeJpNK46QebSA8OggxtzSkwGXJRGkmzAoH3I4DDnnjLuWkJlf5rGbOKuoDE9tlMjggKpk2i8xist7nW21JjhbrQmRwcSGBxEU0LKmxqSnpxMZGcmUKe4NWMtdd93F7Nmzi7G6W2tKHJOxlivNxZon9B7wG6y1uLku1/0Ka3nRg8BDWOt6XwYed1u6VB+PYw2FLsZqGadjLX3ylWlY65/frOH8IuDv1P7zBLwocelcmD2UszOlLwMSsNZauSbmZlXo43xKXDqKi9l/5VUEJCQQd99Moq67Dgn07frWU4Wnqlq860+sJ7c0F0EYEDfA2i4wOZVB8YMaZJJVbcrL7Oxac4LNK4+QbyshJjGMYRNS6H2xbsKgGo8xhvzSCs/jrS6zhc/kl2IrKKPCw6ym4AC/sy3UGlqtCRHWsVBdTlfvpruIPI/VYIs1xpQ2fEitn1e1pqs9SaQvVlK+AaucF8aYZtUcOt9a02VHjxLYqZPPZveW2kvZeGpj1Qzn/Tn7AYgPjWdM0hguTb6UUR1HERNS58L7BlFSUM425yYMJQXlJHaPYtiELnQbHI80g+421TIVl9lrmC1cPdGWVlRvQAX4yTnJ9GyLNZiEyJCqx/GRwUQGN964aytU6w9KRKZjFdvYgTVp91qs2hJPG2M8jZMqL9QreToXal/u8jUUa+lS9RkKLVRQZ2+WjTUcYwyH8g5VJd4NJzdQYi8h0C+Q4e2Hc9NFNzEmaQy9Y3o36S+TPFsxW1YeZeeaDCrKHHQdFMewa7qQ1LNdk8WgWpayCge2wtrHWysnNhWUVh93FYG48KCqBNs9Ptwl0Z7beo0ODdTduHyjEKviYg8gGDgI/BJrEq86T7UmYmfpLtfE2w/rE1M5sAHrh/8l1gC88lJ+WT5fn/i6amlRRqG1nXOXqC7c0usWUpNTGdFhBGGBTT8ubTtewMYVh9n37WkE6H1JB4ZenUJcsm7C0Ba5FpNwT6rux3KK3JeXWqJDA6taqAOTo61u4Migqm7iyuQaGx5EgBZ6adaMMW9S85ioOk+1LV86AHTFSrwlWFO038JKvOsaqBJKm+AwDnbZdrH6+GrWZqxly5kt2I2d8MBwRiaOZOagmYxJGkOnSN8siTLGkLEvh40fH+HIDhsBwf4MvqITQ67qTGTs+ZW1VM1XZTGJzIJSTp/Teq1evclW4LmYRFiQf1UC7dneKiZxznirS5dxcECbH3dVqla1tYj3Y+1esQr4xkM1FVWLM0Vnzk6yylhPdqlVzKV/XH/uHXgvY5LGMKT9EAL9fDMZzDgMp4/kc3Snje83Z3LmSD6hkYGMvKkbA8d2IiRcN2FoaQorJzXVVgbRmXDL7NXHXYP8/aqSZ2Uxiaqkes547PkVk1BKeVbbpg/XNGUgLV2ZvYxNpzdVdTfvyd4DQFxIHJcmX1pVySouNM5nMRbmlnJ0ZxZHdtg4uiubkkLrs1VCSiRj7+pN39EdCdBZo82KazEJ18IRnpbm1FVMIj4ymF4dIquNtyZEBjV6MQmlVM30Y+15MsZwJP9IVSWrb05+Q3FFMQESwLAOw/jJ8J+QmpRKn9g++Ilvxr3s5Q5OHMjhyI4sjuzMwna8AIDQqCC6DIwjZUAsnfvFEhoZ5JP42qoKu4OswjKrW7iOUoh5dRSTSIg8t5iE+8Sm5lJMQilVM03E9VBYXni2ktXxNRwrsIqNdY7szE09biI1KZVLOl5CeGC4T+IzxpB7upgjO20c2ZnF8T3ZVJQ58PMXOvaIZtSk7qQMiCM+OUKXHjUw92IS1WcLn02y3haTSGhFxSSUUjXTRFwLh3GwO2t3VeLdfHozFaaC0IBQRiaOZOqAqaQmpZISlVL3zRpJWXEFx/Zkc2RnFkd32sjLLAEgKiGUfqM70nlAHMm92xEUon/V9eVaTKLGQv71KCaREhvG8C4x1Vqv7SO1mIRSbZn+dnZjK7axNmNt1VdWibVRSN/YvkwdMJVLky9laMJQAv19N8kq81gBh3fYOLozi5MHcnE4DAHB/nTqE8PQ8SmkDIglOsH3JTmbq+Iy+7kzhgtqTrR1FpOICKZ/x6hzZwu7JNoILSahlKqDJmIXJRUlTHhrAmWOMmKCYxidNJrU5FTGJI0hPjTeZ3EV5ZVx1NndfHRXFsX51iSr+M4RDL06hZT+sST2iMa/DXdXuheTqD7eenZiU32KSbiXQoyPCKadFpNQSjUgTcQuQgJCeGLME3Rv151+sf18N8mqwsHJA7kc2ZnFkZ02Mo9ak6xCIgJJ6R9LSv9YOvWLbfW7HNVWTMI90dZUTCIqJKAqiQ5Mjj5b+tClS7h9pBaTUEr5To21pkXEgfcbNpvWUmvaV3LPFFXNbj6+J5vyUjt+fkJij2g6O5NvQufIFj/JqiGKSYQG+tM+ytlarWG2cEJkMHHhQYQE6rirUvXQsn/BtFC1Jc8n8T4Rq3oqK6ng+N4cju6wupxzz1iFyiLjQug9MtFq9faJaTFbC7oWk6hxYlMdxSQqW6uVxSRcx2FdE60Wk1BKtSa1FfR4ognjaPWMsSZZHXV2N5/Yn4vDbggI8iO5TwyDr+xESv84otuHNpvJPZXFJM4pJFFDN3FRWe3FJBIig+nZPtJtvDWI9s5lOVpMQinVVmnTohEV55dxdFeWc6w3i+K8MgDikiMYcmVnOg+IJalHuybdz9dTMYmaSiHWVUwiPuLcYhLuXcNaTEIppermdSIWkSDgOqAP4L4TgDHG/KEhA2uJ7HYHp77P48hOa2nR6SP5YCAkPJDO/WLo3D+OlP6xhLdr2ElWDVVMonLpTd/EKC7r5VJIwtlqjY8MIi48WItJKKVUA/IqETu3Q1yNtRuT4eyAvuuv9DaZiPMyi60W7w4bx/dkU1ZiR/yExG5RXHJDN1IGxJGQElnv5S6uxSRqbLVqMQmllGrxvG0RPw2cwdqT+Agw0vn4XuAOYEKjRNcMlZfaOb432znWm0XOqSIAImKD6TmigzXJqm8MwWGeC34Ul9nP3dO1lu7h2opJVO7nWllMwn1ikxaTUEqplsHbRHwZ8DMgw/nYYYw5BPxWRPyBfwI3N3x4vmeMISuj0Lm0yEbG/hwcFYaAQD+Serdj4OXJdOzTjooIfzILyjiUX8q320946B4uq7WYRGzY2W7g7vHhHreeS4jUYhJKKdXaeJuI44AMY4xDRAqBGJdznwEPN3hkPlRSUM7hnTb2b80kY082Zc5KVkQHUpwSSma4H0f87ZwpyuXMmtPkfFJ7MYn4iGAGJEVV3zhdi0kopVSb520iPgZU1ng8gNUVvdL5+BKgpIHj8ony0gr++ouviC52IAjFYjgcYOdgqINDgXYKpJjQfH8SsBJqj4QIRnWP81AG0SqVqMUklFJK1cXbRPw5MBZYCvwX+LeIDAXKgWucxxqUiHQGngWuxpocthJ4xBhzpKFfq1JgcAB+UYHkdQwgJCWchM4RDIgKOaebWItJKKWUakg1lrg85yKReCDWGLPX+fjHWJO0woDlwJPGmAZrFYtIGLAFKAV+jTU7+4/O1xtsjCms6x4trcSlUko1AzoBxQe8at4ZYzKBTJfH/wL+1VhBAbOA7kAfY8x+ABHZCuwDHgD+3oivrZRSSjUZr2YIichnItK3hnO9ReSzhg2Lm4D1lUkYwBhzEFhDK52drZRSqm3ydqruOCCqhnORWOPHDWkAsN3D8R1A/wZ+LaWUUspn6rNmpqbB5B5AQQPE4ioWyPZwPItzl04ppZRSLVqNY8QiMgOY4XxogBdEJN/tslBgIPBp44RXPyJyP3A/QEpKio+jUUoppepWW4vYAdidX+L2uPLLBvwfMLOB48rGc8u3ppYyAMaYF4wxI4wxIxISEho4JKWUUqrh1bYfcTqQDiAinwOzjTG7myiuHVjjxO76AzubKAallFKq0Xk1RmyMuaIJkzDAe8AoEeleeUBEugKpznNKKaVUq+BVQQ8AERkE/A5rhnQMVhfx58AfjDHbGjQokXCsgh7FnC3o8QesGdqDjTF1Tg4TkTPA4fMMIR6XddNthL7n1q+tvV/Q91xfmcaYaxsyGFU3bytrXQyswkqM7wEngUTgRqwJW5cbY75r0MBEUji3xOWnWCUuDzXk69Tw2huMMSMa+3WaE33PrV9be7+g71m1DN4WTv4L1rreq4wxVTOnRSQSqwb0X2jgPYmdNaVvbch7KqWUUs2Nt+uIRwF/cU3CAM7Hc4HRDR2YUkop1RZ4m4jr6r/2bqC55XjB1wH4gL7n1q+tvV/Q96xaAG/HiFcC0cCVbl3T4cBnQK4xpkG7ppVSSqm2oMZELCLfA5ONMVtE5BLgC6AE+AA4gTVZayLW1oTjjDHfNknESimlVCtSW9d0VyAYwBjzDdY48WfANcCjwLVYy5dGtfQkLCKdRORfIrJORIpExDjXLbdaInKbiLwtIodFpFhE9ojIX5wT8FolEbnGuZPYSREpFZFjIrJYRNrMRiIistz57/uPvo6lMYjIOOf7c//K8XVsjU1EJorIlyJSICJ5IrJBRK70dVyqbt7OmsYYsxW4rRFj8aWewO3Ad8BXNPAM8GbqZ8AR4JfAMWAY8ARwhYiMMcY4fBhbY4nF+jv+D3AGSAF+AawXkUHGmPNdd94iiMhdwBBfx9FE/gdwbSBU+CqQpiAiDwDPO7/+gNXIGorVY6mauboScWubhFWTL40xHQBE5D7aRiK+0RhzxuXxKhHJwiprOg6r96NVMcYsAha5HhORb4DdWB8yn/FFXE1BRGKw1uXPAV7zcThNYZcxZr2vg2gKzt6754CfG2Oeczn1sS/iUfVXVyL+vYh4U6HFGGOmNURAvtBKW3+1ckvClSpbEMlNGYuP2ZzfW3WLCWuZ4XZjzCIRaQuJuC25F2tTnv/n60DU+akrEQ8FSr24T1tpObd2Y53fd/k0ikYmIv6AP9AFeAqrUtyiWp/UgonIpcBU2k63NMCrIhIP5GC1DH/hLBLUGl2K1atzp4j8Buvf9SHgWWPMv30ZmPJOXYl4knOilmrlRCQZeBJYaYzZ4Ot4GtnXwEXOP+/HWpZ32ofxNBoRCQL+C/zNGLPH1/E0gVysIYZVQB7W3IdfAutEZFgr/XtOcn49jfVeDwBTgOdFJMAY8w9fBqfq5vVkLdV6iUgE8C5W9+wMH4fTFO4BooDuWJPWPhGRS5uijrkP/C9WPfg/+TqQpmCM2QRscjm0SkS+BL7BmsD1a58E1rj8sDbEmW6MWeI89plz7PhxEfmn8XZ3H+UT3lbWUq2UiIQC72MlpWuMMcd8HFKjM8bsMsZ87Zy8dRUQgTV7ulVxbpzyK+A3QLCItBORds7TlY/9fRZgEzHGbAT2Ahf7OpZGUjnP4RO34yuADkDHpg1H1Zcm4jZMRAKBt4ARwMSG3s6yJTDG5GB1T/f0cSiNoTsQAizE2ra08gusnoBsYJBvQvOJ1toq3FHH+TY3GbWlqTERG2P8dHy49RIRP+BV4EqsuQBtYqmHOxHpAPTFGldrbTYDV3j4Ais5X4H1IaRVE5ERQB+s7unW6B3n92vcjl8LHDPGnGzieFQ96Rixk4hUFiupnMRznYicAc4YY1b5KKzG9G+sCR1/AgpFZJTLuWOtsYtaRN4BNgJbsSby9MZaV1tBK1xD7Gztf+F+XEQADhtjqp1r6UTkVeAg1t9zDtZkrceB48A/fRdZo/oQq8rhf50zxb/H+r89gbYx56PF82rTh7ZARGr6Qawyxoxryliagogcwlrm4MnvjTFPNF00TUNEHsOqoNYDCAKOYiWqv7TSiVoeOf+t/8kY0+omLonI48BdWP+2w7CWpn0E/M4Yc8KXsTUmEYnC2hf+NiAGaznTU8YYXTPeAmgiVkoppXxIJ2sppZRSPqSJWCmllPIhTcRKKaWUD2kiVkoppXxIE7FSSinlQ5qIlVJKKR/SRKx8TkSmi4gRkRznBvau5wKc557w8l63iMgpEQmrx+t/ISJf1C/q8ycih0RkgduxG0Vkm4iUON9vuxqeu8C5BtznRGSciDzhrNLmeryjiBSJyCW+ik2plkQTsWpOooHHzvfJIhKAVdTgaWNMUT2e+pDzq6lMBv5Q+cAZ96tY1Z8mAKOB/Bqe+wfn85uDccDvcPs94iyc8SLWtnxKqTpoiUvVnKwAfiwizxpjTp3H828GugLz6/MkY8zO83it8+bcqs9VMtY2douNMV/W8dyWUhP7v8AOEblEa9YrVTttEavm5I/O7+dbevE+YLkxJsv1oIj8RER2iUixiGSLyAYRmexy/pyuaWfXsKevQ273vV9Etji7kzNFZJ6IxNYVpGvXtLPLvfK+85yv84XnZ1bvmhaRrs7nPCAiT4rICWcX//si0snD6y4UkVkist8Z90YRucLtOo9d9R7i/p3zVHnlz6jyWueHm21YfydKqVpoIlbNyQngeeB+EampDrZHIhKM1VX6ldvxH2Jt6LAImAj8EGvrx9oS5mi3r1uAYmCXy32fwto4YyVwE/BzrN1uPqrnHr9pWAX6wfogMprz6yZ/HGsrx3uBnzjvs9DDdeOAR7H2Kb4TKHXG3Keer5cGzHP++VLO/qxcfUn1HYGUUm60a1o1N3OBB7BaW/fW43lDsfbe3eJ2fDSw1RjzpMuxD2u7keuWkCISirVrz3HgbuexrliJ9/eu9xWRvcBq4EZgqTdBG2OOichm58MDF7Ad5SFjzA9cYkkAnhaRJGNMhst17YHRxpijzus+BQ5j9ULc4+2LOeOu3KHra2NMhYfLNgE/8hCDUsqFtohVs+LsVn4GmFrPVlqS8/sZt+PfAkNF5F8iMr6es6kFSMfarel6Y4zNeepqrP87rzpndQc4J1x9jTXJ6vJ6xN1Q3D9cbHN+T3E7vr4yCQMYY/KBZVRvzTaEyr+LpFqvUqqN00SsmqNngSzgyboudBHi/F7qdvxlYDYwEvgYyBKRJc5WbV2eBCYBtxpj9rocb+/8vh8od/uKBOLqEXdDyXJ7XPlzCHE77mkS3CmsCWMNrdj5PbQR7q1Uq6Fd06rZMcYUiMhfsFrG3i6BqWytnrMO2Vj7fP4Xa9P0GKzlQc8Ab2AlZ49E5AdY46j3GmO+qOG1JgDZtcTSHHWo4dhxl8clQJSH6+qciFbD9Zn1fJ5SbYq2iFVz9R+s5PDHui502u383r2mC4wx2caYN4DFwMCarhOR0VhLoJ4yxizwcMkngANIMcZs8PB10MuYfWGUiHSufCAikcD1wDqXaw4DvUUkyOW6y7Fa+64qW901tXi7AWVAc/55KOVz2iJWzZIxplREngRe8PL6IyJyGLgEl9nCIvIC1rjtOuA00BtrUtIKT/cRkSisiVa7gfdFZJTL6VJjzCZjzAERmQs87xzHXoXViuyMNX6cZoz5vD7vtwmdAlY4lx+VYhVQCcelwAjwOnA/MN+5XKkb1kzrXLd7Va6//qmIfATYjTEbXM6PBL41xpQ09JtQqjXRRKyas5ewZif38vL6N7CWAv2Py7E1wAys5BsNZGAl6t9Ve7YlFmsMuD2w1u3cYayCIRhjfikiu4AfOb8McBT4FNjnZby+sAr4Avgz0AkrmV7nOgZujPlcRB4EfgbcijX7+W7gbbd7fYDVc/EQ8FtAnF+Vs82vAn7ZiO9FqVZBrCE0pVo+EekB7AHGGWNW+zqe5sZZCGS1MebuJnitO7DWGncyxri3pJVSLnSMWLUazvKPLwG/8HUsisewan5rElaqDpqIVWvzG+Db+qwXVg1LRBKBd4G/+ToWpVoC7ZpWSimlfEhbxEoppZQPaSJWSimlfEgTsVJKKeVDmoiVUkopH9JErJRSSvmQJmKllFLKh/4/K+rPmClXSLMAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# add functions to DataFrame\n",
    "df = pd.DataFrame({\"N\": range(1, 7)})\n",
    "df[\"Algorithm A\"] = df[\"N\"]\n",
    "df[\"Algorithm B\"] = df[\"N\"] + 15\n",
    "df[\"Algorithm C\"] = 3 * df[\"N\"]\n",
    "df[\"Algorithm D\"] = 5 * df[\"N\"]\n",
    "df[\"Algorithm E\"] = df[\"N\"] ** 2\n",
    "df.set_index(\"N\", inplace=True)\n",
    "\n",
    "# plot functions A to E\n",
    "ax = df.plot.line()\n",
    "ax.set_ylabel('Total Work (number of \"steps\")')\n",
    "ax.set_xlabel(\"N (size if input)\")\n",
    "\n",
    "# clean up plot...\n",
    "for label, y in df.iloc[-1].items():\n",
    "    ax.text(6.1, y, label, va=\"center\")\n",
    "ax.spines[\"top\"].set_visible(False)\n",
    "ax.spines[\"right\"].set_visible(False)\n",
    "ax.get_legend().remove()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Each function corresponds to an algorithm and tells us how many \"steps\" (defined next) the algorithm will need to perfom in order to complete a task, given an input size."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Steps\n",
    "\n",
    "In the above section, you may be wondering why you would want to classify function/algorithm A as having the same computational complexity as function/algorithm B.  Isn't B much slower because it does more steps?  Not necessarily: it turns out there's not one correct way to count steps, and it's allowed for some steps to be slower than others.  Our only restriction is as follows:\n",
    "\n",
    "**Definition:** A *step* is any unit of work with bounded execution time (it doesn't keep getting slower and slower with growing input size).\n",
    "\n",
    "For example, for a piece of code that takes the average of the odd numbers in a list, we could break it down into 4 steps as possible:\n",
    "\n",
    "<img src=\"good-steps1.png\" align=\"left\" width=400><br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "How long it takes to execute that third might depend on whether a number is even or odd, but it's *bounded*.  As the size of `input_nums` grows and grows, it won't keep getting slower and slower to execute that step once (that step will execute more times, but that's a separate point).\n",
    "\n",
    "If there are N=10 (where N is `len(input_nums)`), then a total of $1+11+10+1$ steps will execute total.  In general, $f(N) = 2*N + 3$ gives the number of steps that will executed for a given input length.\n",
    "\n",
    "Here's an example of an illegitimate way to identify steps:\n",
    "\n",
    "<img src=\"bad-steps.png\" align=\"left\" width=400>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Going back to the definition, that second box surrounds a snippet of code that keeps \"getting slower will growing input size.\"  The execution time to *run that snippet once* is not bounded, so it's not a single step.\n",
    "\n",
    "Let's consider an anthor valid way to identify steps:\n",
    "\n",
    "<img src=\"good-steps2.png\" align=\"left\" width=400>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here, the number of steps that execute depends on whether the numbers are odd or even.  If all are odd, and $N=10$, there will be $1+11+10+10+1=33$ steps.  If all are even, there will be $1+11+10+1=23$.  Unless specified otherwise, we'll be doing *worst case analysis*, so we'll go with $f(N) = 3*N + 3$.\n",
    "\n",
    "Notice that this $f(N)$ is different than the function we got when we counted steps differently in the first example ($f(N) = 3*N + 3$), even though both approaches to counting steps were legitimate.  Fortunately, it's all good, because both $f$ functions are in the $O(N)$ complexity class.\n",
    "\n",
    "Let's consider some more examples:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "nums = [1, 3, 4, 2, 5, 3, 6, 4]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# example 1: O(N)\n",
    "x = 3\n",
    "x in nums"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The above `x in nums` snippet in $O(N)$.  Even though it's one line of code, that one line is not a single step, as Python essentially loops over all numbers looking for 3.\n",
    "\n",
    "In this case, Python will quickly find 3 at index 1 and stop, but for complexity analysis, we want to think about what happens in the worst case for different `nums` lists.  The list might not even contain the number we're looking for, so Python might need to check every entry."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# example 2: O(1)\n",
    "total = 0\n",
    "for x in nums[:100]:\n",
    "    total += x\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It's not common to find loops in O(1) code, but in this case, the execution time is bounded.  After `len(nums) > 100`, the code won't keep getting slower and slower as the list grows, because it only looks at the first 100."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "duplicate!\n",
      "duplicate!\n",
      "duplicate!\n",
      "duplicate!\n"
     ]
    }
   ],
   "source": [
    "# example 3: O(N**2)\n",
    "for i in range(len(nums)):\n",
    "    for j in range(len(nums)):\n",
    "        if i != j and nums[i] == nums[j]:\n",
    "            print(\"duplicate!\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here, we're looping over every pair of numbers in the list.  If there are N numbers, there are N numbers, there are $N^2$ pairs."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "duplicate!\n",
      "duplicate!\n"
     ]
    }
   ],
   "source": [
    "# example 4: O(N**2)\n",
    "\n",
    "# part 1: filter to odd numbers\n",
    "odds = []\n",
    "for x in nums:\n",
    "    if x % 2 == 1:\n",
    "        odds.append(x)\n",
    "\n",
    "# part 2: are there any duplicates among our odd numbers?\n",
    "for i in range(len(odds)):\n",
    "    for j in range(len(odds)):\n",
    "        if i != j and odds[i] == odds[j]:\n",
    "            print(\"duplicate!\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here, we have two phases, the first of which is $O(N)$, and the second of which is $O(N^2)$.  Together, it is $O(N + N^2)$, which is actually the same as $O(N^2)$ (a better answer since it is simpler).  "
   ]
  }
 ],
 "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.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
