# Phenotyping Censored Survival Data

Author: ***Willa Potosnak***  <wpotosna@andrew.cmu.edu>

# Contents

### 1. [Introduction](#intro)
####                   1.1 [The SUPPORT Dataset](#support)
####                   1.2 [Preprocessing the Data](#preprocess)

### 2. [Intersectional Phenotyping](#interpheno)
####                    2.1 [Fitting the Intersectional Phenotyper](#fitinter)
####                    2.2 [Plotting Survival Curves](#plotpheno)

### 3. [Unsupervised Phenotyping](#clusterpheno)
####                    3.1 [Fitting the Clustering Phenotyper](#fitcluster)
####                    3.2 [Plotting Survival Curves](#clusterplot)
####                    3.3 [Evaluating Phenotype Purity](#clusterphenopur)

### 4. [Supervised Phenotyping with Deep Cox Mixtures (DCM)](#DCM)
####                   4.1 [Fitting the DCM Model](#fitDCM)
####                   4.2 [Inferring Latent Phenotypes](#latentz)
####                   4.3 [Plotting Survival Curves](#plotlatent)
####                   4.4 [Evaluating Phenotype Purity](#superphenopur)

## 1. Introduction

`auton-survival` offers utilities to phenotype, or group, samples for use in assessing differential survival probabilities across groups. Phenotyping can aid clinical decision makers by offering insight into groups of patients for which differential survival probabilities exist. This insight can influence clinical practices applied to these groups.
   * Intersectional Phenotyping
       - Identify phenotypes of samples from all possible combinations of user-specified categorical and numerical features.
   * Unsupervised Phenotyping
       - Identify phenotypes that group samples based on similarity in the feature space.
   * Supervised Phenotyping
       - Identify latent phenotypes $\mathbf{P}(Z|X=\mathbf{x})$ of samples from deep non-linear representations obtained from an encoder.
   * Counterfactual Phenotyping
       - Identify latent phenotypes $\mathbf{P}(Z|X=\mathbf{x})$ of samples that demonstrate heterogneous effects to an intervention from deep non-linear representations obtained from an encoder.

### 1.1. The SUPPORT Dataset

*For the original datasource, please refer to the following [website](https://biostat.app.vumc.org/wiki/Main/SupportDesc).*

Data features, $\mathbf{x}$, are stored in a pandas dataframe with rows corresponding to individual samples and columns as covariates. Data outcomes consists of 'time', $\mathbf{t}$, and 'event', $\mathbf{e}$, that correspond to the time to event and the censoring indicator, respectively.

```python
import pandas as pd
import sys
sys.path.append('../')

from auton_survival.datasets import load_dataset
```

### 1.2. Preprocessing the Data

```python
# Load the SUPPORT dataset
outcomes, features = load_dataset(dataset='SUPPORT')

# Identify categorical (cat_feats) and continuous (num_feats) features
cat_feats = ['sex', 'dzgroup', 'dzclass', 'income', 'race', 'ca']
num_feats = ['age', 'num.co', 'meanbp', 'wblc', 'hrt', 'resp',
             'temp', 'pafi', 'alb', 'bili', 'crea', 'sod', 'ph',
             'glucose', 'bun', 'urine', 'adlp', 'adls']

# Let's take a look at the features
display(features.head(5))

# Let's take a look at the outcomes
display(outcomes.head(5))
```

      sex
      dzgroup
      dzclass
      income
      race
      ca
      age
      num.co
      meanbp
      wblc
      ...
      alb
      bili
      crea
      sod
      ph
      glucose
      bun
      urine
      adlp
      adls

      0
      male
      Lung Cancer
      Cancer
      $11-$25k
      other
      metastatic
      62.84998
      0
      97.0
      6.000000
      ...
      1.799805
      0.199982
      1.199951
      141.0
      7.459961
      NaN
      NaN
      NaN
      7.0
      7.0

      1
      female
      Cirrhosis
      COPD/CHF/Cirrhosis
      $11-$25k
      white
      no
      60.33899
      2
      43.0
      17.097656
      ...
      NaN
      NaN
      5.500000
      132.0
      7.250000
      NaN
      NaN
      NaN
      NaN
      1.0

      2
      female
      Cirrhosis
      COPD/CHF/Cirrhosis
      under $11k
      white
      no
      52.74698
      2
      70.0
      8.500000
      ...
      NaN
      2.199707
      2.000000
      134.0
      7.459961
      NaN
      NaN
      NaN
      1.0
      0.0

      3
      female
      Lung Cancer
      Cancer
      under $11k
      white
      metastatic
      42.38498
      2
      75.0
      9.099609
      ...
      NaN
      NaN
      0.799927
      139.0
      NaN
      NaN
      NaN
      NaN
      0.0
      0.0

      4
      female
      ARF/MOSF w/Sepsis
      ARF/MOSF
      NaN
      white
      no
      79.88495
      1
      59.0
      13.500000
      ...
      NaN
      NaN
      0.799927
      143.0
      7.509766
      NaN
      NaN
      NaN
      NaN
      2.0

5 rows × 24 columns

      event
      time

      0
      0
      2029

      1
      1
      4

      2
      1
      47

      3
      1
      133

      4
      0
      2029

Here we perform imputation and scaling on the entire dataset but in practice we recommend that preprocessing tools be fitted solely to training data.

```python
from auton_survival.preprocessing import Preprocessor

preprocessor = Preprocessor(cat_feat_strat='ignore', num_feat_strat= 'mean')
x = preprocessor.fit_transform(features, cat_feats=cat_feats, num_feats=num_feats,
                                one_hot=True, fill_value=-1)
```

```python
import numpy as np
from sklearn.model_selection import train_test_split

# Split the data into train and test sets
x_tr, x_te, y_tr, y_te = train_test_split(x, outcomes, test_size=0.2, random_state=1)

print(f'Number of training data points: {len(x_tr)}')
print(f'Number of test data points: {len(x_te)}')
```

    Number of training data points: 7284
    Number of test data points: 1821

## 2. Intersectional Phenotyping

The intersectional Phenotyper performs an exhaustive cartesian product on the user-specified set of categorical and numerical variables to obtain the phenotypes. Numeric variables are binned based on user-specified quantiles.

### 2.1. Fitting the Intersectional Phenotyper

Here we fit the phenotyper on the entire dataset but in practice we recommend that the phenotyper be fitted solely to training data.

```python
from auton_survival.phenotyping import IntersectionalPhenotyper

# We create two bins based on the following quantiles of age groups
quantiles = (0, .5, 1.0)

# 'ca' is cancer status
phenotyper = IntersectionalPhenotyper(cat_vars=['ca'], num_vars=['age'],
                                        num_vars_quantiles=quantiles, random_seed=0)
phenotypes = phenotyper.fit_phenotype(features)

# Let's look at the phenotypes for each sample
phenotypes
```

    array(['ca:metastatic & age:(18.041, 64.857]',
           'ca:no & age:(18.041, 64.857]', 'ca:no & age:(18.041, 64.857]',
           ..., 'ca:no & age:(64.857, 101.848]',
           'ca:yes & age:(18.041, 64.857]', 'ca:no & age:(64.857, 101.848]'],
          dtype='<U37')

### 2.2. Plotting Survival Curves

```python
from auton_survival import reporting
import matplotlib.pyplot as plt

# Estimate the probability of event-free survival for phenotypes using the Kaplan Meier estimator.
reporting.plot_kaplanmeier(outcomes, phenotypes)

plt.xlabel('Time (Days)')
plt.ylabel('Event-Free Survival Probability')
plt.legend(loc="upper right")
plt.show()
```

As you can see, patients ages 18 to 64 without cancer have the highest survival rates. Alternatively, patients ages 64 to 101 with metastatic cancer have the lowest survival rates.

## 3. Unsupervised Phenotyping

Dimensionality reduction of the input covariates, $\mathbf{x}$, is performed followed by clustering. Learned clusters are considered phenotypes and used to group samples based on similarity in the covariate space. The estimated probability of sample cluster association is computed as the sample distance to a cluster center normalized by the sum of distances to other clusters.

\begin{align}
\mathbf{P}(Z=k | X=\mathbf{x}_i) = \frac{\mathbf{d}(x_i, x_c)}{\sum_{j=1}^{K} \mathbf{d}(x_i, x_j)}
\end{align}

Where $d_i$ is the distance to a cluster $k$ for i $\in$ \{1, 2, ..., $n$\} where $i$ $\not=$ $c$.

### 3.1. Fitting the Clustering Phenotyper

```python
from auton_survival.phenotyping import ClusteringPhenotyper

# Perform dimensionality reduction using Principal Component Analysis (PCA)
dim_red_method = 'pca'
# We use a Gaussian Mixture Model with a diagonal covariance matrix
clustering_method = 'gmm'
n_components = 8
n_clusters = 2 # Number of underlying phenotypes

# Initialize and fit the clustering phenotyper
phenotyper = ClusteringPhenotyper(clustering_method=clustering_method,
                                              dim_red_method=dim_red_method,
                                              n_components=n_components,
                                              n_clusters=n_clusters)
phenotype_probs = phenotyper.fit_phenotype(x_tr)

# Let's look at the phenotypes
phenotypes = np.argmax(phenotype_probs, axis=1)
phenotypes
```

    Fitting the following Dimensionality Reduction Model:
     PCA(n_components=8, random_state=0)
    Fitting the following Clustering Model:
     GaussianMixture(covariance_type='diag', n_components=3, random_state=0)

    array([1, 2, 1, ..., 1, 1, 2], dtype=int64)

### 3.2. Plotting Survival Curves

```python
from auton_survival import reporting
import matplotlib.pyplot as plt

# Estimate the probability of event-free survival for phenotypes using the Kaplan Meier estimator.
reporting.plot_kaplanmeier(outcomes.loc[x_tr.index], phenotypes)

plt.xlabel('Time (Days)')
plt.ylabel('Event-Free Survival Probability')
plt.xlabel('Time (Days)')
plt.legend(['Phenotype 1', 'Phenotype 2', 'Phenotype 3'], loc="upper right")
plt.show()
```

Intersecting survival rates indicate that the SUPPORT dataset follows non-proportional hazards which violates assumptions of the Cox Model.

### 3.3. Evaluating Phenotype Purity

To measure a phenotyper's ability to extract subgroups with differential survival rates, we estimate the (Integrated) Brier Score by fitting a Kaplan-Meier estimator within each phenogroup and employing it to estimate the survival rate within each phenogroup. We refer to this as the *phenotyping purity.*

```python
from auton_survival.metrics import phenotype_purity

# Estimate the Integrated Brier Score at event horizons of 1, 2 and 5 years.
metric = phenotype_purity(phenotypes_train=phenotypes, outcomes_train=y_tr,
                                phenotypes_test=None, outcomes_test=None,
                                strategy='instantaneous', horizon=[365, 730, 1825],
                                bootstrap=None)

print(f'Phenotyping purity for event horizon of 1 year: {metric[0]} | 2 years: {metric[1]} | 5 years: {metric[2]}')
```

    Phenotyping purity for event horizon of 1 year: 0.2455368004986801 | 2 years: 0.23061501456202 | 5 years: 0.18646535424261926

    C:\Users\Willa Potosnak\OneDrive\Documents\CMU Research\CMU_Projects\auton-survival\examples\..\auton_survival\metrics.py:260: UserWarning: You are are estimating survival probabilities for                     the same dataset used to estimate the censoring                     distribution.
      warnings.warn("You are are estimating survival probabilities for \
    C:\Users\Willa Potosnak\miniconda3\envs\localenv\lib\site-packages\lifelines\fitters\__init__.py:204: ApproximationWarning: Approximating using linear interpolation`.

      warnings.warn("Approximating using linear interpolation`.\n", exceptions.ApproximationWarning)

## 4. Supervised Phenotyping with Deep Cox Mixtures (DCM)

Deep Cox Mixtures (DCM) [2] generalizes the proportional hazards assumption via a mixture model, by assuming that there are latent groups and within each, the proportional hazards assumption holds. DCM allows the hazard ratio in each latent group, as well as the latent group membership, to be flexibly modeled by a deep neural network.

Figure A: DCM works by generating representation of the individual covariates, $x$, using an encoding neural network. The output representation, $xe$, then interacts with linear functions, $f$ and $g$, that determine the proportional hazards within each cluster $Z ∈ {1, 2, ...K}$ and the mixing weights $P(Z|X)$ respectively. For each cluster, baseline survival rates $Sk(t)$ are estimated non-parametrically. The final individual survival curve $S(t|x)$ is an average over the cluster specific individual survival curves weighted by the mixing probabilities $P(Z|X = x)$.

*For full details on Deep Cox Mixtures (DCM), please refer to the following paper*:

[2] [Nagpal, C., Yadlowsky, S., Rostamzadeh, N., and Heller, K. (2021c). Deep cox mixtures for survival regression. In
Machine Learning for Healthcare Conference, pages 674–708. PMLR.](https://arxiv.org/abs/2101.06536)

### 4.1. Fitting the DCM Model

Fit DCM model to training data. Perform hyperparameter tuning by selecting model parameters that minimize the brier score computed for the validation set.

$\textbf{Brier Score} \ (\textrm{BS})$: Defined as the Mean Squared Error (MSE) around the probabilistic prediction at a certain time horizon.
\begin{align}
\text{BS}(t) = \mathop{\mathbf{E}}_{x\sim\mathcal{D}}\big[ ||\mathbf{1}\{ T > t \} - \widehat{\mathbf{P}}(T>t|X)\big)||_{_\textbf{2}}^\textbf{2}  \big]
\end{align}

```python
from auton_survival.models.dcm import DeepCoxMixtures
from sklearn.model_selection import ParameterGrid
from sksurv.metrics import brier_score

param_grid = {'k' : [3],
              'learning_rate' : [1e-3],
              'layers' : [[100]]
             }

params = ParameterGrid(param_grid)

for param in params:
    model = DeepCoxMixtures(k = param['k'],
                            layers = param['layers'],
                            random_seed=0)

# The fit method is called to train the model
model.fit(x_tr.values, y_tr.time.values, y_tr.event.values, iters = 100, learning_rate = param['learning_rate'])
```

     51%|████████████████████████████████████████████████████████                                                      | 51/100 [00:40<00:38,  1.27it/s]

    <auton_survival.models.dcm.DeepCoxMixtures at 0x16a5aef3d90>

### 4.2. Inferring latent Phenotypes

The mixing probabilities $P(Z|X = x)$ estimate individual sample association to the latent phenotypes mediated by an encoder gating function
$g(.)$. $P(Z|X = x)$ is used to weight the cluster specific individual survival curves for computing the final individual survival curve $S(t|x)$.

```python
from auton_survival.models.dcm.dcm_utilities import predict_latent_z

latent_z_prob = model.predict_latent_z(x_tr.values)

# Let's look at the latent group probabilities
latent_z_prob

# Let's look at the phenotypes
phenotypes = np.argmax(latent_z_prob, axis=1)
phenotypes
```

    array([1, 1, 1, ..., 1, 2, 1], dtype=int64)

### 4.3. Plotting Survival Curves

```python
from auton_survival import reporting
import matplotlib.pyplot as plt

# Estimate the probability of event-free survival for phenotypes using the Kaplan Meier estimator.
reporting.plot_kaplanmeier(outcomes.loc[x_tr.index], phenotypes)

plt.xlabel('Time (Days)')
plt.ylabel('Event-Free Survival Probability')
plt.legend(['Phenotype 1', 'Phenotype 2', 'Phenotype 3'], loc="upper right")
plt.show()
```

Intersecting survival rates indicate that the SUPPORT dataset follows non-proportional hazards which violates assumptions of the Cox Model.

### 4.4. Evaluating Phenotype Purity

To measure a phenotyper's ability to extract subgroups with differential survival rates, we estimate the (Integrated) Brier Score by fitting a Kaplan-Meier estimator within each phenogroup and employing it to estimate the survival rate within each phenogroup. We refer to this as the *phenotyping purity.*

```python
from auton_survival.metrics import phenotype_purity

# Estimate the Integrated Brier Score at event horizons of 1, 2 and 5 years
metric = phenotype_purity(phenotypes_train=phenotypes, outcomes_train=y_tr,
                                phenotypes_test=None, outcomes_test=None,
                                strategy='instantaneous', horizon=[365, 730, 1825],
                                bootstrap=None)

print(f'Phenotyping purity for event horizon of 1 year: {metric[0]} | 2 years: {metric[1]} | 5 years: {metric[2]}')
```

    Phenotyping purity for event horizon of 1 year: 0.2089303530440138 | 2 years: 0.19797610158417195 | 5 years: 0.15850960111875823

    C:\Users\Willa Potosnak\OneDrive\Documents\CMU Research\CMU_Projects\auton-survival\examples\..\auton_survival\metrics.py:260: UserWarning: You are are estimating survival probabilities for                     the same dataset used to estimate the censoring                     distribution.
      warnings.warn("You are are estimating survival probabilities for \
    C:\Users\Willa Potosnak\miniconda3\envs\localenv\lib\site-packages\lifelines\fitters\__init__.py:204: ApproximationWarning: Approximating using linear interpolation`.

      warnings.warn("Approximating using linear interpolation`.\n", exceptions.ApproximationWarning)

It can be observed the phenotyping purity is lower for supervised phenotyping compared to unsupervised phenotyping. This indicates that the supervised phenotyper is able extract phenogroups with higher discriminative power in terms of the observed survival rates.

*IMPORTANT: Phenotype purity can only be compared between phenotypers that identify the same number of subgroups. This is because phenotypers that extract more subgroups than another will inherently have better phenotyping purity.*

## 5. Counterfactual Phenotyping

*For examples of counterfactual phenotyping with Deep Cox Mixtures with Heterogeneous Effects (CMHE) [1], please refer to the following paper and example jupyter notebook*:

[1] [Counterfactual Phenotyping with Censored Time-to-Events, arXiv preprint, C. Nagpal, M. Goswami, K. Dufendach, A. Dubrawski](https://arxiv.org/abs/2202.11089)

[Demo of CMHE on Synthetic Data.ipynb](https://github.com/autonlab/auton-survival/blob/master/examples/Demo%20of%20CMHE%20on%20Synthetic%20Data.ipynb)

```python

```


# Overview

This week we'll get started on modern network science. We'll focus on two key results that kick-started a revolution in our understanding of networks.

* Problems with random networks as models for real networks and the Watts-Strogatz model
* Scale-free networks and the Barabasi-Albert model

But before we can get started, there's the bookkeeping stuff, the admin things. Do watch it - the material below tells you about key elements of how to do well in class, assignments and stuff.

## The informal intro (not to be missed)

Today I talk about
* Recap on admin so far.
* The COVID-19 situation
* The user satisfaction questionnaire
* The assignments
* Forming groups
* Set up the peer evaluation video below

And the good news is that after today, we can take it easy with admin stuff for a while. We'll restart this aspect when we get closer to the project assignments that we finish the class with.

```python
from IPython.display import YouTubeVideo
YouTubeVideo("ASkdMRs4YH4",width=800, height=450)
```

# Part 0: The admin stuff
### (Why we use Peer Evaluations Edition)

We use the system [Peergrade.io](http://peergrade.io/) to get you better feedback and make you smarter. In the video below, I explain why that is the case. There are a lot of good reasons that peer evaluations are great, so watch the video :)

```python
YouTubeVideo("-TC18KgpiIQ",width=800, height=450)
```

# Part 1: Small world networks

Once again, we'll start with some lecturing. So it's time to watch a little video to get you started.

> **_Video Lecture_**: Some properties of real world networks. Clustering and small paths. The Watts-Strogatz model.
>

```python
YouTubeVideo("tMLJ2NYI1FU",width=800, height=450)
```

Next up is fun with reading the textbook. There's lots of goodies left in Chapter 3 that covers the stuff I've just covered in the video from a slightly different angle.
>
> *Reading*: For this part, we'll read the remaining part of *Network Science* Chapter 3, Section 3.5 - 3.10, with ***emphasis*** on 3.8 and 3.9\.
>

> *Exercises*: Did you really read the text? Answer the following questions (no calculations needed) in your IPython notebook.
>
> * What's the problem with random networks as a model for real-world networks according to the argument in section 3.5 (near the end)?
>> There is very little variation in the Poisson model. The most connected individual (the largest degree node) in a random society is expected to have $k_{max} = 1,185$ acquaintances.
The degree of the least connected individual is $k_{min} = 816$, not that different from $kmax$ or $‹k›$.

> * List the four regimes that characterize random networks as a function of $\langle k \rangle$.

>> 1. Subcritical $\langle k \rangle < 1$.
>> 1. Critical Point $\langle k \rangle = 1$.
>> 1. Supercritical $\langle k \rangle > 1$.
>> 1. Fully connect $\langle k \rangle > \log n 1$.

> * According to the book, why is it a problem for random networks (in terms of being a model for real-world networks) that the degree-dependent clustering $C(k)$ decreases as a function of $k$ in real-world networks?
>> For random networks the average clustering coefficient decreases as $N-1$. In contrast, for real networks $\langle C \rangle $ appears to be independent of N.

The next set of exercises departs from the book by presenting a little study of the Watts-Strogatz (WS) model. We're going to see just how few random links the WS model needs to dramatically shorten the path-lengths in the network. And while doing that, we'll practice using `networkx`, writing loops, and plotting nice figures.

> *Exercises*: WS edition.
>
> * First, let's use `networkx` to play around with WS graphs. Use `nx.watts_strogatz_graph` to generate 3 graphs with 500 nodes each, average degree = 4, and rewiring probablity $p = 0, 0.1, \textrm{and} 1$. Calculate the average shortest path length $\langle d \rangle$ for each one. Describe what happens to the network when $p = 1$.
> * Play around with $p$. What's the value of $p$ for which the average shortest path length gets close to the fully randomized network (i.e. when $p = 1$).
> * Let's investigate this behavior in detail. Generate 50 networks with $N = 500$, $\langle k \rangle = 4$, for each of $p = \{0, 0.01, 0.03, 0.05, 0.1, 0.2\}$. Calculate the average of $\langle d \rangle$ as well as the standard deviation over the 50 networks, to create a plot that shows how the path length decreases very quickly with only a little fraction of re-wiring. Use the standard deviation to add [errorbars](https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.pyplot.errorbar.html) to the plot. My version of the plot is below (since a picture's worth 1000 words).
>

```python
import networkx as nx
import numpy as np
import matplotlib.pyplot as plt
ws1 = nx.watts_strogatz_graph(n = 500, k = 4, p = 0)
ws2 = nx.watts_strogatz_graph(n = 500, k = 4, p = 0.1)
ws3 = nx.watts_strogatz_graph(n = 500, k = 4, p = 1)

print(nx.average_shortest_path_length(ws1))
print(nx.average_shortest_path_length(ws2))
print(nx.average_shortest_path_length(ws3))

```

    62.875751503006015
    7.655751503006012
    4.764529058116232

```python
mat = np.zeros((50, 6))
prop = [0, 0.01, 0.03, 0.05, 0.1, 0.2]

for i in range(50):
    for j, p in enumerate(prop):
        tmp = nx.watts_strogatz_graph(n = 500, k = 4, p = p)
        mat[i,j] = nx.average_shortest_path_length(tmp)

```

```python
plt.plot(prop, mu, '-o')

plt.errorbar(prop, mu, std, capsize=3)
```

### Part 2: Scale-free networks

The text book uses two whole chapters on the scale free property. We'll try and power through during the remainder of this lecture. As always, let's start by getting my take on the whole thing.

> **_Video Lecture_**: The scale free property and the Barabasi-Albert Model. Direct link [**here**](https://dtu.coursera.org/02805-001/lecture/25).
>

```python
YouTubeVideo("myLgzbXxhOQ",width=800, height=450)
```

And now it's time for you guys to read. Recall that Barabasi (who wrote the textbook) discovered power-laws.

> *Reading*: Now we dig into the extended history and and theory behind Scale-Free networks and the Barabasi-Albert Model.
>
> * Chapter 4, Section 4.1 - 4.7\.
> * Chapter 5, section 5.1 - 5.5\.
>

> *Exercises*: BA edition.
>
> First a couple of questions to make sure that you've actually read the text.
>
> * What are the three slope dependent regimes of complex networks with power-law degree distributions? Briefly describe each one. (You will have to skim chp 4.7 to answer this one).
>> 1. **Anomalous Regime:** For $\gamma < 2$ the exponent $1/(\gamma − 1)$ is larger than one. Hence the number of links connected to the largest hub grows faster than the size of the network. The degree of the largest hub must exceed the total number of nodes in the network, hence it will run out of nodes to connect to.
>> 1. **Scale Free Regime:** For $2 < \gamma < 3$ In this regime the first moment of the degree distribution is finite but the second and higher moments diverge as $N \rightarrow \infty$. Networks in this regime are ultra-samll.
>> 1. **Random Regime**: For $ \gamma > 3$. Both the first and the second moments are finite. The properties of a scale-free network in this regime are difficult to distinguish from the properties a random network of similar size. The reason is that for large $\gamma$ the degree distribution pk decays sufficiently fast to make the hubs small and less numerous.

> * What are the three regimes we find in non-linear preferential attachement? (chapter 5) Briefly describe each one.
>> 1. **Sublinear Regime $(0 < \alpha < 1)$** : The degree distribution follows the stretched exponential (5.23), resulting in fewer and smaller hubs than in a scale-free network
>> 1. **Linear Regime $(\alpha=1)$** : This corresponds to the Barabási-Albert model, hence the degree distribution follows a power law.
>> 1. **Superlinear Regime** $(α > 1)$** : The high-degree nodes are disproportionately attractive. A winner-takes-all dynamics leads to a hub-and-spoke topology. In this configuration the earliest nodes become super hubs and all subsequent nodes link to them.

> We're going to create our own Barabasi-Albert model (a special case) in right in a `notebook`. Follow the recipe below for success
>
> * First create a graph consisting of a single link. (You can call the nodes anything, but I would simply use integers as names).
> * Now add another node, connecting one of the existing nodes in proportion to their degree.
> * Keep going until you have a 100 node network.
>   * *Hint*: The difficult part here is connecting to each node according to their degree. The way I do it is: generate a list of all edges (e.g. pairs of nodes), then flatten it (e.g. remove connection information). That list contains each node in proportion to its connections, thus drawing a random node from that list (e.g. using `random.choice`) corresponds to selecting a node with probability proportional to it's degree.
> * Plot the network.
> * Add more nodes until you have a 5000 node network.
> * What's the maximum and minimum degree?
> * Now, bin the degree distribution using `numpy.histogram`.
> * Plot the distribution. Plot it with both linear and log-log axes.
>
>
>
> Next step is to explore the [Friendship paradox](https://en.wikipedia.org/wiki/Friendship_paradox). This paradox states that _almost everyone_ have fewer friends than their friends have, on average\*. This sounds crazy, but is actually an almost trivial consequence of living in a social network with a power-law degree distribution. The explanation is that almost everyone is friends with a hub, that drives up the average degree of the friends. Let's explore that in the 5000 node BA network we've just generated. Do the following:
>
> * Pick a node $i$ at random (e.g. use `random.choice`). [Find its degree](https://networkx.github.io/documentation/stable/reference/classes/generated/networkx.Graph.degree.html).
> * Find $i$'s [neighbors](https://networkx.github.io/documentation/networkx-1.10/reference/generated/networkx.Graph.neighbors.html?highlight=neighbors#networkx.Graph.neighbors). And calculate their average degree.
> * Compare the two numbers to check if it's true that $i$'s friends (on average) have more friends than $i$.
> * Do this 1000 times. How many out of those 1000 times is the friendship paradox true?
>
> Finally, we'll build a network of same size and degree, using the growth mechanism without the preferential attachment.
>
> * Compare to the ER network of same size and same $p$. What are the differences? Explain in your own words. *Hint*: To get started, take a look at the degree distribution, and study the number of connected components.
>

```python
np.random.seed(42)
G = nx.Graph()
G.add_edge(0,1)
```

```python
nodes = np.arange(2, 100)

for node in nodes:
    degrees = np.array(list(dict(G.degree).values()))
    prob = degrees/degrees.sum()
    r = np.random.choice(list(G.nodes), p = prob)
    G.add_edge(r, node)

```

```python
nx.draw_spring(
    G = G,
    node_size = 125,
    node_color = '#7FA8FF',
    node_shape = 'o',
    edge_color = 'k',
    with_labels = False,
    width = 1.3,
    edgecolors='k')
plt.draw()
```

```python
nodes = np.arange(100, 5000)

for node in nodes:
    degrees = np.array(list(dict(G.degree).values()))
    prob = degrees/degrees.sum()
    r = np.random.choice(list(G.nodes), p = prob)
    G.add_edge(r, node)

```

```python
degree = np.array(list(dict(G.degree).values()))
print(degree.min())
print(degree.max())
```

    1
    227

```python
v = np.arange(degree.min(), degree.max()+2)
hist, bin_edges = np.histogram(degree, bins = v - 1/2)

mylog = lambda x: np.log(x) if x != 0 else np.nan
vectorized_my_log = np.vectorize(mylog)

plt.figure(figsize=(12,6))
plt.subplot(1, 2, 1)
plt.scatter(v[:-1], hist, s = 10)
plt.ylabel('Count')
plt.xlabel('k')

plt.subplot(1, 2, 2)
plt.scatter(vectorized_my_log(v[:-1]), vectorized_my_log(hist), s = 10)
plt.ylabel('exp(count)')
plt.xlabel('exp(k)')
plt.show()
```

#### Friendship paradox

```python
n = 1000
num_of_friends = np.zeros(n)
num_of_friends_friends = np.zeros(n)

for i in range(n):

    r = np.random.choice(np.arange(5000))

    degree_dict = dict(G.degree)

    neighbours = [n for n in G.neighbors(r)]
    num_neighbours = len(neighbours)

    avg_freinds = np.array([degree_dict[neighbour] for neighbour in neighbours]).mean()

    num_of_friends[i] = num_neighbours
    num_of_friends_friends[i] = avg_freinds
```

```python
(num_of_friends > num_of_friends_friends).sum()
```

    102

```python

```

    24

```python
(num_of_friends < num_of_friends_friends).sum()
```

    874

### Build a network of same size and degree, using the growth mechanism without the preferential attachment.

```python
np.random.seed(123)
G = nx.Graph()
G.add_edge(0,1)

nodes = np.arange(2, 100)

for node in nodes:
    r = np.random.choice(list(G.nodes))
    G.add_edge(r, node)

nodes = np.arange(100, 5000)
for node in nodes:
    r = np.random.choice(list(G.nodes))
    G.add_edge(r, node)
```

```python
nx.draw_spring(
    G = G,
    node_size = 25,
    node_color = '#7FA8FF',
    node_shape = 'o',
    edge_color = 'k',
    with_labels = False,
    width = 1.3,
    edgecolors='k')
plt.draw()
```

```python

```

```python
n = 1000
num_of_friends = np.zeros(n)
num_of_friends_friends = np.zeros(n)

for i in range(n):

    r = np.random.choice(np.arange(5000))

    degree_dict = dict(G.degree)

    neighbours = [n for n in G.neighbors(r)]
    num_neighbours = len(neighbours)

    avg_freinds = np.array([degree_dict[neighbour] for neighbour in neighbours]).mean()

    num_of_friends[i] = num_neighbours
    num_of_friends_friends[i] = avg_freinds

print((num_of_friends > num_of_friends_friends).sum())

print((num_of_friends == num_of_friends_friends).sum())

print((num_of_friends < num_of_friends_friends).sum())
```

    245
    69
    686

\begin{align}
    \langle L \rangle &=\frac{p N(N-1)}{2} \\
    & \Updownarrow \\
    P &= \frac{2L}{(N-1)N} \\
      &= \frac{2 \cdot 4999 }{(5000-1)\cdot 5000} = 0.0004
\end{align}

```python

```

```python

```

```python

```

```python
np.array(list(dict(G_er.degree).values())).mean()
```

    2.0828

```python
np.array(list(dict(G.degree).values())).mean()
```

    1.9996

```python
G.degree
```

    DegreeView({0: 13, 1: 11, 2: 9, 3: 14, 4: 7, 5: 4, 6: 13, 7: 4, 8: 6, 9: 6, 10: 6, 11: 7, 12: 4, 13: 3, 14: 11, 15: 6, 16: 6, 17: 8, 18: 6, 19: 9, 20: 10, 21: 7, 22: 10, 23: 9, 24: 3, 25: 4, 26: 7, 27: 8, 28: 5, 29: 6, 30: 7, 31: 1, 32: 11, 33: 7, 34: 6, 35: 5, 36: 7, 37: 6, 38: 8, 39: 9, 40: 6, 41: 5, 42: 5, 43: 3, 44: 7, 45: 3, 46: 5, 47: 5, 48: 5, 49: 8, 50: 3, 51: 3, 52: 8, 53: 5, 54: 6, 55: 7, 56: 9, 57: 5, 58: 4, 59: 4, 60: 8, 61: 4, 62: 5, 63: 6, 64: 7, 65: 5, 66: 4, 67: 5, 68: 5, 69: 10, 70: 5, 71: 7, 72: 2, 73: 3, 74: 4, 75: 6, 76: 6, 77: 3, 78: 4, 79: 3, 80: 3, 81: 5, 82: 7, 83: 6, 84: 3, 85: 1, 86: 4, 87: 7, 88: 2, 89: 4, 90: 7, 91: 7, 92: 3, 93: 7, 94: 5, 95: 5, 96: 3, 97: 3, 98: 3, 99: 5, 100: 7, 101: 6, 102: 3, 103: 4, 104: 2, 105: 3, 106: 5, 107: 7, 108: 5, 109: 5, 110: 3, 111: 5, 112: 3, 113: 6, 114: 4, 115: 4, 116: 2, 117: 4, 118: 3, 119: 3, 120: 6, 121: 8, 122: 5, 123: 8, 124: 5, 125: 5, 126: 6, 127: 6, 128: 4, 129: 2, 130: 5, 131: 2, 132: 2, 133: 7, 134: 1, 135: 3, 136: 5, 137: 3, 138: 3, 139: 6, 140: 7, 141: 3, 142: 5, 143: 5, 144: 4, 145: 6, 146: 4, 147: 5, 148: 5, 149: 4, 150: 6, 151: 8, 152: 6, 153: 6, 154: 4, 155: 4, 156: 3, 157: 8, 158: 5, 159: 4, 160: 6, 161: 6, 162: 3, 163: 5, 164: 3, 165: 5, 166: 5, 167: 1, 168: 5, 169: 6, 170: 5, 171: 6, 172: 4, 173: 7, 174: 7, 175: 8, 176: 4, 177: 5, 178: 6, 179: 4, 180: 3, 181: 6, 182: 3, 183: 6, 184: 1, 185: 4, 186: 4, 187: 7, 188: 1, 189: 2, 190: 6, 191: 7, 192: 5, 193: 1, 194: 2, 195: 4, 196: 4, 197: 5, 198: 4, 199: 7, 200: 3, 201: 9, 202: 3, 203: 3, 204: 1, 205: 7, 206: 3, 207: 2, 208: 5, 209: 3, 210: 4, 211: 3, 212: 7, 213: 6, 214: 6, 215: 4, 216: 7, 217: 5, 218: 3, 219: 6, 220: 2, 221: 2, 222: 1, 223: 3, 224: 2, 225: 2, 226: 3, 227: 6, 228: 5, 229: 2, 230: 7, 231: 4, 232: 4, 233: 4, 234: 4, 235: 2, 236: 3, 237: 4, 238: 4, 239: 2, 240: 6, 241: 5, 242: 3, 243: 5, 244: 3, 245: 4, 246: 3, 247: 4, 248: 2, 249: 3, 250: 9, 251: 5, 252: 1, 253: 5, 254: 3, 255: 3, 256: 5, 257: 1, 258: 6, 259: 4, 260: 3, 261: 4, 262: 2, 263: 2, 264: 4, 265: 2, 266: 3, 267: 3, 268: 1, 269: 4, 270: 2, 271: 1, 272: 3, 273: 5, 274: 2, 275: 4, 276: 3, 277: 5, 278: 4, 279: 2, 280: 5, 281: 5, 282: 4, 283: 7, 284: 4, 285: 7, 286: 7, 287: 6, 288: 2, 289: 3, 290: 3, 291: 4, 292: 4, 293: 4, 294: 4, 295: 3, 296: 6, 297: 4, 298: 4, 299: 4, 300: 4, 301: 5, 302: 5, 303: 3, 304: 1, 305: 5, 306: 4, 307: 4, 308: 4, 309: 2, 310: 5, 311: 6, 312: 3, 313: 4, 314: 1, 315: 3, 316: 3, 317: 3, 318: 3, 319: 1, 320: 3, 321: 3, 322: 3, 323: 2, 324: 6, 325: 6, 326: 3, 327: 4, 328: 1, 329: 3, 330: 4, 331: 6, 332: 3, 333: 5, 334: 2, 335: 3, 336: 3, 337: 3, 338: 5, 339: 5, 340: 5, 341: 4, 342: 6, 343: 1, 344: 5, 345: 4, 346: 6, 347: 5, 348: 2, 349: 7, 350: 4, 351: 4, 352: 5, 353: 6, 354: 4, 355: 6, 356: 2, 357: 5, 358: 3, 359: 4, 360: 3, 361: 4, 362: 6, 363: 2, 364: 2, 365: 5, 366: 3, 367: 2, 368: 3, 369: 4, 370: 2, 371: 2, 372: 3, 373: 4, 374: 3, 375: 4, 376: 4, 377: 6, 378: 3, 379: 3, 380: 1, 381: 1, 382: 4, 383: 2, 384: 2, 385: 3, 386: 6, 387: 3, 388: 2, 389: 2, 390: 1, 391: 2, 392: 4, 393: 6, 394: 6, 395: 3, 396: 6, 397: 5, 398: 6, 399: 5, 400: 4, 401: 6, 402: 3, 403: 1, 404: 6, 405: 2, 406: 2, 407: 3, 408: 3, 409: 3, 410: 2, 411: 7, 412: 3, 413: 7, 414: 5, 415: 4, 416: 3, 417: 4, 418: 2, 419: 5, 420: 3, 421: 3, 422: 6, 423: 3, 424: 5, 425: 4, 426: 3, 427: 2, 428: 3, 429: 1, 430: 3, 431: 2, 432: 4, 433: 3, 434: 1, 435: 5, 436: 4, 437: 3, 438: 2, 439: 1, 440: 1, 441: 6, 442: 3, 443: 2, 444: 3, 445: 1, 446: 5, 447: 2, 448: 4, 449: 1, 450: 4, 451: 2, 452: 2, 453: 6, 454: 2, 455: 3, 456: 5, 457: 2, 458: 5, 459: 3, 460: 5, 461: 7, 462: 4, 463: 3, 464: 6, 465: 3, 466: 2, 467: 6, 468: 3, 469: 4, 470: 7, 471: 3, 472: 5, 473: 2, 474: 2, 475: 3, 476: 2, 477: 2, 478: 4, 479: 4, 480: 4, 481: 5, 482: 4, 483: 3, 484: 5, 485: 4, 486: 4, 487: 4, 488: 5, 489: 3, 490: 5, 491: 4, 492: 4, 493: 3, 494: 4, 495: 1, 496: 2, 497: 4, 498: 2, 499: 3, 500: 3, 501: 4, 502: 5, 503: 3, 504: 4, 505: 3, 506: 2, 507: 7, 508: 3, 509: 4, 510: 5, 511: 2, 512: 3, 513: 3, 514: 4, 515: 2, 516: 2, 517: 4, 518: 1, 519: 7, 520: 5, 521: 3, 522: 6, 523: 3, 524: 1, 525: 2, 526: 4, 527: 3, 528: 3, 529: 4, 530: 1, 531: 4, 532: 3, 533: 3, 534: 4, 535: 5, 536: 6, 537: 1, 538: 3, 539: 4, 540: 1, 541: 2, 542: 5, 543: 2, 544: 3, 545: 3, 546: 2, 547: 1, 548: 5, 549: 1, 550: 2, 551: 5, 552: 3, 553: 2, 554: 2, 555: 4, 556: 1, 557: 1, 558: 1, 559: 2, 560: 4, 561: 6, 562: 5, 563: 1, 564: 4, 565: 2, 566: 4, 567: 2, 568: 4, 569: 1, 570: 8, 571: 4, 572: 2, 573: 4, 574: 2, 575: 4, 576: 1, 577: 3, 578: 4, 579: 5, 580: 3, 581: 2, 582: 2, 583: 2, 584: 4, 585: 3, 586: 3, 587: 6, 588: 1, 589: 3, 590: 2, 591: 3, 592: 6, 593: 3, 594: 1, 595: 2, 596: 2, 597: 3, 598: 2, 599: 4, 600: 3, 601: 2, 602: 1, 603: 5, 604: 4, 605: 1, 606: 2, 607: 2, 608: 3, 609: 2, 610: 6, 611: 1, 612: 6, 613: 1, 614: 2, 615: 3, 616: 5, 617: 3, 618: 2, 619: 5, 620: 2, 621: 3, 622: 5, 623: 4, 624: 4, 625: 1, 626: 2, 627: 2, 628: 3, 629: 1, 630: 4, 631: 4, 632: 3, 633: 2, 634: 5, 635: 6, 636: 5, 637: 5, 638: 3, 639: 3, 640: 2, 641: 2, 642: 4, 643: 3, 644: 3, 645: 4, 646: 2, 647: 1, 648: 5, 649: 2, 650: 5, 651: 4, 652: 6, 653: 3, 654: 3, 655: 1, 656: 2, 657: 3, 658: 1, 659: 6, 660: 5, 661: 2, 662: 2, 663: 2, 664: 3, 665: 5, 666: 4, 667: 2, 668: 2, 669: 6, 670: 2, 671: 2, 672: 1, 673: 2, 674: 3, 675: 4, 676: 3, 677: 3, 678: 4, 679: 3, 680: 1, 681: 2, 682: 2, 683: 5, 684: 3, 685: 4, 686: 5, 687: 2, 688: 2, 689: 1, 690: 4, 691: 5, 692: 3, 693: 3, 694: 3, 695: 2, 696: 4, 697: 2, 698: 3, 699: 2, 700: 5, 701: 2, 702: 4, 703: 2, 704: 2, 705: 3, 706: 2, 707: 3, 708: 4, 709: 2, 710: 5, 711: 3, 712: 2, 713: 3, 714: 2, 715: 3, 716: 4, 717: 3, 718: 5, 719: 4, 720: 3, 721: 4, 722: 2, 723: 1, 724: 3, 725: 6, 726: 3, 727: 4, 728: 6, 729: 2, 730: 1, 731: 2, 732: 2, 733: 4, 734: 3, 735: 1, 736: 2, 737: 7, 738: 2, 739: 2, 740: 5, 741: 5, 742: 1, 743: 1, 744: 2, 745: 2, 746: 1, 747: 6, 748: 1, 749: 2, 750: 2, 751: 4, 752: 2, 753: 4, 754: 3, 755: 4, 756: 3, 757: 1, 758: 2, 759: 4, 760: 3, 761: 2, 762: 4, 763: 4, 764: 4, 765: 2, 766: 3, 767: 2, 768: 3, 769: 2, 770: 3, 771: 4, 772: 6, 773: 2, 774: 2, 775: 1, 776: 3, 777: 2, 778: 4, 779: 3, 780: 2, 781: 5, 782: 4, 783: 2, 784: 2, 785: 2, 786: 4, 787: 4, 788: 2, 789: 3, 790: 2, 791: 3, 792: 2, 793: 3, 794: 5, 795: 5, 796: 3, 797: 2, 798: 3, 799: 1, 800: 3, 801: 3, 802: 4, 803: 1, 804: 1, 805: 1, 806: 5, 807: 3, 808: 1, 809: 2, 810: 1, 811: 3, 812: 1, 813: 2, 814: 2, 815: 2, 816: 4, 817: 2, 818: 5, 819: 2, 820: 1, 821: 2, 822: 1, 823: 1, 824: 3, 825: 2, 826: 3, 827: 3, 828: 4, 829: 3, 830: 5, 831: 3, 832: 3, 833: 2, 834: 3, 835: 1, 836: 4, 837: 1, 838: 3, 839: 5, 840: 3, 841: 2, 842: 4, 843: 1, 844: 2, 845: 1, 846: 2, 847: 2, 848: 2, 849: 1, 850: 4, 851: 3, 852: 2, 853: 2, 854: 3, 855: 3, 856: 2, 857: 5, 858: 5, 859: 5, 860: 4, 861: 4, 862: 1, 863: 4, 864: 2, 865: 4, 866: 4, 867: 4, 868: 2, 869: 1, 870: 6, 871: 3, 872: 1, 873: 4, 874: 4, 875: 3, 876: 4, 877: 4, 878: 4, 879: 3, 880: 2, 881: 4, 882: 1, 883: 5, 884: 2, 885: 3, 886: 4, 887: 7, 888: 2, 889: 1, 890: 2, 891: 2, 892: 4, 893: 2, 894: 3, 895: 4, 896: 2, 897: 1, 898: 4, 899: 4, 900: 3, 901: 2, 902: 1, 903: 2, 904: 2, 905: 1, 906: 2, 907: 1, 908: 1, 909: 2, 910: 4, 911: 4, 912: 3, 913: 3, 914: 3, 915: 2, 916: 2, 917: 3, 918: 2, 919: 2, 920: 1, 921: 4, 922: 1, 923: 1, 924: 3, 925: 1, 926: 3, 927: 3, 928: 3, 929: 6, 930: 1, 931: 3, 932: 5, 933: 2, 934: 2, 935: 1, 936: 3, 937: 2, 938: 3, 939: 2, 940: 3, 941: 2, 942: 2, 943: 3, 944: 4, 945: 3, 946: 3, 947: 5, 948: 4, 949: 2, 950: 1, 951: 3, 952: 2, 953: 6, 954: 2, 955: 4, 956: 4, 957: 4, 958: 2, 959: 5, 960: 5, 961: 3, 962: 3, 963: 3, 964: 2, 965: 5, 966: 1, 967: 1, 968: 3, 969: 1, 970: 2, 971: 3, 972: 2, 973: 1, 974: 2, 975: 2, 976: 1, 977: 2, 978: 4, 979: 4, 980: 5, 981: 2, 982: 3, 983: 5, 984: 1, 985: 3, 986: 5, 987: 2, 988: 2, 989: 1, 990: 2, 991: 2, 992: 3, 993: 1, 994: 1, 995: 1, 996: 3, 997: 2, 998: 3, 999: 3, 1000: 3, 1001: 2, 1002: 1, 1003: 1, 1004: 1, 1005: 2, 1006: 2, 1007: 3, 1008: 3, 1009: 4, 1010: 3, 1011: 3, 1012: 1, 1013: 3, 1014: 5, 1015: 2, 1016: 3, 1017: 3, 1018: 3, 1019: 3, 1020: 2, 1021: 3, 1022: 4, 1023: 3, 1024: 2, 1025: 2, 1026: 4, 1027: 1, 1028: 3, 1029: 2, 1030: 4, 1031: 3, 1032: 4, 1033: 3, 1034: 2, 1035: 1, 1036: 2, 1037: 3, 1038: 3, 1039: 4, 1040: 3, 1041: 4, 1042: 3, 1043: 2, 1044: 2, 1045: 3, 1046: 2, 1047: 4, 1048: 2, 1049: 3, 1050: 2, 1051: 3, 1052: 3, 1053: 5, 1054: 2, 1055: 2, 1056: 2, 1057: 1, 1058: 3, 1059: 3, 1060: 2, 1061: 3, 1062: 3, 1063: 3, 1064: 2, 1065: 1, 1066: 1, 1067: 1, 1068: 3, 1069: 2, 1070: 4, 1071: 1, 1072: 3, 1073: 2, 1074: 1, 1075: 3, 1076: 2, 1077: 3, 1078: 4, 1079: 2, 1080: 5, 1081: 3, 1082: 2, 1083: 2, 1084: 2, 1085: 2, 1086: 3, 1087: 2, 1088: 1, 1089: 4, 1090: 3, 1091: 1, 1092: 2, 1093: 3, 1094: 2, 1095: 4, 1096: 3, 1097: 5, 1098: 5, 1099: 2, 1100: 3, 1101: 3, 1102: 1, 1103: 1, 1104: 3, 1105: 4, 1106: 3, 1107: 2, 1108: 3, 1109: 2, 1110: 6, 1111: 2, 1112: 1, 1113: 3, 1114: 3, 1115: 1, 1116: 3, 1117: 2, 1118: 4, 1119: 2, 1120: 3, 1121: 1, 1122: 4, 1123: 1, 1124: 3, 1125: 2, 1126: 2, 1127: 1, 1128: 4, 1129: 3, 1130: 4, 1131: 4, 1132: 2, 1133: 3, 1134: 4, 1135: 2, 1136: 3, 1137: 2, 1138: 2, 1139: 3, 1140: 1, 1141: 3, 1142: 3, 1143: 2, 1144: 2, 1145: 1, 1146: 2, 1147: 3, 1148: 3, 1149: 3, 1150: 1, 1151: 1, 1152: 2, 1153: 2, 1154: 3, 1155: 3, 1156: 2, 1157: 2, 1158: 8, 1159: 2, 1160: 3, 1161: 1, 1162: 1, 1163: 2, 1164: 3, 1165: 2, 1166: 2, 1167: 3, 1168: 3, 1169: 2, 1170: 2, 1171: 3, 1172: 1, 1173: 1, 1174: 3, 1175: 2, 1176: 2, 1177: 3, 1178: 4, 1179: 1, 1180: 4, 1181: 3, 1182: 2, 1183: 2, 1184: 3, 1185: 2, 1186: 2, 1187: 3, 1188: 3, 1189: 1, 1190: 1, 1191: 3, 1192: 1, 1193: 2, 1194: 2, 1195: 4, 1196: 2, 1197: 5, 1198: 1, 1199: 2, 1200: 4, 1201: 2, 1202: 3, 1203: 2, 1204: 1, 1205: 3, 1206: 1, 1207: 2, 1208: 2, 1209: 3, 1210: 3, 1211: 1, 1212: 4, 1213: 1, 1214: 3, 1215: 3, 1216: 4, 1217: 2, 1218: 4, 1219: 5, 1220: 2, 1221: 1, 1222: 3, 1223: 3, 1224: 4, 1225: 3, 1226: 2, 1227: 4, 1228: 4, 1229: 2, 1230: 2, 1231: 2, 1232: 2, 1233: 4, 1234: 1, 1235: 4, 1236: 2, 1237: 2, 1238: 4, 1239: 1, 1240: 5, 1241: 1, 1242: 3, 1243: 1, 1244: 1, 1245: 5, 1246: 1, 1247: 2, 1248: 2, 1249: 3, 1250: 2, 1251: 2, 1252: 3, 1253: 2, 1254: 1, 1255: 3, 1256: 2, 1257: 4, 1258: 4, 1259: 4, 1260: 2, 1261: 4, 1262: 3, 1263: 1, 1264: 3, 1265: 5, 1266: 1, 1267: 1, 1268: 1, 1269: 2, 1270: 4, 1271: 1, 1272: 4, 1273: 3, 1274: 4, 1275: 3, 1276: 5, 1277: 1, 1278: 2, 1279: 2, 1280: 1, 1281: 3, 1282: 3, 1283: 1, 1284: 2, 1285: 2, 1286: 3, 1287: 1, 1288: 3, 1289: 5, 1290: 2, 1291: 2, 1292: 2, 1293: 3, 1294: 2, 1295: 1, 1296: 2, 1297: 1, 1298: 2, 1299: 2, 1300: 2, 1301: 3, 1302: 2, 1303: 2, 1304: 2, 1305: 3, 1306: 3, 1307: 2, 1308: 2, 1309: 1, 1310: 2, 1311: 1, 1312: 2, 1313: 1, 1314: 1, 1315: 3, 1316: 2, 1317: 1, 1318: 1, 1319: 4, 1320: 2, 1321: 1, 1322: 5, 1323: 1, 1324: 3, 1325: 1, 1326: 2, 1327: 3, 1328: 2, 1329: 3, 1330: 3, 1331: 4, 1332: 5, 1333: 4, 1334: 3, 1335: 1, 1336: 2, 1337: 3, 1338: 3, 1339: 1, 1340: 1, 1341: 5, 1342: 4, 1343: 1, 1344: 2, 1345: 3, 1346: 2, 1347: 2, 1348: 1, 1349: 1, 1350: 2, 1351: 1, 1352: 2, 1353: 4, 1354: 1, 1355: 2, 1356: 3, 1357: 1, 1358: 3, 1359: 3, 1360: 1, 1361: 3, 1362: 1, 1363: 1, 1364: 2, 1365: 1, 1366: 1, 1367: 2, 1368: 5, 1369: 1, 1370: 1, 1371: 2, 1372: 3, 1373: 1, 1374: 3, 1375: 2, 1376: 2, 1377: 2, 1378: 4, 1379: 2, 1380: 5, 1381: 3, 1382: 3, 1383: 4, 1384: 1, 1385: 1, 1386: 3, 1387: 3, 1388: 1, 1389: 2, 1390: 2, 1391: 4, 1392: 2, 1393: 4, 1394: 2, 1395: 2, 1396: 2, 1397: 3, 1398: 4, 1399: 2, 1400: 2, 1401: 2, 1402: 3, 1403: 5, 1404: 1, 1405: 1, 1406: 2, 1407: 2, 1408: 4, 1409: 1, 1410: 3, 1411: 2, 1412: 2, 1413: 2, 1414: 2, 1415: 4, 1416: 2, 1417: 1, 1418: 3, 1419: 2, 1420: 1, 1421: 1, 1422: 2, 1423: 4, 1424: 2, 1425: 2, 1426: 2, 1427: 4, 1428: 4, 1429: 2, 1430: 1, 1431: 4, 1432: 2, 1433: 3, 1434: 1, 1435: 1, 1436: 1, 1437: 4, 1438: 2, 1439: 1, 1440: 3, 1441: 2, 1442: 2, 1443: 3, 1444: 2, 1445: 1, 1446: 2, 1447: 3, 1448: 1, 1449: 1, 1450: 2, 1451: 1, 1452: 2, 1453: 3, 1454: 4, 1455: 2, 1456: 4, 1457: 4, 1458: 1, 1459: 1, 1460: 2, 1461: 3, 1462: 1, 1463: 2, 1464: 1, 1465: 1, 1466: 2, 1467: 3, 1468: 2, 1469: 1, 1470: 3, 1471: 3, 1472: 2, 1473: 1, 1474: 1, 1475: 2, 1476: 1, 1477: 2, 1478: 2, 1479: 2, 1480: 2, 1481: 2, 1482: 3, 1483: 2, 1484: 3, 1485: 1, 1486: 2, 1487: 2, 1488: 2, 1489: 2, 1490: 1, 1491: 1, 1492: 3, 1493: 3, 1494: 4, 1495: 2, 1496: 3, 1497: 2, 1498: 4, 1499: 1, 1500: 1, 1501: 3, 1502: 2, 1503: 2, 1504: 1, 1505: 3, 1506: 5, 1507: 2, 1508: 1, 1509: 1, 1510: 4, 1511: 2, 1512: 4, 1513: 2, 1514: 2, 1515: 1, 1516: 2, 1517: 1, 1518: 1, 1519: 1, 1520: 2, 1521: 4, 1522: 2, 1523: 2, 1524: 2, 1525: 1, 1526: 2, 1527: 4, 1528: 4, 1529: 5, 1530: 3, 1531: 2, 1532: 3, 1533: 1, 1534: 4, 1535: 1, 1536: 4, 1537: 3, 1538: 1, 1539: 2, 1540: 3, 1541: 3, 1542: 1, 1543: 2, 1544: 2, 1545: 2, 1546: 3, 1547: 4, 1548: 2, 1549: 4, 1550: 3, 1551: 1, 1552: 4, 1553: 1, 1554: 1, 1555: 1, 1556: 1, 1557: 2, 1558: 1, 1559: 3, 1560: 1, 1561: 3, 1562: 1, 1563: 2, 1564: 2, 1565: 1, 1566: 4, 1567: 1, 1568: 2, 1569: 1, 1570: 3, 1571: 2, 1572: 1, 1573: 2, 1574: 2, 1575: 2, 1576: 1, 1577: 1, 1578: 1, 1579: 1, 1580: 2, 1581: 1, 1582: 1, 1583: 1, 1584: 2, 1585: 2, 1586: 3, 1587: 4, 1588: 3, 1589: 1, 1590: 1, 1591: 1, 1592: 3, 1593: 1, 1594: 1, 1595: 1, 1596: 3, 1597: 3, 1598: 4, 1599: 1, 1600: 1, 1601: 1, 1602: 1, 1603: 2, 1604: 5, 1605: 3, 1606: 4, 1607: 2, 1608: 5, 1609: 6, 1610: 2, 1611: 3, 1612: 2, 1613: 2, 1614: 1, 1615: 2, 1616: 3, 1617: 3, 1618: 2, 1619: 3, 1620: 2, 1621: 1, 1622: 5, 1623: 2, 1624: 3, 1625: 3, 1626: 2, 1627: 1, 1628: 1, 1629: 2, 1630: 2, 1631: 4, 1632: 4, 1633: 1, 1634: 4, 1635: 2, 1636: 2, 1637: 1, 1638: 1, 1639: 3, 1640: 2, 1641: 1, 1642: 2, 1643: 2, 1644: 2, 1645: 2, 1646: 3, 1647: 2, 1648: 2, 1649: 1, 1650: 2, 1651: 3, 1652: 2, 1653: 2, 1654: 1, 1655: 3, 1656: 3, 1657: 4, 1658: 1, 1659: 2, 1660: 2, 1661: 1, 1662: 2, 1663: 4, 1664: 2, 1665: 1, 1666: 2, 1667: 2, 1668: 2, 1669: 2, 1670: 2, 1671: 1, 1672: 1, 1673: 1, 1674: 3, 1675: 2, 1676: 2, 1677: 2, 1678: 2, 1679: 1, 1680: 2, 1681: 2, 1682: 1, 1683: 2, 1684: 2, 1685: 2, 1686: 2, 1687: 1, 1688: 3, 1689: 5, 1690: 2, 1691: 2, 1692: 1, 1693: 2, 1694: 2, 1695: 3, 1696: 3, 1697: 1, 1698: 4, 1699: 2, 1700: 3, 1701: 2, 1702: 1, 1703: 1, 1704: 2, 1705: 2, 1706: 3, 1707: 2, 1708: 2, 1709: 4, 1710: 2, 1711: 2, 1712: 2, 1713: 4, 1714: 4, 1715: 2, 1716: 1, 1717: 1, 1718: 1, 1719: 1, 1720: 3, 1721: 2, 1722: 3, 1723: 1, 1724: 4, 1725: 3, 1726: 2, 1727: 2, 1728: 4, 1729: 2, 1730: 3, 1731: 2, 1732: 3, 1733: 1, 1734: 1, 1735: 3, 1736: 2, 1737: 2, 1738: 1, 1739: 4, 1740: 4, 1741: 2, 1742: 1, 1743: 1, 1744: 2, 1745: 2, 1746: 2, 1747: 1, 1748: 2, 1749: 2, 1750: 2, 1751: 3, 1752: 4, 1753: 2, 1754: 2, 1755: 2, 1756: 1, 1757: 3, 1758: 2, 1759: 1, 1760: 2, 1761: 5, 1762: 1, 1763: 1, 1764: 2, 1765: 1, 1766: 2, 1767: 1, 1768: 2, 1769: 1, 1770: 2, 1771: 2, 1772: 1, 1773: 3, 1774: 2, 1775: 2, 1776: 3, 1777: 1, 1778: 1, 1779: 2, 1780: 2, 1781: 3, 1782: 2, 1783: 3, 1784: 4, 1785: 2, 1786: 2, 1787: 1, 1788: 2, 1789: 3, 1790: 4, 1791: 1, 1792: 2, 1793: 1, 1794: 2, 1795: 1, 1796: 1, 1797: 2, 1798: 1, 1799: 1, 1800: 1, 1801: 2, 1802: 1, 1803: 1, 1804: 4, 1805: 3, 1806: 1, 1807: 2, 1808: 2, 1809: 3, 1810: 2, 1811: 1, 1812: 2, 1813: 1, 1814: 1, 1815: 3, 1816: 3, 1817: 3, 1818: 1, 1819: 3, 1820: 2, 1821: 2, 1822: 1, 1823: 4, 1824: 2, 1825: 1, 1826: 1, 1827: 2, 1828: 1, 1829: 2, 1830: 2, 1831: 1, 1832: 4, 1833: 3, 1834: 2, 1835: 1, 1836: 2, 1837: 2, 1838: 1, 1839: 1, 1840: 2, 1841: 1, 1842: 3, 1843: 1, 1844: 4, 1845: 3, 1846: 1, 1847: 2, 1848: 2, 1849: 2, 1850: 2, 1851: 3, 1852: 1, 1853: 3, 1854: 1, 1855: 2, 1856: 2, 1857: 3, 1858: 3, 1859: 1, 1860: 2, 1861: 2, 1862: 2, 1863: 2, 1864: 4, 1865: 3, 1866: 4, 1867: 2, 1868: 1, 1869: 3, 1870: 1, 1871: 1, 1872: 3, 1873: 2, 1874: 3, 1875: 4, 1876: 4, 1877: 1, 1878: 3, 1879: 1, 1880: 2, 1881: 2, 1882: 1, 1883: 3, 1884: 2, 1885: 3, 1886: 3, 1887: 1, 1888: 1, 1889: 1, 1890: 2, 1891: 1, 1892: 1, 1893: 1, 1894: 1, 1895: 1, 1896: 1, 1897: 1, 1898: 1, 1899: 1, 1900: 2, 1901: 3, 1902: 2, 1903: 5, 1904: 1, 1905: 3, 1906: 1, 1907: 1, 1908: 1, 1909: 1, 1910: 2, 1911: 3, 1912: 2, 1913: 2, 1914: 4, 1915: 1, 1916: 2, 1917: 1, 1918: 2, 1919: 3, 1920: 2, 1921: 3, 1922: 2, 1923: 3, 1924: 3, 1925: 2, 1926: 1, 1927: 1, 1928: 1, 1929: 1, 1930: 3, 1931: 2, 1932: 2, 1933: 4, 1934: 1, 1935: 3, 1936: 3, 1937: 2, 1938: 3, 1939: 3, 1940: 2, 1941: 1, 1942: 2, 1943: 5, 1944: 1, 1945: 2, 1946: 2, 1947: 3, 1948: 2, 1949: 3, 1950: 2, 1951: 3, 1952: 2, 1953: 2, 1954: 1, 1955: 2, 1956: 1, 1957: 1, 1958: 3, 1959: 1, 1960: 2, 1961: 3, 1962: 2, 1963: 1, 1964: 1, 1965: 1, 1966: 4, 1967: 1, 1968: 2, 1969: 2, 1970: 2, 1971: 1, 1972: 2, 1973: 1, 1974: 1, 1975: 1, 1976: 2, 1977: 2, 1978: 1, 1979: 1, 1980: 1, 1981: 1, 1982: 2, 1983: 4, 1984: 1, 1985: 2, 1986: 1, 1987: 1, 1988: 2, 1989: 2, 1990: 4, 1991: 2, 1992: 2, 1993: 3, 1994: 5, 1995: 2, 1996: 2, 1997: 3, 1998: 3, 1999: 1, 2000: 1, 2001: 1, 2002: 3, 2003: 2, 2004: 4, 2005: 2, 2006: 1, 2007: 2, 2008: 1, 2009: 1, 2010: 2, 2011: 1, 2012: 2, 2013: 1, 2014: 1, 2015: 1, 2016: 4, 2017: 1, 2018: 1, 2019: 1, 2020: 1, 2021: 3, 2022: 1, 2023: 3, 2024: 1, 2025: 1, 2026: 1, 2027: 2, 2028: 2, 2029: 2, 2030: 1, 2031: 3, 2032: 2, 2033: 4, 2034: 1, 2035: 3, 2036: 2, 2037: 1, 2038: 4, 2039: 3, 2040: 1, 2041: 4, 2042: 3, 2043: 2, 2044: 1, 2045: 2, 2046: 2, 2047: 4, 2048: 2, 2049: 2, 2050: 2, 2051: 1, 2052: 3, 2053: 2, 2054: 1, 2055: 2, 2056: 1, 2057: 3, 2058: 3, 2059: 2, 2060: 1, 2061: 2, 2062: 2, 2063: 1, 2064: 1, 2065: 1, 2066: 2, 2067: 2, 2068: 4, 2069: 1, 2070: 1, 2071: 4, 2072: 2, 2073: 2, 2074: 1, 2075: 1, 2076: 2, 2077: 2, 2078: 1, 2079: 2, 2080: 1, 2081: 2, 2082: 1, 2083: 1, 2084: 3, 2085: 1, 2086: 1, 2087: 2, 2088: 2, 2089: 3, 2090: 3, 2091: 1, 2092: 1, 2093: 2, 2094: 3, 2095: 1, 2096: 1, 2097: 2, 2098: 2, 2099: 3, 2100: 1, 2101: 1, 2102: 1, 2103: 1, 2104: 2, 2105: 1, 2106: 3, 2107: 2, 2108: 1, 2109: 1, 2110: 5, 2111: 1, 2112: 2, 2113: 3, 2114: 2, 2115: 1, 2116: 2, 2117: 1, 2118: 3, 2119: 1, 2120: 1, 2121: 1, 2122: 1, 2123: 1, 2124: 2, 2125: 1, 2126: 1, 2127: 2, 2128: 2, 2129: 1, 2130: 2, 2131: 1, 2132: 1, 2133: 2, 2134: 2, 2135: 2, 2136: 4, 2137: 2, 2138: 2, 2139: 1, 2140: 1, 2141: 3, 2142: 3, 2143: 1, 2144: 1, 2145: 1, 2146: 2, 2147: 2, 2148: 1, 2149: 1, 2150: 2, 2151: 2, 2152: 2, 2153: 2, 2154: 1, 2155: 1, 2156: 1, 2157: 1, 2158: 1, 2159: 1, 2160: 3, 2161: 2, 2162: 4, 2163: 1, 2164: 4, 2165: 1, 2166: 2, 2167: 1, 2168: 1, 2169: 1, 2170: 2, 2171: 3, 2172: 2, 2173: 2, 2174: 1, 2175: 4, 2176: 1, 2177: 4, 2178: 4, 2179: 1, 2180: 3, 2181: 1, 2182: 2, 2183: 1, 2184: 1, 2185: 2, 2186: 1, 2187: 3, 2188: 2, 2189: 1, 2190: 2, 2191: 2, 2192: 2, 2193: 2, 2194: 1, 2195: 3, 2196: 1, 2197: 1, 2198: 2, 2199: 1, 2200: 1, 2201: 4, 2202: 1, 2203: 1, 2204: 1, 2205: 2, 2206: 1, 2207: 1, 2208: 2, 2209: 3, 2210: 1, 2211: 1, 2212: 1, 2213: 1, 2214: 4, 2215: 2, 2216: 2, 2217: 2, 2218: 1, 2219: 3, 2220: 2, 2221: 2, 2222: 2, 2223: 1, 2224: 2, 2225: 1, 2226: 4, 2227: 1, 2228: 3, 2229: 3, 2230: 6, 2231: 2, 2232: 2, 2233: 1, 2234: 2, 2235: 3, 2236: 1, 2237: 2, 2238: 1, 2239: 2, 2240: 1, 2241: 3, 2242: 2, 2243: 1, 2244: 2, 2245: 2, 2246: 1, 2247: 1, 2248: 1, 2249: 1, 2250: 2, 2251: 2, 2252: 1, 2253: 1, 2254: 1, 2255: 2, 2256: 3, 2257: 2, 2258: 2, 2259: 2, 2260: 1, 2261: 1, 2262: 2, 2263: 1, 2264: 2, 2265: 2, 2266: 1, 2267: 2, 2268: 2, 2269: 1, 2270: 1, 2271: 3, 2272: 2, 2273: 1, 2274: 2, 2275: 1, 2276: 2, 2277: 2, 2278: 2, 2279: 1, 2280: 1, 2281: 3, 2282: 2, 2283: 1, 2284: 1, 2285: 1, 2286: 3, 2287: 2, 2288: 1, 2289: 1, 2290: 2, 2291: 3, 2292: 1, 2293: 2, 2294: 3, 2295: 1, 2296: 1, 2297: 3, 2298: 4, 2299: 1, 2300: 2, 2301: 1, 2302: 2, 2303: 1, 2304: 1, 2305: 2, 2306: 1, 2307: 1, 2308: 1, 2309: 1, 2310: 1, 2311: 2, 2312: 1, 2313: 2, 2314: 1, 2315: 1, 2316: 2, 2317: 2, 2318: 1, 2319: 1, 2320: 2, 2321: 2, 2322: 3, 2323: 1, 2324: 1, 2325: 1, 2326: 3, 2327: 1, 2328: 3, 2329: 2, 2330: 2, 2331: 2, 2332: 3, 2333: 1, 2334: 2, 2335: 2, 2336: 2, 2337: 3, 2338: 1, 2339: 3, 2340: 4, 2341: 1, 2342: 2, 2343: 2, 2344: 2, 2345: 2, 2346: 1, 2347: 2, 2348: 3, 2349: 3, 2350: 1, 2351: 1, 2352: 2, 2353: 2, 2354: 1, 2355: 1, 2356: 4, 2357: 1, 2358: 3, 2359: 1, 2360: 2, 2361: 2, 2362: 2, 2363: 2, 2364: 1, 2365: 1, 2366: 3, 2367: 1, 2368: 2, 2369: 2, 2370: 2, 2371: 1, 2372: 1, 2373: 2, 2374: 1, 2375: 2, 2376: 2, 2377: 2, 2378: 1, 2379: 3, 2380: 4, 2381: 1, 2382: 1, 2383: 1, 2384: 1, 2385: 2, 2386: 3, 2387: 1, 2388: 2, 2389: 2, 2390: 1, 2391: 2, 2392: 1, 2393: 4, 2394: 3, 2395: 2, 2396: 2, 2397: 2, 2398: 1, 2399: 1, 2400: 1, 2401: 1, 2402: 2, 2403: 1, 2404: 4, 2405: 1, 2406: 2, 2407: 1, 2408: 1, 2409: 2, 2410: 2, 2411: 2, 2412: 1, 2413: 1, 2414: 2, 2415: 2, 2416: 1, 2417: 1, 2418: 3, 2419: 2, 2420: 3, 2421: 1, 2422: 1, 2423: 1, 2424: 1, 2425: 1, 2426: 1, 2427: 1, 2428: 1, 2429: 1, 2430: 2, 2431: 2, 2432: 1, 2433: 2, 2434: 1, 2435: 1, 2436: 2, 2437: 4, 2438: 2, 2439: 2, 2440: 1, 2441: 1, 2442: 2, 2443: 1, 2444: 1, 2445: 2, 2446: 1, 2447: 2, 2448: 1, 2449: 1, 2450: 3, 2451: 4, 2452: 3, 2453: 2, 2454: 1, 2455: 1, 2456: 1, 2457: 2, 2458: 2, 2459: 1, 2460: 3, 2461: 3, 2462: 2, 2463: 3, 2464: 1, 2465: 2, 2466: 2, 2467: 1, 2468: 2, 2469: 3, 2470: 1, 2471: 2, 2472: 2, 2473: 1, 2474: 1, 2475: 3, 2476: 1, 2477: 2, 2478: 1, 2479: 1, 2480: 2, 2481: 1, 2482: 1, 2483: 2, 2484: 1, 2485: 1, 2486: 2, 2487: 1, 2488: 2, 2489: 2, 2490: 2, 2491: 2, 2492: 1, 2493: 3, 2494: 3, 2495: 3, 2496: 2, 2497: 2, 2498: 2, 2499: 1, 2500: 3, 2501: 5, 2502: 3, 2503: 2, 2504: 2, 2505: 1, 2506: 1, 2507: 2, 2508: 1, 2509: 1, 2510: 2, 2511: 1, 2512: 1, 2513: 1, 2514: 1, 2515: 1, 2516: 1, 2517: 2, 2518: 1, 2519: 1, 2520: 1, 2521: 3, 2522: 2, 2523: 3, 2524: 1, 2525: 1, 2526: 1, 2527: 3, 2528: 1, 2529: 1, 2530: 3, 2531: 1, 2532: 2, 2533: 1, 2534: 2, 2535: 1, 2536: 2, 2537: 3, 2538: 1, 2539: 2, 2540: 1, 2541: 1, 2542: 1, 2543: 1, 2544: 1, 2545: 2, 2546: 2, 2547: 1, 2548: 3, 2549: 1, 2550: 3, 2551: 1, 2552: 1, 2553: 3, 2554: 1, 2555: 1, 2556: 1, 2557: 1, 2558: 5, 2559: 1, 2560: 1, 2561: 1, 2562: 4, 2563: 1, 2564: 1, 2565: 1, 2566: 2, 2567: 2, 2568: 3, 2569: 1, 2570: 3, 2571: 3, 2572: 3, 2573: 1, 2574: 2, 2575: 1, 2576: 1, 2577: 2, 2578: 1, 2579: 2, 2580: 2, 2581: 1, 2582: 2, 2583: 1, 2584: 4, 2585: 1, 2586: 1, 2587: 2, 2588: 1, 2589: 1, 2590: 2, 2591: 2, 2592: 2, 2593: 3, 2594: 1, 2595: 1, 2596: 1, 2597: 1, 2598: 2, 2599: 1, 2600: 1, 2601: 3, 2602: 1, 2603: 3, 2604: 2, 2605: 1, 2606: 1, 2607: 1, 2608: 1, 2609: 1, 2610: 2, 2611: 2, 2612: 1, 2613: 2, 2614: 2, 2615: 1, 2616: 1, 2617: 2, 2618: 1, 2619: 2, 2620: 3, 2621: 1, 2622: 1, 2623: 1, 2624: 1, 2625: 1, 2626: 1, 2627: 1, 2628: 3, 2629: 2, 2630: 3, 2631: 1, 2632: 1, 2633: 1, 2634: 2, 2635: 2, 2636: 1, 2637: 1, 2638: 2, 2639: 1, 2640: 1, 2641: 1, 2642: 2, 2643: 1, 2644: 2, 2645: 2, 2646: 1, 2647: 1, 2648: 1, 2649: 2, 2650: 1, 2651: 3, 2652: 1, 2653: 3, 2654: 1, 2655: 2, 2656: 1, 2657: 4, 2658: 2, 2659: 2, 2660: 2, 2661: 1, 2662: 1, 2663: 1, 2664: 1, 2665: 2, 2666: 3, 2667: 1, 2668: 1, 2669: 1, 2670: 1, 2671: 2, 2672: 2, 2673: 1, 2674: 1, 2675: 1, 2676: 2, 2677: 2, 2678: 1, 2679: 1, 2680: 1, 2681: 1, 2682: 1, 2683: 1, 2684: 2, 2685: 2, 2686: 1, 2687: 2, 2688: 1, 2689: 3, 2690: 1, 2691: 2, 2692: 1, 2693: 2, 2694: 1, 2695: 2, 2696: 3, 2697: 2, 2698: 2, 2699: 1, 2700: 1, 2701: 2, 2702: 2, 2703: 1, 2704: 4, 2705: 1, 2706: 1, 2707: 2, 2708: 1, 2709: 1, 2710: 3, 2711: 1, 2712: 2, 2713: 1, 2714: 1, 2715: 3, 2716: 1, 2717: 2, 2718: 1, 2719: 1, 2720: 2, 2721: 2, 2722: 2, 2723: 2, 2724: 1, 2725: 1, 2726: 2, 2727: 1, 2728: 3, 2729: 2, 2730: 3, 2731: 2, 2732: 1, 2733: 3, 2734: 1, 2735: 1, 2736: 3, 2737: 2, 2738: 2, 2739: 2, 2740: 1, 2741: 1, 2742: 1, 2743: 1, 2744: 1, 2745: 1, 2746: 4, 2747: 3, 2748: 1, 2749: 1, 2750: 1, 2751: 2, 2752: 1, 2753: 1, 2754: 2, 2755: 1, 2756: 1, 2757: 2, 2758: 1, 2759: 1, 2760: 1, 2761: 2, 2762: 1, 2763: 2, 2764: 2, 2765: 1, 2766: 1, 2767: 1, 2768: 2, 2769: 2, 2770: 1, 2771: 1, 2772: 1, 2773: 1, 2774: 1, 2775: 3, 2776: 1, 2777: 2, 2778: 1, 2779: 3, 2780: 2, 2781: 1, 2782: 2, 2783: 2, 2784: 2, 2785: 1, 2786: 1, 2787: 1, 2788: 1, 2789: 1, 2790: 3, 2791: 2, 2792: 3, 2793: 2, 2794: 2, 2795: 1, 2796: 1, 2797: 1, 2798: 3, 2799: 1, 2800: 2, 2801: 3, 2802: 1, 2803: 1, 2804: 3, 2805: 1, 2806: 3, 2807: 2, 2808: 3, 2809: 3, 2810: 2, 2811: 2, 2812: 1, 2813: 2, 2814: 1, 2815: 2, 2816: 2, 2817: 2, 2818: 1, 2819: 1, 2820: 2, 2821: 1, 2822: 1, 2823: 1, 2824: 2, 2825: 1, 2826: 1, 2827: 3, 2828: 1, 2829: 1, 2830: 1, 2831: 2, 2832: 2, 2833: 1, 2834: 2, 2835: 1, 2836: 1, 2837: 1, 2838: 2, 2839: 1, 2840: 4, 2841: 1, 2842: 3, 2843: 1, 2844: 3, 2845: 1, 2846: 2, 2847: 3, 2848: 1, 2849: 1, 2850: 1, 2851: 1, 2852: 2, 2853: 2, 2854: 2, 2855: 3, 2856: 3, 2857: 1, 2858: 2, 2859: 1, 2860: 1, 2861: 1, 2862: 1, 2863: 3, 2864: 2, 2865: 1, 2866: 3, 2867: 1, 2868: 1, 2869: 1, 2870: 1, 2871: 2, 2872: 3, 2873: 1, 2874: 1, 2875: 1, 2876: 1, 2877: 3, 2878: 2, 2879: 2, 2880: 2, 2881: 1, 2882: 2, 2883: 1, 2884: 1, 2885: 1, 2886: 1, 2887: 1, 2888: 1, 2889: 1, 2890: 2, 2891: 1, 2892: 2, 2893: 2, 2894: 2, 2895: 1, 2896: 1, 2897: 1, 2898: 1, 2899: 2, 2900: 2, 2901: 1, 2902: 2, 2903: 1, 2904: 2, 2905: 1, 2906: 2, 2907: 1, 2908: 1, 2909: 1, 2910: 1, 2911: 3, 2912: 2, 2913: 2, 2914: 1, 2915: 1, 2916: 2, 2917: 1, 2918: 2, 2919: 1, 2920: 2, 2921: 1, 2922: 2, 2923: 3, 2924: 1, 2925: 1, 2926: 1, 2927: 1, 2928: 1, 2929: 1, 2930: 1, 2931: 1, 2932: 1, 2933: 5, 2934: 3, 2935: 2, 2936: 2, 2937: 1, 2938: 2, 2939: 1, 2940: 1, 2941: 1, 2942: 1, 2943: 1, 2944: 3, 2945: 2, 2946: 1, 2947: 1, 2948: 1, 2949: 2, 2950: 2, 2951: 2, 2952: 1, 2953: 3, 2954: 2, 2955: 1, 2956: 1, 2957: 2, 2958: 2, 2959: 2, 2960: 1, 2961: 1, 2962: 2, 2963: 2, 2964: 1, 2965: 2, 2966: 1, 2967: 1, 2968: 1, 2969: 2, 2970: 1, 2971: 1, 2972: 1, 2973: 1, 2974: 2, 2975: 1, 2976: 1, 2977: 1, 2978: 5, 2979: 1, 2980: 2, 2981: 1, 2982: 1, 2983: 1, 2984: 2, 2985: 1, 2986: 1, 2987: 2, 2988: 1, 2989: 1, 2990: 1, 2991: 1, 2992: 2, 2993: 1, 2994: 1, 2995: 3, 2996: 2, 2997: 1, 2998: 2, 2999: 1, 3000: 2, 3001: 2, 3002: 1, 3003: 1, 3004: 2, 3005: 3, 3006: 2, 3007: 1, 3008: 2, 3009: 1, 3010: 1, 3011: 2, 3012: 1, 3013: 1, 3014: 2, 3015: 1, 3016: 1, 3017: 2, 3018: 3, 3019: 1, 3020: 1, 3021: 1, 3022: 2, 3023: 2, 3024: 1, 3025: 2, 3026: 1, 3027: 1, 3028: 2, 3029: 1, 3030: 2, 3031: 2, 3032: 1, 3033: 1, 3034: 2, 3035: 1, 3036: 1, 3037: 2, 3038: 1, 3039: 2, 3040: 2, 3041: 1, 3042: 2, 3043: 1, 3044: 1, 3045: 1, 3046: 1, 3047: 1, 3048: 1, 3049: 1, 3050: 1, 3051: 2, 3052: 2, 3053: 2, 3054: 2, 3055: 1, 3056: 1, 3057: 2, 3058: 1, 3059: 1, 3060: 1, 3061: 2, 3062: 1, 3063: 1, 3064: 2, 3065: 1, 3066: 2, 3067: 3, 3068: 3, 3069: 1, 3070: 1, 3071: 3, 3072: 1, 3073: 1, 3074: 1, 3075: 2, 3076: 1, 3077: 1, 3078: 1, 3079: 1, 3080: 1, 3081: 1, 3082: 1, 3083: 2, 3084: 1, 3085: 1, 3086: 2, 3087: 1, 3088: 3, 3089: 2, 3090: 3, 3091: 2, 3092: 2, 3093: 2, 3094: 2, 3095: 1, 3096: 1, 3097: 1, 3098: 1, 3099: 1, 3100: 1, 3101: 1, 3102: 3, 3103: 1, 3104: 1, 3105: 1, 3106: 1, 3107: 1, 3108: 1, 3109: 1, 3110: 1, 3111: 3, 3112: 2, 3113: 1, 3114: 1, 3115: 3, 3116: 2, 3117: 2, 3118: 2, 3119: 3, 3120: 1, 3121: 1, 3122: 2, 3123: 1, 3124: 1, 3125: 1, 3126: 2, 3127: 1, 3128: 1, 3129: 2, 3130: 1, 3131: 1, 3132: 1, 3133: 1, 3134: 1, 3135: 2, 3136: 1, 3137: 1, 3138: 3, 3139: 1, 3140: 1, 3141: 2, 3142: 2, 3143: 2, 3144: 1, 3145: 1, 3146: 2, 3147: 1, 3148: 1, 3149: 1, 3150: 1, 3151: 3, 3152: 4, 3153: 1, 3154: 1, 3155: 1, 3156: 1, 3157: 2, 3158: 1, 3159: 1, 3160: 1, 3161: 2, 3162: 1, 3163: 2, 3164: 1, 3165: 2, 3166: 2, 3167: 2, 3168: 1, 3169: 1, 3170: 2, 3171: 1, 3172: 1, 3173: 2, 3174: 1, 3175: 2, 3176: 1, 3177: 2, 3178: 1, 3179: 2, 3180: 1, 3181: 1, 3182: 1, 3183: 2, 3184: 1, 3185: 2, 3186: 2, 3187: 1, 3188: 2, 3189: 1, 3190: 1, 3191: 2, 3192: 1, 3193: 1, 3194: 1, 3195: 2, 3196: 1, 3197: 1, 3198: 1, 3199: 1, 3200: 1, 3201: 1, 3202: 2, 3203: 2, 3204: 2, 3205: 2, 3206: 1, 3207: 3, 3208: 2, 3209: 1, 3210: 1, 3211: 2, 3212: 1, 3213: 1, 3214: 2, 3215: 1, 3216: 1, 3217: 2, 3218: 2, 3219: 1, 3220: 1, 3221: 2, 3222: 2, 3223: 2, 3224: 2, 3225: 1, 3226: 1, 3227: 1, 3228: 3, 3229: 2, 3230: 2, 3231: 1, 3232: 1, 3233: 1, 3234: 1, 3235: 1, 3236: 2, 3237: 1, 3238: 2, 3239: 1, 3240: 1, 3241: 1, 3242: 1, 3243: 1, 3244: 1, 3245: 1, 3246: 1, 3247: 2, 3248: 1, 3249: 1, 3250: 1, 3251: 2, 3252: 2, 3253: 3, 3254: 1, 3255: 1, 3256: 1, 3257: 2, 3258: 2, 3259: 3, 3260: 1, 3261: 1, 3262: 1, 3263: 1, 3264: 3, 3265: 1, 3266: 2, 3267: 1, 3268: 3, 3269: 1, 3270: 1, 3271: 1, 3272: 1, 3273: 1, 3274: 1, 3275: 2, 3276: 1, 3277: 1, 3278: 1, 3279: 1, 3280: 3, 3281: 1, 3282: 3, 3283: 1, 3284: 1, 3285: 2, 3286: 3, 3287: 1, 3288: 2, 3289: 1, 3290: 1, 3291: 1, 3292: 1, 3293: 1, 3294: 1, 3295: 1, 3296: 1, 3297: 1, 3298: 1, 3299: 2, 3300: 1, 3301: 1, 3302: 1, 3303: 1, 3304: 2, 3305: 1, 3306: 2, 3307: 1, 3308: 2, 3309: 2, 3310: 1, 3311: 2, 3312: 1, 3313: 1, 3314: 2, 3315: 2, 3316: 1, 3317: 1, 3318: 2, 3319: 1, 3320: 1, 3321: 1, 3322: 1, 3323: 2, 3324: 1, 3325: 1, 3326: 1, 3327: 1, 3328: 1, 3329: 2, 3330: 1, 3331: 2, 3332: 1, 3333: 1, 3334: 1, 3335: 1, 3336: 1, 3337: 1, 3338: 1, 3339: 1, 3340: 1, 3341: 2, 3342: 1, 3343: 2, 3344: 1, 3345: 1, 3346: 2, 3347: 1, 3348: 3, 3349: 1, 3350: 3, 3351: 2, 3352: 1, 3353: 2, 3354: 1, 3355: 3, 3356: 1, 3357: 1, 3358: 2, 3359: 4, 3360: 1, 3361: 1, 3362: 2, 3363: 2, 3364: 1, 3365: 1, 3366: 2, 3367: 1, 3368: 1, 3369: 1, 3370: 1, 3371: 2, 3372: 1, 3373: 2, 3374: 1, 3375: 1, 3376: 1, 3377: 2, 3378: 2, 3379: 1, 3380: 2, 3381: 3, 3382: 1, 3383: 1, 3384: 3, 3385: 1, 3386: 1, 3387: 1, 3388: 1, 3389: 3, 3390: 1, 3391: 2, 3392: 2, 3393: 1, 3394: 1, 3395: 1, 3396: 1, 3397: 1, 3398: 1, 3399: 2, 3400: 1, 3401: 2, 3402: 1, 3403: 1, 3404: 1, 3405: 2, 3406: 1, 3407: 2, 3408: 1, 3409: 1, 3410: 1, 3411: 2, 3412: 1, 3413: 3, 3414: 1, 3415: 2, 3416: 1, 3417: 2, 3418: 1, 3419: 2, 3420: 1, 3421: 2, 3422: 3, 3423: 2, 3424: 1, 3425: 1, 3426: 2, 3427: 1, 3428: 2, 3429: 1, 3430: 2, 3431: 1, 3432: 1, 3433: 2, 3434: 1, 3435: 1, 3436: 3, 3437: 1, 3438: 1, 3439: 1, 3440: 2, 3441: 1, 3442: 2, 3443: 2, 3444: 2, 3445: 1, 3446: 1, 3447: 1, 3448: 1, 3449: 1, 3450: 1, 3451: 1, 3452: 1, 3453: 1, 3454: 1, 3455: 1, 3456: 1, 3457: 1, 3458: 2, 3459: 2, 3460: 2, 3461: 1, 3462: 1, 3463: 1, 3464: 2, 3465: 2, 3466: 3, 3467: 1, 3468: 1, 3469: 1, 3470: 2, 3471: 1, 3472: 1, 3473: 2, 3474: 1, 3475: 1, 3476: 1, 3477: 1, 3478: 1, 3479: 1, 3480: 2, 3481: 1, 3482: 1, 3483: 1, 3484: 1, 3485: 1, 3486: 1, 3487: 2, 3488: 1, 3489: 2, 3490: 1, 3491: 2, 3492: 1, 3493: 1, 3494: 1, 3495: 2, 3496: 1, 3497: 2, 3498: 1, 3499: 3, 3500: 1, 3501: 1, 3502: 1, 3503: 2, 3504: 2, 3505: 1, 3506: 1, 3507: 1, 3508: 1, 3509: 1, 3510: 2, 3511: 1, 3512: 1, 3513: 1, 3514: 1, 3515: 3, 3516: 1, 3517: 2, 3518: 1, 3519: 2, 3520: 2, 3521: 1, 3522: 1, 3523: 1, 3524: 1, 3525: 1, 3526: 1, 3527: 1, 3528: 1, 3529: 1, 3530: 1, 3531: 1, 3532: 1, 3533: 3, 3534: 1, 3535: 1, 3536: 1, 3537: 1, 3538: 1, 3539: 1, 3540: 1, 3541: 1, 3542: 2, 3543: 1, 3544: 1, 3545: 1, 3546: 1, 3547: 1, 3548: 1, 3549: 1, 3550: 1, 3551: 1, 3552: 1, 3553: 1, 3554: 1, 3555: 2, 3556: 1, 3557: 1, 3558: 1, 3559: 2, 3560: 3, 3561: 1, 3562: 1, 3563: 1, 3564: 1, 3565: 1, 3566: 1, 3567: 1, 3568: 1, 3569: 1, 3570: 1, 3571: 1, 3572: 1, 3573: 2, 3574: 2, 3575: 1, 3576: 3, 3577: 1, 3578: 1, 3579: 2, 3580: 3, 3581: 1, 3582: 2, 3583: 2, 3584: 1, 3585: 3, 3586: 2, 3587: 2, 3588: 1, 3589: 1, 3590: 1, 3591: 1, 3592: 1, 3593: 1, 3594: 1, 3595: 1, 3596: 2, 3597: 1, 3598: 1, 3599: 1, 3600: 1, 3601: 1, 3602: 2, 3603: 2, 3604: 1, 3605: 1, 3606: 1, 3607: 2, 3608: 2, 3609: 2, 3610: 1, 3611: 1, 3612: 1, 3613: 2, 3614: 2, 3615: 1, 3616: 2, 3617: 1, 3618: 1, 3619: 1, 3620: 1, 3621: 2, 3622: 1, 3623: 1, 3624: 2, 3625: 1, 3626: 1, 3627: 2, 3628: 1, 3629: 1, 3630: 2, 3631: 1, 3632: 1, 3633: 1, 3634: 1, 3635: 2, 3636: 2, 3637: 1, 3638: 1, 3639: 1, 3640: 1, 3641: 1, 3642: 2, 3643: 1, 3644: 1, 3645: 1, 3646: 1, 3647: 2, 3648: 1, 3649: 3, 3650: 2, 3651: 1, 3652: 1, 3653: 1, 3654: 1, 3655: 1, 3656: 1, 3657: 1, 3658: 1, 3659: 1, 3660: 1, 3661: 1, 3662: 1, 3663: 1, 3664: 1, 3665: 1, 3666: 1, 3667: 2, 3668: 1, 3669: 1, 3670: 1, 3671: 2, 3672: 1, 3673: 1, 3674: 1, 3675: 1, 3676: 1, 3677: 1, 3678: 1, 3679: 1, 3680: 1, 3681: 1, 3682: 1, 3683: 1, 3684: 1, 3685: 2, 3686: 1, 3687: 1, 3688: 1, 3689: 3, 3690: 1, 3691: 2, 3692: 1, 3693: 1, 3694: 3, 3695: 2, 3696: 2, 3697: 1, 3698: 1, 3699: 1, 3700: 1, 3701: 2, 3702: 2, 3703: 1, 3704: 1, 3705: 1, 3706: 1, 3707: 1, 3708: 1, 3709: 1, 3710: 1, 3711: 1, 3712: 1, 3713: 1, 3714: 2, 3715: 1, 3716: 1, 3717: 2, 3718: 1, 3719: 1, 3720: 1, 3721: 1, 3722: 1, 3723: 1, 3724: 1, 3725: 1, 3726: 2, 3727: 1, 3728: 1, 3729: 1, 3730: 1, 3731: 1, 3732: 1, 3733: 1, 3734: 1, 3735: 1, 3736: 3, 3737: 2, 3738: 2, 3739: 2, 3740: 1, 3741: 2, 3742: 1, 3743: 1, 3744: 1, 3745: 2, 3746: 1, 3747: 1, 3748: 1, 3749: 3, 3750: 2, 3751: 1, 3752: 1, 3753: 2, 3754: 2, 3755: 1, 3756: 1, 3757: 1, 3758: 1, 3759: 1, 3760: 1, 3761: 2, 3762: 1, 3763: 2, 3764: 1, 3765: 1, 3766: 1, 3767: 2, 3768: 1, 3769: 1, 3770: 2, 3771: 1, 3772: 1, 3773: 1, 3774: 1, 3775: 1, 3776: 1, 3777: 1, 3778: 2, 3779: 1, 3780: 1, 3781: 1, 3782: 1, 3783: 2, 3784: 2, 3785: 1, 3786: 2, 3787: 1, 3788: 1, 3789: 1, 3790: 1, 3791: 1, 3792: 1, 3793: 2, 3794: 1, 3795: 1, 3796: 2, 3797: 1, 3798: 1, 3799: 1, 3800: 1, 3801: 2, 3802: 1, 3803: 1, 3804: 2, 3805: 1, 3806: 1, 3807: 2, 3808: 1, 3809: 1, 3810: 1, 3811: 1, 3812: 1, 3813: 1, 3814: 2, 3815: 1, 3816: 1, 3817: 1, 3818: 2, 3819: 2, 3820: 2, 3821: 1, 3822: 1, 3823: 1, 3824: 2, 3825: 1, 3826: 1, 3827: 2, 3828: 1, 3829: 1, 3830: 2, 3831: 1, 3832: 1, 3833: 1, 3834: 1, 3835: 1, 3836: 2, 3837: 1, 3838: 1, 3839: 2, 3840: 1, 3841: 1, 3842: 3, 3843: 2, 3844: 1, 3845: 1, 3846: 1, 3847: 1, 3848: 1, 3849: 1, 3850: 1, 3851: 1, 3852: 1, 3853: 1, 3854: 1, 3855: 1, 3856: 1, 3857: 1, 3858: 1, 3859: 1, 3860: 1, 3861: 1, 3862: 1, 3863: 2, 3864: 2, 3865: 3, 3866: 2, 3867: 1, 3868: 1, 3869: 1, 3870: 2, 3871: 1, 3872: 1, 3873: 1, 3874: 2, 3875: 1, 3876: 1, 3877: 1, 3878: 1, 3879: 3, 3880: 1, 3881: 1, 3882: 1, 3883: 1, 3884: 1, 3885: 1, 3886: 1, 3887: 1, 3888: 1, 3889: 1, 3890: 1, 3891: 1, 3892: 3, 3893: 2, 3894: 1, 3895: 2, 3896: 2, 3897: 1, 3898: 1, 3899: 1, 3900: 2, 3901: 1, 3902: 1, 3903: 1, 3904: 1, 3905: 2, 3906: 1, 3907: 1, 3908: 2, 3909: 2, 3910: 1, 3911: 1, 3912: 1, 3913: 1, 3914: 1, 3915: 1, 3916: 1, 3917: 1, 3918: 1, 3919: 1, 3920: 1, 3921: 2, 3922: 1, 3923: 1, 3924: 1, 3925: 1, 3926: 3, 3927: 1, 3928: 1, 3929: 3, 3930: 2, 3931: 1, 3932: 1, 3933: 1, 3934: 1, 3935: 1, 3936: 1, 3937: 1, 3938: 1, 3939: 1, 3940: 1, 3941: 2, 3942: 2, 3943: 1, 3944: 1, 3945: 1, 3946: 2, 3947: 1, 3948: 2, 3949: 1, 3950: 1, 3951: 1, 3952: 1, 3953: 1, 3954: 2, 3955: 1, 3956: 2, 3957: 2, 3958: 2, 3959: 2, 3960: 1, 3961: 1, 3962: 2, 3963: 1, 3964: 1, 3965: 2, 3966: 1, 3967: 1, 3968: 1, 3969: 1, 3970: 1, 3971: 1, 3972: 1, 3973: 1, 3974: 1, 3975: 1, 3976: 1, 3977: 1, 3978: 2, 3979: 1, 3980: 1, 3981: 1, 3982: 1, 3983: 1, 3984: 1, 3985: 2, 3986: 1, 3987: 1, 3988: 1, 3989: 1, 3990: 1, 3991: 1, 3992: 1, 3993: 2, 3994: 1, 3995: 1, 3996: 1, 3997: 1, 3998: 1, 3999: 2, 4000: 1, 4001: 1, 4002: 1, 4003: 1, 4004: 1, 4005: 1, 4006: 1, 4007: 1, 4008: 1, 4009: 1, 4010: 2, 4011: 1, 4012: 1, 4013: 2, 4014: 1, 4015: 1, 4016: 1, 4017: 1, 4018: 1, 4019: 1, 4020: 1, 4021: 1, 4022: 1, 4023: 1, 4024: 1, 4025: 1, 4026: 1, 4027: 1, 4028: 2, 4029: 1, 4030: 1, 4031: 1, 4032: 1, 4033: 1, 4034: 1, 4035: 1, 4036: 1, 4037: 1, 4038: 1, 4039: 1, 4040: 1, 4041: 1, 4042: 1, 4043: 2, 4044: 1, 4045: 1, 4046: 1, 4047: 1, 4048: 1, 4049: 2, 4050: 1, 4051: 1, 4052: 1, 4053: 1, 4054: 1, 4055: 1, 4056: 1, 4057: 1, 4058: 3, 4059: 1, 4060: 1, 4061: 1, 4062: 1, 4063: 3, 4064: 2, 4065: 1, 4066: 1, 4067: 2, 4068: 2, 4069: 2, 4070: 1, 4071: 1, 4072: 1, 4073: 1, 4074: 1, 4075: 1, 4076: 1, 4077: 2, 4078: 1, 4079: 1, 4080: 1, 4081: 1, 4082: 1, 4083: 1, 4084: 1, 4085: 1, 4086: 1, 4087: 1, 4088: 1, 4089: 1, 4090: 1, 4091: 1, 4092: 1, 4093: 1, 4094: 1, 4095: 2, 4096: 1, 4097: 1, 4098: 1, 4099: 1, 4100: 1, 4101: 1, 4102: 1, 4103: 1, 4104: 2, 4105: 1, 4106: 1, 4107: 1, 4108: 2, 4109: 1, 4110: 1, 4111: 1, 4112: 1, 4113: 3, 4114: 1, 4115: 2, 4116: 1, 4117: 1, 4118: 1, 4119: 1, 4120: 2, 4121: 1, 4122: 1, 4123: 1, 4124: 1, 4125: 1, 4126: 1, 4127: 1, 4128: 1, 4129: 1, 4130: 1, 4131: 1, 4132: 1, 4133: 1, 4134: 1, 4135: 1, 4136: 2, 4137: 1, 4138: 1, 4139: 1, 4140: 2, 4141: 1, 4142: 2, 4143: 1, 4144: 1, 4145: 1, 4146: 1, 4147: 1, 4148: 1, 4149: 1, 4150: 1, 4151: 1, 4152: 1, 4153: 1, 4154: 1, 4155: 1, 4156: 1, 4157: 1, 4158: 1, 4159: 3, 4160: 1, 4161: 1, 4162: 1, 4163: 1, 4164: 1, 4165: 1, 4166: 1, 4167: 3, 4168: 1, 4169: 1, 4170: 1, 4171: 1, 4172: 1, 4173: 1, 4174: 2, 4175: 1, 4176: 2, 4177: 1, 4178: 1, 4179: 1, 4180: 2, 4181: 1, 4182: 1, 4183: 1, 4184: 1, 4185: 1, 4186: 1, 4187: 2, 4188: 1, 4189: 1, 4190: 1, 4191: 1, 4192: 1, 4193: 1, 4194: 1, 4195: 1, 4196: 1, 4197: 1, 4198: 1, 4199: 1, 4200: 1, 4201: 1, 4202: 1, 4203: 1, 4204: 1, 4205: 1, 4206: 1, 4207: 1, 4208: 1, 4209: 2, 4210: 1, 4211: 1, 4212: 1, 4213: 1, 4214: 1, 4215: 1, 4216: 1, 4217: 1, 4218: 1, 4219: 1, 4220: 1, 4221: 1, 4222: 1, 4223: 1, 4224: 1, 4225: 2, 4226: 1, 4227: 1, 4228: 1, 4229: 1, 4230: 1, 4231: 2, 4232: 1, 4233: 1, 4234: 2, 4235: 1, 4236: 1, 4237: 1, 4238: 1, 4239: 1, 4240: 1, 4241: 1, 4242: 1, 4243: 1, 4244: 2, 4245: 1, 4246: 1, 4247: 1, 4248: 1, 4249: 1, 4250: 1, 4251: 1, 4252: 1, 4253: 1, 4254: 2, 4255: 1, 4256: 1, 4257: 2, 4258: 1, 4259: 1, 4260: 2, 4261: 1, 4262: 1, 4263: 1, 4264: 1, 4265: 1, 4266: 1, 4267: 1, 4268: 1, 4269: 1, 4270: 1, 4271: 2, 4272: 1, 4273: 1, 4274: 1, 4275: 1, 4276: 1, 4277: 1, 4278: 2, 4279: 1, 4280: 1, 4281: 1, 4282: 1, 4283: 2, 4284: 1, 4285: 1, 4286: 2, 4287: 2, 4288: 1, 4289: 2, 4290: 1, 4291: 1, 4292: 1, 4293: 1, 4294: 1, 4295: 1, 4296: 1, 4297: 1, 4298: 2, 4299: 2, 4300: 1, 4301: 1, 4302: 1, 4303: 1, 4304: 1, 4305: 1, 4306: 2, 4307: 1, 4308: 2, 4309: 1, 4310: 1, 4311: 1, 4312: 1, 4313: 1, 4314: 1, 4315: 2, 4316: 1, 4317: 1, 4318: 1, 4319: 1, 4320: 1, 4321: 1, 4322: 1, 4323: 1, 4324: 1, 4325: 1, 4326: 1, 4327: 1, 4328: 1, 4329: 1, 4330: 1, 4331: 1, 4332: 1, 4333: 1, 4334: 1, 4335: 1, 4336: 1, 4337: 1, 4338: 2, 4339: 1, 4340: 1, 4341: 1, 4342: 1, 4343: 1, 4344: 1, 4345: 1, 4346: 1, 4347: 1, 4348: 1, 4349: 1, 4350: 1, 4351: 1, 4352: 1, 4353: 1, 4354: 1, 4355: 1, 4356: 1, 4357: 1, 4358: 1, 4359: 1, 4360: 1, 4361: 1, 4362: 1, 4363: 1, 4364: 1, 4365: 1, 4366: 2, 4367: 1, 4368: 1, 4369: 2, 4370: 2, 4371: 1, 4372: 1, 4373: 1, 4374: 1, 4375: 1, 4376: 1, 4377: 3, 4378: 1, 4379: 1, 4380: 1, 4381: 1, 4382: 1, 4383: 1, 4384: 1, 4385: 1, 4386: 1, 4387: 1, 4388: 2, 4389: 1, 4390: 2, 4391: 1, 4392: 1, 4393: 1, 4394: 1, 4395: 1, 4396: 1, 4397: 1, 4398: 1, 4399: 1, 4400: 1, 4401: 1, 4402: 1, 4403: 1, 4404: 1, 4405: 1, 4406: 1, 4407: 1, 4408: 2, 4409: 1, 4410: 1, 4411: 1, 4412: 1, 4413: 1, 4414: 1, 4415: 1, 4416: 1, 4417: 1, 4418: 1, 4419: 2, 4420: 1, 4421: 1, 4422: 1, 4423: 1, 4424: 1, 4425: 1, 4426: 1, 4427: 1, 4428: 1, 4429: 1, 4430: 1, 4431: 1, 4432: 1, 4433: 1, 4434: 1, 4435: 1, 4436: 1, 4437: 1, 4438: 1, 4439: 1, 4440: 1, 4441: 1, 4442: 1, 4443: 2, 4444: 2, 4445: 1, 4446: 1, 4447: 1, 4448: 1, 4449: 2, 4450: 1, 4451: 1, 4452: 1, 4453: 1, 4454: 1, 4455: 1, 4456: 2, 4457: 1, 4458: 2, 4459: 1, 4460: 1, 4461: 1, 4462: 3, 4463: 2, 4464: 1, 4465: 1, 4466: 1, 4467: 1, 4468: 2, 4469: 1, 4470: 1, 4471: 1, 4472: 2, 4473: 1, 4474: 1, 4475: 1, 4476: 1, 4477: 1, 4478: 1, 4479: 1, 4480: 1, 4481: 1, 4482: 1, 4483: 1, 4484: 2, 4485: 2, 4486: 1, 4487: 1, 4488: 1, 4489: 1, 4490: 1, 4491: 1, 4492: 1, 4493: 1, 4494: 1, 4495: 1, 4496: 1, 4497: 1, 4498: 1, 4499: 1, 4500: 1, 4501: 2, 4502: 1, 4503: 1, 4504: 1, 4505: 1, 4506: 1, 4507: 1, 4508: 1, 4509: 1, 4510: 1, 4511: 1, 4512: 1, 4513: 1, 4514: 1, 4515: 2, 4516: 1, 4517: 1, 4518: 1, 4519: 1, 4520: 1, 4521: 1, 4522: 1, 4523: 1, 4524: 2, 4525: 1, 4526: 1, 4527: 2, 4528: 1, 4529: 1, 4530: 1, 4531: 1, 4532: 1, 4533: 1, 4534: 1, 4535: 1, 4536: 1, 4537: 1, 4538: 1, 4539: 1, 4540: 1, 4541: 1, 4542: 1, 4543: 1, 4544: 1, 4545: 1, 4546: 1, 4547: 1, 4548: 1, 4549: 1, 4550: 1, 4551: 1, 4552: 1, 4553: 2, 4554: 1, 4555: 1, 4556: 1, 4557: 1, 4558: 2, 4559: 1, 4560: 1, 4561: 1, 4562: 1, 4563: 1, 4564: 1, 4565: 1, 4566: 1, 4567: 1, 4568: 1, 4569: 1, 4570: 1, 4571: 1, 4572: 1, 4573: 1, 4574: 1, 4575: 1, 4576: 1, 4577: 1, 4578: 1, 4579: 1, 4580: 1, 4581: 1, 4582: 1, 4583: 1, 4584: 1, 4585: 1, 4586: 1, 4587: 1, 4588: 1, 4589: 1, 4590: 1, 4591: 1, 4592: 1, 4593: 1, 4594: 1, 4595: 1, 4596: 1, 4597: 1, 4598: 1, 4599: 1, 4600: 1, 4601: 1, 4602: 1, 4603: 1, 4604: 1, 4605: 2, 4606: 1, 4607: 1, 4608: 2, 4609: 1, 4610: 1, 4611: 1, 4612: 1, 4613: 1, 4614: 1, 4615: 1, 4616: 1, 4617: 1, 4618: 1, 4619: 1, 4620: 1, 4621: 1, 4622: 1, 4623: 1, 4624: 2, 4625: 1, 4626: 1, 4627: 1, 4628: 1, 4629: 1, 4630: 1, 4631: 1, 4632: 2, 4633: 1, 4634: 1, 4635: 1, 4636: 1, 4637: 1, 4638: 1, 4639: 1, 4640: 1, 4641: 1, 4642: 1, 4643: 1, 4644: 1, 4645: 1, 4646: 1, 4647: 1, 4648: 1, 4649: 1, 4650: 1, 4651: 1, 4652: 1, 4653: 1, 4654: 1, 4655: 1, 4656: 1, 4657: 1, 4658: 1, 4659: 1, 4660: 1, 4661: 1, 4662: 1, 4663: 1, 4664: 1, 4665: 1, 4666: 1, 4667: 1, 4668: 1, 4669: 3, 4670: 1, 4671: 1, 4672: 1, 4673: 1, 4674: 1, 4675: 1, 4676: 1, 4677: 2, 4678: 1, 4679: 1, 4680: 1, 4681: 1, 4682: 2, 4683: 1, 4684: 1, 4685: 1, 4686: 1, 4687: 1, 4688: 1, 4689: 2, 4690: 1, 4691: 1, 4692: 1, 4693: 1, 4694: 1, 4695: 1, 4696: 1, 4697: 1, 4698: 1, 4699: 2, 4700: 1, 4701: 1, 4702: 1, 4703: 1, 4704: 1, 4705: 1, 4706: 1, 4707: 1, 4708: 1, 4709: 1, 4710: 1, 4711: 1, 4712: 1, 4713: 1, 4714: 1, 4715: 1, 4716: 1, 4717: 1, 4718: 1, 4719: 1, 4720: 1, 4721: 1, 4722: 1, 4723: 1, 4724: 1, 4725: 1, 4726: 1, 4727: 1, 4728: 1, 4729: 1, 4730: 1, 4731: 1, 4732: 1, 4733: 1, 4734: 2, 4735: 1, 4736: 1, 4737: 2, 4738: 1, 4739: 1, 4740: 1, 4741: 1, 4742: 1, 4743: 1, 4744: 1, 4745: 1, 4746: 2, 4747: 1, 4748: 1, 4749: 1, 4750: 1, 4751: 1, 4752: 1, 4753: 1, 4754: 1, 4755: 1, 4756: 1, 4757: 1, 4758: 1, 4759: 1, 4760: 1, 4761: 1, 4762: 1, 4763: 1, 4764: 1, 4765: 1, 4766: 1, 4767: 1, 4768: 1, 4769: 1, 4770: 1, 4771: 1, 4772: 2, 4773: 1, 4774: 1, 4775: 1, 4776: 1, 4777: 1, 4778: 1, 4779: 1, 4780: 1, 4781: 1, 4782: 3, 4783: 1, 4784: 1, 4785: 1, 4786: 1, 4787: 1, 4788: 1, 4789: 1, 4790: 1, 4791: 1, 4792: 1, 4793: 1, 4794: 1, 4795: 1, 4796: 1, 4797: 1, 4798: 1, 4799: 2, 4800: 1, 4801: 1, 4802: 1, 4803: 1, 4804: 1, 4805: 1, 4806: 1, 4807: 1, 4808: 1, 4809: 1, 4810: 1, 4811: 1, 4812: 1, 4813: 1, 4814: 1, 4815: 1, 4816: 1, 4817: 1, 4818: 1, 4819: 1, 4820: 1, 4821: 1, 4822: 1, 4823: 1, 4824: 1, 4825: 1, 4826: 1, 4827: 1, 4828: 1, 4829: 1, 4830: 1, 4831: 1, 4832: 1, 4833: 1, 4834: 1, 4835: 1, 4836: 1, 4837: 1, 4838: 1, 4839: 1, 4840: 1, 4841: 1, 4842: 1, 4843: 1, 4844: 1, 4845: 1, 4846: 1, 4847: 1, 4848: 1, 4849: 1, 4850: 1, 4851: 1, 4852: 1, 4853: 1, 4854: 1, 4855: 1, 4856: 1, 4857: 1, 4858: 1, 4859: 1, 4860: 1, 4861: 1, 4862: 2, 4863: 1, 4864: 1, 4865: 1, 4866: 1, 4867: 1, 4868: 1, 4869: 1, 4870: 1, 4871: 1, 4872: 1, 4873: 1, 4874: 1, 4875: 1, 4876: 1, 4877: 1, 4878: 1, 4879: 1, 4880: 1, 4881: 1, 4882: 1, 4883: 1, 4884: 1, 4885: 1, 4886: 1, 4887: 1, 4888: 1, 4889: 1, 4890: 1, 4891: 1, 4892: 1, 4893: 1, 4894: 1, 4895: 1, 4896: 1, 4897: 1, 4898: 1, 4899: 1, 4900: 1, 4901: 1, 4902: 1, 4903: 1, 4904: 1, 4905: 1, 4906: 1, 4907: 1, 4908: 1, 4909: 1, 4910: 1, 4911: 1, 4912: 1, 4913: 1, 4914: 1, 4915: 1, 4916: 1, 4917: 1, 4918: 1, 4919: 1, 4920: 1, 4921: 1, 4922: 1, 4923: 1, 4924: 1, 4925: 1, 4926: 1, 4927: 1, 4928: 1, 4929: 1, 4930: 1, 4931: 1, 4932: 1, 4933: 1, 4934: 1, 4935: 1, 4936: 1, 4937: 1, 4938: 2, 4939: 1, 4940: 1, 4941: 1, 4942: 1, 4943: 1, 4944: 1, 4945: 1, 4946: 1, 4947: 1, 4948: 1, 4949: 1, 4950: 1, 4951: 1, 4952: 1, 4953: 1, 4954: 1, 4955: 1, 4956: 1, 4957: 1, 4958: 1, 4959: 1, 4960: 1, 4961: 1, 4962: 1, 4963: 1, 4964: 1, 4965: 1, 4966: 1, 4967: 1, 4968: 1, 4969: 1, 4970: 1, 4971: 1, 4972: 1, 4973: 1, 4974: 1, 4975: 1, 4976: 1, 4977: 1, 4978: 1, 4979: 1, 4980: 1, 4981: 1, 4982: 1, 4983: 1, 4984: 1, 4985: 1, 4986: 1, 4987: 1, 4988: 1, 4989: 1, 4990: 1, 4991: 1, 4992: 1, 4993: 1, 4994: 1, 4995: 1, 4996: 1, 4997: 1, 4998: 1, 4999: 1})

```python

```