diff --git a/AutoDL-Projects/.github/CODE-OF-CONDUCT.md b/AutoDL-Projects/.github/CODE-OF-CONDUCT.md
new file mode 100644
index 0000000..d6c16eb
--- /dev/null
+++ b/AutoDL-Projects/.github/CODE-OF-CONDUCT.md
@@ -0,0 +1,76 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as
+contributors and maintainers pledge to making participation in our project and
+our community a harassment-free experience for everyone, regardless of age, body
+size, disability, ethnicity, sex characteristics, gender identity and expression,
+level of experience, education, socio-economic status, nationality, personal
+appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment
+include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or
+ advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic
+ address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable
+behavior and are expected to take appropriate and fair corrective action in
+response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or
+reject comments, commits, code, wiki edits, issues, and other contributions
+that are not aligned to this Code of Conduct, or to ban temporarily or
+permanently any contributor for other behaviors that they deem inappropriate,
+threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces
+when an individual is representing the project or its community. Examples of
+representing a project or community include using an official project e-mail
+address, posting via an official social media account, or acting as an appointed
+representative at an online or offline event. Representation of a project may be
+further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported by contacting the project team at dongxuanyi888@gmail.com. All
+complaints will be reviewed and investigated and will result in a response that
+is deemed necessary and appropriate to the circumstances. The project team is
+obligated to maintain confidentiality with regard to the reporter of an incident.
+Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good
+faith may face temporary or permanent repercussions as determined by other
+members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
+available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
+
+[homepage]: https://www.contributor-covenant.org
+
+For answers to common questions about this code of conduct, see
+https://www.contributor-covenant.org/faq
diff --git a/AutoDL-Projects/.github/CONTRIBUTING.md b/AutoDL-Projects/.github/CONTRIBUTING.md
new file mode 100644
index 0000000..0cc0ef2
--- /dev/null
+++ b/AutoDL-Projects/.github/CONTRIBUTING.md
@@ -0,0 +1,33 @@
+# Contributing to AutoDL-Projects
+
+:+1::tada: First off, thanks for taking the time to contribute! :tada::+1:
+
+The following is a set of guidelines for contributing to AutoDL-Projects.
+
+## Table Of Contents
+
+[How Can I Contribute?](#how-can-i-contribute)
+ * [Reporting Bugs](#reporting-bugs)
+ * [Suggesting Enhancements](#suggesting-enhancements)
+ * [Your First Code Contribution](#your-first-code-contribution)
+
+## How Can I Contribute?
+
+### Reporting Bugs
+
+This section guides you through submitting a bug report for AutoDL-Projects.
+Following these guidelines helps maintainers and the community understand your report :pencil:, reproduce the behavior :computer: :computer:, and find related reports :mag_right:.
+
+When you are creating a bug report, please include as many details as possible.
+Fill out [the required template](https://github.com/D-X-Y/AutoDL-Projects/blob/main/.github/ISSUE_TEMPLATE/bug-report.md). The information it asks for helps us resolve issues faster.
+
+> **Note:** If you find a **Closed** issue that seems like it is the same thing that you're experiencing, open a new issue and include a link to the original issue in the body of your new one.
+
+### Suggesting Enhancements
+
+Please feel free to email me (dongxuanyi888@gmail.com).
+
+### Your First Code Contribution
+
+Please feel free to open an Pull Requests.
+
diff --git a/AutoDL-Projects/.github/ISSUE_TEMPLATE/bug-report.md b/AutoDL-Projects/.github/ISSUE_TEMPLATE/bug-report.md
new file mode 100644
index 0000000..edaaff7
--- /dev/null
+++ b/AutoDL-Projects/.github/ISSUE_TEMPLATE/bug-report.md
@@ -0,0 +1,24 @@
+---
+name: Bug Report
+about: Create a report to help us improve
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+**Describe the bug**
+A clear and concise description of what the bug is.
+
+**To Reproduce**
+Please provide a small script to reproduce the behavior:
+```
+codes to reproduce the bug
+```
+Please let me know your OS, Python version, PyTorch version.
+
+**Expected behavior**
+A clear and concise description of what you expected to happen.
+
+**Screenshots**
+If applicable, add screenshots to help explain your problem.
diff --git a/AutoDL-Projects/.github/ISSUE_TEMPLATE/question.md b/AutoDL-Projects/.github/ISSUE_TEMPLATE/question.md
new file mode 100644
index 0000000..fbedf5a
--- /dev/null
+++ b/AutoDL-Projects/.github/ISSUE_TEMPLATE/question.md
@@ -0,0 +1,15 @@
+---
+name: Questions w.r.t. an AutoDL algorithm
+about: Ask questions about or discuss on some algorithms
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+**Which Algorithm**
+Please put the title of the AutoDL algorithm that you want to ask here.
+
+**Describe the Question**
+A clear and concise description of what the bug is.
+
diff --git a/AutoDL-Projects/.github/workflows/test-basic.yaml b/AutoDL-Projects/.github/workflows/test-basic.yaml
new file mode 100644
index 0000000..22a747b
--- /dev/null
+++ b/AutoDL-Projects/.github/workflows/test-basic.yaml
@@ -0,0 +1,67 @@
+name: Test Spaces
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+ branches:
+ - main
+
+
+jobs:
+ build:
+ strategy:
+ matrix:
+ os: [ubuntu-18.04, ubuntu-20.04, macos-latest]
+ python-version: [3.6, 3.7, 3.8, 3.9]
+
+ runs-on: ${{ matrix.os }}
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: Set up Python ${{ matrix.python-version }}
+ uses: actions/setup-python@v2
+ with:
+ python-version: ${{ matrix.python-version }}
+
+ - name: Lint with Black
+ run: |
+ python -m pip install black
+ python --version
+ python -m black --version
+ echo $PWD ; ls
+ python -m black ./exps -l 88 --check --diff --verbose
+ python -m black ./tests -l 88 --check --diff --verbose
+ python -m black ./xautodl/x* -l 88 --check --diff --verbose
+ python -m black ./xautodl/spaces -l 88 --check --diff --verbose
+ python -m black ./xautodl/trade_models -l 88 --check --diff --verbose
+ python -m black ./xautodl/procedures -l 88 --check --diff --verbose
+ python -m black ./xautodl/config_utils -l 88 --check --diff --verbose
+ python -m black ./xautodl/log_utils -l 88 --check --diff --verbose
+
+ - name: Install XAutoDL from source
+ run: |
+ pip install .
+
+ - name: Test Search Space
+ run: |
+ python -m pip install pytest
+ python -m pip install torch torchvision
+ python -m pip install parameterized
+ echo $PWD
+ echo "Show what we have here:"
+ ls
+ python --version
+ python -m pytest ./tests/test_import.py -s
+ python -m pytest ./tests/test_basic_space.py -s
+ shell: bash
+
+ - name: Test Math
+ run: |
+ python -m pytest ./tests/test_math*.py -s
+ shell: bash
+
+ - name: Test Synthetic Data
+ run: |
+ python -m pytest ./tests/test_synthetic*.py -s
+ shell: bash
diff --git a/AutoDL-Projects/.github/workflows/test-misc.yaml b/AutoDL-Projects/.github/workflows/test-misc.yaml
new file mode 100644
index 0000000..28776a6
--- /dev/null
+++ b/AutoDL-Projects/.github/workflows/test-misc.yaml
@@ -0,0 +1,41 @@
+name: Test Xmisc
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+ branches:
+ - main
+
+
+jobs:
+ build:
+ strategy:
+ matrix:
+ os: [ubuntu-18.04, ubuntu-20.04, macos-latest]
+ python-version: [3.6, 3.7, 3.8, 3.9]
+
+ runs-on: ${{ matrix.os }}
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: Set up Python ${{ matrix.python-version }}
+ uses: actions/setup-python@v2
+ with:
+ python-version: ${{ matrix.python-version }}
+
+ - name: Install XAutoDL from source
+ run: |
+ pip install .
+
+ - name: Test Xmisc
+ run: |
+ python -m pip install pytest
+ python -m pip install torch torchvision
+ python -m pip install parameterized
+ echo $PWD
+ echo "Show what we have here:"
+ ls
+ python --version
+ python -m pytest ./tests/test_misc* -s
+ shell: bash
diff --git a/AutoDL-Projects/.github/workflows/test-super-layer_model.yaml b/AutoDL-Projects/.github/workflows/test-super-layer_model.yaml
new file mode 100644
index 0000000..31f12ef
--- /dev/null
+++ b/AutoDL-Projects/.github/workflows/test-super-layer_model.yaml
@@ -0,0 +1,42 @@
+name: Test Super Model
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+ branches:
+ - main
+
+
+jobs:
+ build:
+ strategy:
+ matrix:
+ os: [ubuntu-18.04, ubuntu-20.04, macos-latest]
+ python-version: [3.6, 3.7, 3.8, 3.9]
+
+ runs-on: ${{ matrix.os }}
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: Set up Python ${{ matrix.python-version }}
+ uses: actions/setup-python@v2
+ with:
+ python-version: ${{ matrix.python-version }}
+
+ - name: Install XAutoDL from source
+ run: |
+ pip install .
+
+ - name: Test Super Model
+ run: |
+ python -m pip install pytest
+ python -m pip install parameterized
+ python -m pip install torch torchvision
+ python -m pytest ./tests/test_super_*.py
+ shell: bash
+
+ - name: Test TAS (NeurIPS 2019)
+ run: |
+ python -m pytest ./tests/test_tas.py
+ shell: bash
diff --git a/AutoDL-Projects/.gitignore b/AutoDL-Projects/.gitignore
new file mode 100644
index 0000000..6b6c19a
--- /dev/null
+++ b/AutoDL-Projects/.gitignore
@@ -0,0 +1,138 @@
+.DS_Store
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+env/
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib64/
+parts/
+sdist/
+var/
+*.egg-info/
+.installed.cfg
+*.egg
+
+# PyInstaller
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*,cover
+.hypothesis/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+target/
+
+# IPython Notebook
+.ipynb_checkpoints
+
+# pyenv
+.python-version
+
+# celery beat schedule file
+celerybeat-schedule
+
+# dotenv
+.env
+
+# virtualenv
+venv/
+ENV/
+
+# Spyder project settings
+.spyderproject
+
+# Rope project settings
+.ropeproject
+
+# Pycharm project
+.idea
+snapshots
+*.pytorch
+*.tar.bz
+data
+.*.swp
+main_main.py
+*.pdf
+*/*.pdf
+
+# Device
+scripts-nas/.nfs00*
+*/.nfs00*
+*.DS_Store
+
+# logs and snapshots
+output
+logs
+
+# snapshot
+a.pth
+cal-merge*.sh
+GPU-*.sh
+cal.sh
+aaa
+cx.sh
+
+NAS-Bench-*-v1_0.pth
+lib/NAS-Bench-*-v1_0.pth
+others/TF
+scripts-search/l2s-algos
+TEMP-L.sh
+
+.nfs00*
+*.swo
+*/*.swo
+
+# Visual Studio Code
+.vscode
+mlruns*
+outputs
+
+pytest_cache
+*.pkl
+*.pth
+
+*.tgz
diff --git a/AutoDL-Projects/.gitmodules b/AutoDL-Projects/.gitmodules
new file mode 100644
index 0000000..889ea50
--- /dev/null
+++ b/AutoDL-Projects/.gitmodules
@@ -0,0 +1,9 @@
+[submodule ".latent-data/qlib"]
+ path = .latent-data/qlib
+ url = https://github.com/microsoft/qlib.git
+[submodule ".latent-data/NATS-Bench"]
+ path = .latent-data/NATS-Bench
+ url = https://github.com/D-X-Y/NATS-Bench.git
+[submodule ".latent-data/NAS-Bench-201"]
+ path = .latent-data/NAS-Bench-201
+ url = https://github.com/D-X-Y/NAS-Bench-201.git
diff --git a/AutoDL-Projects/CHANGE-LOG.md b/AutoDL-Projects/CHANGE-LOG.md
new file mode 100644
index 0000000..68ac0bc
--- /dev/null
+++ b/AutoDL-Projects/CHANGE-LOG.md
@@ -0,0 +1,12 @@
+# This file shows the major updates of this repo.
+
+- [2020.04.11] [4ef9531](https://github.com/D-X-Y/AutoDL-Projects/tree/4ef9531) Add change log as `CHANGE-LOG.md`.
+- [2019.12.20] [69ca086](https://github.com/D-X-Y/AutoDL-Projects/tree/69ca086) Release NAS-Bench-201.
+- [2019.09.28] [f8f3f38](https://github.com/D-X-Y/AutoDL-Projects/tree/f8f3f38) TAS and SETN codes were publicly released.
+- [2019.01.31] [13e908f](https://github.com/D-X-Y/AutoDL-Projects/tree/13e908f) GDAS codes were publicly released.
+- [2020.07.01] [a45808b](https://github.com/D-X-Y/AutoDL-Projects/tree/a45808b) Upgrade NAS-API to the 2.0 version.
+- [2020.09.16] [7052265](https://github.com/D-X-Y/AutoDL-Projects/tree/7052265) Create NATS-BENCH.
+- [2020.10.15] [446262a](https://github.com/D-X-Y/AutoDL-Projects/tree/446262a) Update NATS-BENCH to version 1.0
+- [2020.12.20] [dae387a](https://github.com/D-X-Y/AutoDL-Projects/tree/dae387a) Update NATS-BENCH to version 1.1
+- [2021.05.18] [98fadf8](https://github.com/D-X-Y/AutoDL-Projects/tree/98fadf8) Before moving to `xautodl`
+- [2021.05.21] [df99173](https://github.com/D-X-Y/AutoDL-Projects/tree/df99173) `xautodl` is close to ready
diff --git a/AutoDL-Projects/LICENSE.md b/AutoDL-Projects/LICENSE.md
new file mode 100644
index 0000000..ed92c61
--- /dev/null
+++ b/AutoDL-Projects/LICENSE.md
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) since 2019.01.01, author: Xuanyi Dong (GitHub: https://github.com/D-X-Y)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/AutoDL-Projects/README.md b/AutoDL-Projects/README.md
new file mode 100644
index 0000000..66b29c7
--- /dev/null
+++ b/AutoDL-Projects/README.md
@@ -0,0 +1,163 @@
+
+
+
+
+---------
+[](LICENSE.md)
+
+Automated Deep Learning Projects (AutoDL-Projects) is an open source, lightweight, but useful project for everyone.
+This project implemented several neural architecture search (NAS) and hyper-parameter optimization (HPO) algorithms.
+中文介绍见[README_CN.md](https://github.com/D-X-Y/AutoDL-Projects/tree/main/docs/README_CN.md)
+
+**Who should consider using AutoDL-Projects**
+
+- Beginners who want to **try different AutoDL algorithms**
+- Engineers who want to **try AutoDL** to investigate whether AutoDL works on your projects
+- Researchers who want to **easily** implement and experiement **new** AutoDL algorithms.
+
+**Why should we use AutoDL-Projects**
+- Simple library dependencies
+- All algorithms are in the same codebase
+- Active maintenance
+
+## AutoDL-Projects Capabilities
+
+At this moment, this project provides the following algorithms and scripts to run them. Please see the details in the link provided in the description column.
+
+
+
+
+
+## Requirements and Preparation
+
+
+**First of all**, please use `pip install .` to install `xautodl` library.
+
+Please install `Python>=3.6` and `PyTorch>=1.5.0`. (You could use lower versions of Python and PyTorch, but may have bugs).
+Some visualization codes may require `opencv`.
+
+CIFAR and ImageNet should be downloaded and extracted into `$TORCH_HOME`.
+Some methods use knowledge distillation (KD), which require pre-trained models. Please download these models from [Google Drive](https://drive.google.com/open?id=1ANmiYEGX-IQZTfH8w0aSpj-Wypg-0DR-) (or train by yourself) and save into `.latent-data`.
+
+Please use
+```
+git clone --recurse-submodules https://github.com/D-X-Y/AutoDL-Projects.git XAutoDL
+```
+to download this repo with submodules.
+
+## Citation
+
+If you find that this project helps your research, please consider citing the related paper:
+```
+@inproceedings{dong2021autohas,
+ title = {{AutoHAS}: Efficient Hyperparameter and Architecture Search},
+ author = {Dong, Xuanyi and Tan, Mingxing and Yu, Adams Wei and Peng, Daiyi and Gabrys, Bogdan and Le, Quoc V},
+ booktitle = {2nd Workshop on Neural Architecture Search at International Conference on Learning Representations (ICLR)},
+ year = {2021}
+}
+@article{dong2021nats,
+ title = {{NATS-Bench}: Benchmarking NAS Algorithms for Architecture Topology and Size},
+ author = {Dong, Xuanyi and Liu, Lu and Musial, Katarzyna and Gabrys, Bogdan},
+ doi = {10.1109/TPAMI.2021.3054824},
+ journal = {IEEE Transactions on Pattern Analysis and Machine Intelligence (TPAMI)},
+ year = {2021},
+ note = {\mbox{doi}:\url{10.1109/TPAMI.2021.3054824}}
+}
+@inproceedings{dong2020nasbench201,
+ title = {{NAS-Bench-201}: Extending the Scope of Reproducible Neural Architecture Search},
+ author = {Dong, Xuanyi and Yang, Yi},
+ booktitle = {International Conference on Learning Representations (ICLR)},
+ url = {https://openreview.net/forum?id=HJxyZkBKDr},
+ year = {2020}
+}
+@inproceedings{dong2019tas,
+ title = {Network Pruning via Transformable Architecture Search},
+ author = {Dong, Xuanyi and Yang, Yi},
+ booktitle = {Neural Information Processing Systems (NeurIPS)},
+ pages = {760--771},
+ year = {2019}
+}
+@inproceedings{dong2019one,
+ title = {One-Shot Neural Architecture Search via Self-Evaluated Template Network},
+ author = {Dong, Xuanyi and Yang, Yi},
+ booktitle = {Proceedings of the IEEE International Conference on Computer Vision (ICCV)},
+ pages = {3681--3690},
+ year = {2019}
+}
+@inproceedings{dong2019search,
+ title = {Searching for A Robust Neural Architecture in Four GPU Hours},
+ author = {Dong, Xuanyi and Yang, Yi},
+ booktitle = {Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},
+ pages = {1761--1770},
+ year = {2019}
+}
+```
+
+# Others
+
+If you want to contribute to this repo, please see [CONTRIBUTING.md](.github/CONTRIBUTING.md).
+Besides, please follow [CODE-OF-CONDUCT.md](.github/CODE-OF-CONDUCT.md).
+
+We use [`black`](https://github.com/psf/black) for Python code formatter.
+Please use `black . -l 88`.
+
+# License
+The entire codebase is under the [MIT license](LICENSE.md).
diff --git a/AutoDL-Projects/configs/NeurIPS-2019/C010-ResNet110.config b/AutoDL-Projects/configs/NeurIPS-2019/C010-ResNet110.config
new file mode 100644
index 0000000..53cd8b5
--- /dev/null
+++ b/AutoDL-Projects/configs/NeurIPS-2019/C010-ResNet110.config
@@ -0,0 +1,13 @@
+{
+ "dataset" : ["str" , "cifar"],
+ "arch" : ["str" , "resnet"],
+ "depth" : ["int" , "110"],
+ "module" : ["str" , "ResNetBasicblock"],
+ "super_type" : ["str" , "infer-shape"],
+ "zero_init_residual" : ["bool" , "0"],
+ "class_num" : ["int" , "10"],
+ "search_mode" : ["str" , "shape"],
+ "xchannels" : ["int" , ["3", "16", "14", "16", "14", "16", "16", "16", "16", "16", "14", "16", "16", "16", "12", "16", "16", "16", "9", "16", "8", "16", "4", "16", "4", "4", "4", "16", "4", "4", "4", "4", "6", "6", "4", "6", "11", "4", "32", "32", "32", "32", "32", "32", "32", "32", "28", "32", "32", "28", "22", "22", "22", "32", "32", "25", "28", "9", "9", "28", "12", "9", "12", "32", "9", "9", "22", "12", "16", "9", "12", "9", "9", "9", "64", "64", "64", "64", "64", "64", "64", "64", "64", "64", "64", "64", "64", "64", "64", "38", "64", "25", "19", "19", "19", "19", "19", "25", "32", "19", "19", "25", "25", "19", "19", "38", "38", "19", "19", "51"]],
+ "xblocks" : ["int" , ["11", "11", "9"]],
+ "estimated_FLOP" : ["float" , "117.498238"]
+}
\ No newline at end of file
diff --git a/AutoDL-Projects/configs/NeurIPS-2019/C010-ResNet164.config b/AutoDL-Projects/configs/NeurIPS-2019/C010-ResNet164.config
new file mode 100644
index 0000000..a305790
--- /dev/null
+++ b/AutoDL-Projects/configs/NeurIPS-2019/C010-ResNet164.config
@@ -0,0 +1,13 @@
+{
+ "dataset" : ["str" , "cifar"],
+ "arch" : ["str" , "resnet"],
+ "depth" : ["int" , "164"],
+ "module" : ["str" , "ResNetBottleneck"],
+ "super_type" : ["str" , "infer-shape"],
+ "zero_init_residual" : ["bool" , "0"],
+ "class_num" : ["int" , "10"],
+ "search_mode" : ["str" , "shape"],
+ "xchannels" : ["int" , ["3", "16", "8", "16", "64", "6", "16", "64", "14", "16", "64", "8", "16", "64", "4", "16", "64", "6", "16", "64", "6", "16", "64", "11", "11", "64", "4", "14", "64", "4", "4", "57", "4", "16", "64", "9", "12", "57", "4", "16", "64", "4", "8", "57", "6", "6", "51", "6", "4", "44", "6", "4", "57", "6", "6", "19", "32", "32", "128", "32", "32", "128", "32", "32", "128", "9", "32", "128", "32", "32", "128", "25", "28", "115", "12", "32", "128", "32", "32", "128", "32", "32", "128", "32", "32", "102", "28", "32", "128", "16", "32", "128", "28", "19", "128", "32", "9", "51", "16", "12", "102", "12", "22", "115", "9", "12", "51", "12", "16", "38", "64", "64", "256", "64", "64", "256", "64", "64", "256", "64", "64", "256", "64", "64", "256", "64", "64", "256", "64", "64", "256", "64", "64", "256", "64", "64", "256", "64", "64", "256", "64", "57", "204", "64", "25", "179", "19", "25", "204", "44", "19", "153", "38", "25", "76", "19", "32", "128", "19", "51", "76", "57", "32", "76"]],
+ "xblocks" : ["int" , ["13", "15", "13"]],
+ "estimated_FLOP" : ["float" , "173.023672"]
+}
\ No newline at end of file
diff --git a/AutoDL-Projects/configs/NeurIPS-2019/C010-ResNet20.config b/AutoDL-Projects/configs/NeurIPS-2019/C010-ResNet20.config
new file mode 100644
index 0000000..c22368d
--- /dev/null
+++ b/AutoDL-Projects/configs/NeurIPS-2019/C010-ResNet20.config
@@ -0,0 +1,13 @@
+{
+ "dataset" : ["str" , "cifar"],
+ "arch" : ["str" , "resnet"],
+ "depth" : ["int" , "20"],
+ "module" : ["str" , "ResNetBasicblock"],
+ "super_type" : ["str" , "infer-shape"],
+ "zero_init_residual" : ["bool" , "0"],
+ "class_num" : ["int" , "10"],
+ "search_mode" : ["str" , "shape"],
+ "xchannels" : ["int" , ["3", "16", "6", "4", "4", "4", "4", "4", "32", "32", "12", "19", "32", "28", "64", "64", "64", "64", "64", "44"]],
+ "xblocks" : ["int" , ["3", "3", "3"]],
+ "estimated_FLOP" : ["float" , "22.444472"]
+}
\ No newline at end of file
diff --git a/AutoDL-Projects/configs/NeurIPS-2019/C010-ResNet32.config b/AutoDL-Projects/configs/NeurIPS-2019/C010-ResNet32.config
new file mode 100644
index 0000000..dbdef77
--- /dev/null
+++ b/AutoDL-Projects/configs/NeurIPS-2019/C010-ResNet32.config
@@ -0,0 +1,13 @@
+{
+ "dataset" : ["str" , "cifar"],
+ "arch" : ["str" , "resnet"],
+ "depth" : ["int" , "32"],
+ "module" : ["str" , "ResNetBasicblock"],
+ "super_type" : ["str" , "infer-shape"],
+ "zero_init_residual" : ["bool" , "0"],
+ "class_num" : ["int" , "10"],
+ "search_mode" : ["str" , "shape"],
+ "xchannels" : ["int" , ["3", "16", "6", "4", "12", "4", "4", "16", "9", "9", "6", "14", "32", "32", "9", "19", "28", "9", "32", "19", "32", "9", "64", "64", "64", "64", "64", "64", "64", "32", "38", "32"]],
+ "xblocks" : ["int" , ["5", "5", "5"]],
+ "estimated_FLOP" : ["float" , "34.945344"]
+}
\ No newline at end of file
diff --git a/AutoDL-Projects/configs/NeurIPS-2019/C010-ResNet56.config b/AutoDL-Projects/configs/NeurIPS-2019/C010-ResNet56.config
new file mode 100644
index 0000000..c35ed70
--- /dev/null
+++ b/AutoDL-Projects/configs/NeurIPS-2019/C010-ResNet56.config
@@ -0,0 +1,13 @@
+{
+ "dataset" : ["str" , "cifar"],
+ "arch" : ["str" , "resnet"],
+ "depth" : ["int" , "56"],
+ "module" : ["str" , "ResNetBasicblock"],
+ "super_type" : ["str" , "infer-shape"],
+ "zero_init_residual" : ["bool" , "0"],
+ "class_num" : ["int" , "10"],
+ "search_mode" : ["str" , "shape"],
+ "xchannels" : ["int" , ["3", "16", "16", "16", "14", "11", "9", "16", "12", "16", "6", "16", "4", "8", "4", "14", "6", "4", "4", "4", "32", "32", "32", "32", "32", "32", "22", "28", "32", "32", "19", "9", "19", "16", "9", "25", "16", "9", "64", "64", "64", "64", "64", "64", "64", "64", "64", "51", "19", "19", "32", "19", "19", "32", "19", "25"]],
+ "xblocks" : ["int" , ["5", "5", "5"]],
+ "estimated_FLOP" : ["float" , "57.93305"]
+}
\ No newline at end of file
diff --git a/AutoDL-Projects/configs/NeurIPS-2019/C100-ResNet110.config b/AutoDL-Projects/configs/NeurIPS-2019/C100-ResNet110.config
new file mode 100644
index 0000000..a4083e7
--- /dev/null
+++ b/AutoDL-Projects/configs/NeurIPS-2019/C100-ResNet110.config
@@ -0,0 +1,13 @@
+{
+ "dataset" : ["str" , "cifar"],
+ "arch" : ["str" , "resnet"],
+ "depth" : ["int" , "110"],
+ "module" : ["str" , "ResNetBasicblock"],
+ "super_type" : ["str" , "infer-shape"],
+ "zero_init_residual" : ["bool" , "0"],
+ "class_num" : ["int" , "100"],
+ "search_mode" : ["str" , "shape"],
+ "xchannels" : ["int" , ["3", "16", "14", "16", "11", "14", "16", "16", "11", "16", "9", "14", "12", "16", "16", "16", "8", "16", "14", "16", "12", "4", "11", "16", "4", "4", "4", "16", "12", "4", "8", "4", "9", "4", "6", "14", "4", "4", "32", "32", "32", "32", "28", "28", "32", "32", "32", "32", "32", "28", "32", "28", "25", "32", "32", "32", "9", "9", "32", "32", "9", "25", "28", "32", "28", "9", "9", "32", "12", "12", "9", "22", "12", "9", "64", "64", "64", "64", "64", "64", "64", "64", "64", "64", "64", "64", "64", "64", "64", "44", "64", "57", "19", "19", "19", "19", "25", "19", "25", "19", "25", "19", "19", "25", "19", "19", "19", "25", "25", "19"]],
+ "xblocks" : ["int" , ["13", "9", "11"]],
+ "estimated_FLOP" : ["float" , "117.653164"]
+}
\ No newline at end of file
diff --git a/AutoDL-Projects/configs/NeurIPS-2019/C100-ResNet164.config b/AutoDL-Projects/configs/NeurIPS-2019/C100-ResNet164.config
new file mode 100644
index 0000000..4401483
--- /dev/null
+++ b/AutoDL-Projects/configs/NeurIPS-2019/C100-ResNet164.config
@@ -0,0 +1,13 @@
+{
+ "dataset" : ["str" , "cifar"],
+ "arch" : ["str" , "resnet"],
+ "depth" : ["int" , "164"],
+ "module" : ["str" , "ResNetBottleneck"],
+ "super_type" : ["str" , "infer-shape"],
+ "zero_init_residual" : ["bool" , "0"],
+ "class_num" : ["int" , "100"],
+ "search_mode" : ["str" , "shape"],
+ "xchannels" : ["int" , ["3", "16", "16", "16", "57", "6", "11", "64", "4", "6", "51", "6", "9", "64", "4", "8", "64", "4", "14", "64", "4", "8", "64", "4", "8", "64", "6", "12", "64", "6", "16", "64", "8", "16", "64", "14", "12", "64", "4", "16", "64", "4", "14", "64", "11", "16", "64", "4", "14", "64", "11", "4", "64", "4", "4", "19", "25", "32", "128", "28", "32", "115", "28", "32", "128", "25", "32", "128", "32", "32", "128", "25", "32", "128", "12", "32", "128", "25", "32", "128", "28", "32", "128", "25", "28", "128", "32", "32", "128", "28", "19", "128", "32", "32", "128", "19", "28", "128", "9", "19", "128", "28", "9", "89", "28", "19", "128", "9", "16", "38", "64", "64", "256", "64", "64", "256", "64", "64", "256", "64", "64", "256", "64", "64", "256", "64", "64", "256", "64", "64", "256", "64", "64", "256", "64", "64", "256", "64", "64", "204", "64", "64", "179", "64", "64", "102", "64", "64", "102", "44", "19", "76", "19", "19", "76", "19", "38", "76", "25", "38", "153", "44", "25", "230"]],
+ "xblocks" : ["int" , ["15", "15", "15"]],
+ "estimated_FLOP" : ["float" , "165.583512"]
+}
\ No newline at end of file
diff --git a/AutoDL-Projects/configs/NeurIPS-2019/C100-ResNet20.config b/AutoDL-Projects/configs/NeurIPS-2019/C100-ResNet20.config
new file mode 100644
index 0000000..080424e
--- /dev/null
+++ b/AutoDL-Projects/configs/NeurIPS-2019/C100-ResNet20.config
@@ -0,0 +1,13 @@
+{
+ "dataset" : ["str" , "cifar"],
+ "arch" : ["str" , "resnet"],
+ "depth" : ["int" , "20"],
+ "module" : ["str" , "ResNetBasicblock"],
+ "super_type" : ["str" , "infer-shape"],
+ "zero_init_residual" : ["bool" , "0"],
+ "class_num" : ["int" , "100"],
+ "search_mode" : ["str" , "shape"],
+ "xchannels" : ["int" , ["3", "16", "4", "4", "4", "4", "6", "4", "32", "32", "9", "19", "32", "28", "64", "64", "64", "64", "64", "64"]],
+ "xblocks" : ["int" , ["3", "3", "3"]],
+ "estimated_FLOP" : ["float" , "22.433792"]
+}
\ No newline at end of file
diff --git a/AutoDL-Projects/configs/NeurIPS-2019/C100-ResNet32.config b/AutoDL-Projects/configs/NeurIPS-2019/C100-ResNet32.config
new file mode 100644
index 0000000..2ca3087
--- /dev/null
+++ b/AutoDL-Projects/configs/NeurIPS-2019/C100-ResNet32.config
@@ -0,0 +1,12 @@
+{
+ "dataset" : ["str" , "cifar"],
+ "arch" : ["str" , "resnet"],
+ "depth" : ["int" , "32"],
+ "module" : ["str" , "ResNetBasicblock"],
+ "super_type" : ["str" , "infer-shape"],
+ "zero_init_residual" : ["bool" , "0"],
+ "class_num" : ["int" , "100"],
+ "xchannels" : ["int" , ["3", "16", "4", "4", "6", "11", "6", "4", "8", "4", "4", "4", "32", "32", "9", "28", "28", "28", "28", "28", "32", "32", "64", "64", "64", "64", "64", "64", "64", "64", "64", "64"]],
+ "xblocks" : ["int" , ["5", "5", "5"]],
+ "estimated_FLOP" : ["float" , "42.47"]
+}
diff --git a/AutoDL-Projects/configs/NeurIPS-2019/C100-ResNet56.config b/AutoDL-Projects/configs/NeurIPS-2019/C100-ResNet56.config
new file mode 100644
index 0000000..3baa0e7
--- /dev/null
+++ b/AutoDL-Projects/configs/NeurIPS-2019/C100-ResNet56.config
@@ -0,0 +1,13 @@
+{
+ "dataset" : ["str" , "cifar"],
+ "arch" : ["str" , "resnet"],
+ "depth" : ["int" , "56"],
+ "module" : ["str" , "ResNetBasicblock"],
+ "super_type" : ["str" , "infer-shape"],
+ "zero_init_residual" : ["bool" , "0"],
+ "class_num" : ["int" , "100"],
+ "search_mode" : ["str" , "shape"],
+ "xchannels" : ["int" , ["3", "16", "16", "9", "14", "16", "14", "16", "8", "16", "8", "14", "4", "4", "4", "8", "4", "6", "4", "4", "32", "32", "32", "28", "32", "32", "32", "22", "32", "32", "32", "9", "25", "19", "25", "12", "9", "9", "64", "64", "64", "64", "64", "64", "64", "64", "64", "51", "19", "19", "19", "19", "25", "38", "19", "19"]],
+ "xblocks" : ["int" , ["5", "5", "7"]],
+ "estimated_FLOP" : ["float" , "59.472556"]
+}
\ No newline at end of file
diff --git a/AutoDL-Projects/configs/NeurIPS-2019/ImageNet-ResNet18V1.config b/AutoDL-Projects/configs/NeurIPS-2019/ImageNet-ResNet18V1.config
new file mode 100644
index 0000000..9a0ab7d
--- /dev/null
+++ b/AutoDL-Projects/configs/NeurIPS-2019/ImageNet-ResNet18V1.config
@@ -0,0 +1,14 @@
+{
+ "dataset" : ["str" , "imagenet"],
+ "arch" : ["str" , "resnet"],
+ "block_name" : ["str" , "BasicBlock"],
+ "layers" : ["int" , ["2", "2", "2", "2"]],
+ "deep_stem" : ["bool" , "0"],
+ "zero_init_residual" : ["bool" , "1"],
+ "class_num" : ["int" , "1000"],
+ "search_mode" : ["str" , "shape"],
+ "xchannels" : ["int" , ["3", "64", "25", "64", "38", "19", "128", "128", "38", "38", "256", "256", "256", "256", "512", "512", "512", "512"]],
+ "xblocks" : ["int" , ["1", "1", "2", "2"]],
+ "super_type" : ["str" , "infer-shape"],
+ "estimated_FLOP" : ["float" , "1120.44032"]
+}
\ No newline at end of file
diff --git a/AutoDL-Projects/configs/NeurIPS-2019/ImageNet-ResNet50V1.config b/AutoDL-Projects/configs/NeurIPS-2019/ImageNet-ResNet50V1.config
new file mode 100644
index 0000000..2d04b7d
--- /dev/null
+++ b/AutoDL-Projects/configs/NeurIPS-2019/ImageNet-ResNet50V1.config
@@ -0,0 +1,14 @@
+{
+ "dataset" : ["str" , "imagenet"],
+ "arch" : ["str" , "resnet"],
+ "block_name" : ["str" , "Bottleneck"],
+ "layers" : ["int" , ["3", "4", "6", "3"]],
+ "deep_stem" : ["bool" , "0"],
+ "zero_init_residual" : ["bool" , "1"],
+ "class_num" : ["int" , "1000"],
+ "search_mode" : ["str" , "shape"],
+ "xchannels" : ["int" , ["3", "45", "45", "30", "102", "33", "60", "154", "68", "70", "180", "38", "38", "307", "38", "38", "410", "64", "128", "358", "38", "51", "256", "76", "76", "512", "76", "76", "512", "179", "256", "614", "100", "102", "307", "179", "230", "614", "204", "102", "307", "153", "153", "1228", "512", "512", "1434", "512", "512", "1844"]],
+ "xblocks" : ["int" , ["3", "4", "5", "3"]],
+ "super_type" : ["str" , "infer-shape"],
+ "estimated_FLOP" : ["float" , "2291.316289"]
+}
diff --git a/AutoDL-Projects/configs/archs/CIFAR-ResNet08.config b/AutoDL-Projects/configs/archs/CIFAR-ResNet08.config
new file mode 100644
index 0000000..113fe69
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/CIFAR-ResNet08.config
@@ -0,0 +1,8 @@
+{
+ "dataset" : ["str", "cifar"],
+ "arch" : ["str", "resnet"],
+ "depth" : ["int", 8],
+ "module" : ["str", "ResNetBasicblock"],
+ "super_type": ["str" , "basic"],
+ "zero_init_residual" : ["bool", "0"]
+}
diff --git a/AutoDL-Projects/configs/archs/CIFAR-ResNet1001.config b/AutoDL-Projects/configs/archs/CIFAR-ResNet1001.config
new file mode 100644
index 0000000..451c152
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/CIFAR-ResNet1001.config
@@ -0,0 +1,8 @@
+{
+ "dataset" : ["str", "cifar"],
+ "arch" : ["str", "resnet"],
+ "depth" : ["int", 1001],
+ "module" : ["str", "ResNetBottleneck"],
+ "super_type": ["str" , "basic"],
+ "zero_init_residual" : ["bool", "0"]
+}
diff --git a/AutoDL-Projects/configs/archs/CIFAR-ResNet110.config b/AutoDL-Projects/configs/archs/CIFAR-ResNet110.config
new file mode 100644
index 0000000..65f1fb6
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/CIFAR-ResNet110.config
@@ -0,0 +1,8 @@
+{
+ "dataset" : ["str", "cifar"],
+ "arch" : ["str", "resnet"],
+ "depth" : ["int", 110],
+ "module" : ["str", "ResNetBasicblock"],
+ "super_type": ["str" , "basic"],
+ "zero_init_residual" : ["bool", "0"]
+}
diff --git a/AutoDL-Projects/configs/archs/CIFAR-ResNet164.config b/AutoDL-Projects/configs/archs/CIFAR-ResNet164.config
new file mode 100644
index 0000000..c563971
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/CIFAR-ResNet164.config
@@ -0,0 +1,8 @@
+{
+ "dataset" : ["str", "cifar"],
+ "arch" : ["str", "resnet"],
+ "depth" : ["int", 164],
+ "module" : ["str", "ResNetBottleneck"],
+ "super_type": ["str" , "basic"],
+ "zero_init_residual" : ["bool", "0"]
+}
diff --git a/AutoDL-Projects/configs/archs/CIFAR-ResNet20.config b/AutoDL-Projects/configs/archs/CIFAR-ResNet20.config
new file mode 100644
index 0000000..91b1539
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/CIFAR-ResNet20.config
@@ -0,0 +1,8 @@
+{
+ "dataset" : ["str", "cifar"],
+ "arch" : ["str", "resnet"],
+ "depth" : ["int", 20],
+ "module" : ["str", "ResNetBasicblock"],
+ "super_type": ["str" , "basic"],
+ "zero_init_residual" : ["bool", "0"]
+}
diff --git a/AutoDL-Projects/configs/archs/CIFAR-ResNet32.config b/AutoDL-Projects/configs/archs/CIFAR-ResNet32.config
new file mode 100644
index 0000000..afccb8d
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/CIFAR-ResNet32.config
@@ -0,0 +1,8 @@
+{
+ "dataset" : ["str", "cifar"],
+ "arch" : ["str", "resnet"],
+ "depth" : ["int", 32],
+ "module" : ["str", "ResNetBasicblock"],
+ "super_type": ["str" , "basic"],
+ "zero_init_residual" : ["bool", "0"]
+}
diff --git a/AutoDL-Projects/configs/archs/CIFAR-ResNet56.config b/AutoDL-Projects/configs/archs/CIFAR-ResNet56.config
new file mode 100644
index 0000000..dc4ca92
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/CIFAR-ResNet56.config
@@ -0,0 +1,8 @@
+{
+ "dataset" : ["str", "cifar"],
+ "arch" : ["str", "resnet"],
+ "depth" : ["int", 56],
+ "module" : ["str", "ResNetBasicblock"],
+ "super_type": ["str" , "basic"],
+ "zero_init_residual" : ["bool", "0"]
+}
diff --git a/AutoDL-Projects/configs/archs/CIFAR-SIM05.config b/AutoDL-Projects/configs/archs/CIFAR-SIM05.config
new file mode 100644
index 0000000..c0f6f7b
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/CIFAR-SIM05.config
@@ -0,0 +1,7 @@
+{
+ "dataset" : ["str", "cifar"],
+ "arch" : ["str", "simres"],
+ "depth" : ["int", 5],
+ "super_type": ["str" , "basic"],
+ "zero_init_residual" : ["bool", "0"]
+}
diff --git a/AutoDL-Projects/configs/archs/CIFAR-WRN28-10.config b/AutoDL-Projects/configs/archs/CIFAR-WRN28-10.config
new file mode 100644
index 0000000..839ef9c
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/CIFAR-WRN28-10.config
@@ -0,0 +1,8 @@
+{
+ "dataset" : ["str", "cifar"],
+ "arch" : ["str", "wideresnet"],
+ "depth" : ["int", 28],
+ "wide_factor":["int", 10],
+ "dropout" : ["bool", 0],
+ "super_type": ["str" , "basic"]
+}
diff --git a/AutoDL-Projects/configs/archs/ImageNet-ResNet101V1.config b/AutoDL-Projects/configs/archs/ImageNet-ResNet101V1.config
new file mode 100644
index 0000000..9411eea
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/ImageNet-ResNet101V1.config
@@ -0,0 +1,12 @@
+{
+ "dataset" : ["str", "imagenet"],
+ "arch" : ["str", "resnet"],
+ "block_name" : ["str", "Bottleneck"],
+ "layers" : ["int", [3,4,23,3]],
+ "deep_stem" : ["bool", 0],
+ "zero_init_residual" : ["bool", "1"],
+ "groups" : ["int", 1],
+ "width_per_group" : ["int", 64],
+ "norm_layer" : ["none", "None"]
+
+}
diff --git a/AutoDL-Projects/configs/archs/ImageNet-ResNet101V2.config b/AutoDL-Projects/configs/archs/ImageNet-ResNet101V2.config
new file mode 100644
index 0000000..7117dba
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/ImageNet-ResNet101V2.config
@@ -0,0 +1,12 @@
+{
+ "dataset" : ["str", "imagenet"],
+ "arch" : ["str", "resnet"],
+ "block_name" : ["str", "Bottleneck"],
+ "layers" : ["int", [3,4,23,3]],
+ "deep_stem" : ["bool", 1],
+ "zero_init_residual" : ["bool", "1"],
+ "groups" : ["int", 1],
+ "width_per_group" : ["int", 64],
+ "norm_layer" : ["none", "None"]
+
+}
diff --git a/AutoDL-Projects/configs/archs/ImageNet-ResNet152V1.config b/AutoDL-Projects/configs/archs/ImageNet-ResNet152V1.config
new file mode 100644
index 0000000..542aa3d
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/ImageNet-ResNet152V1.config
@@ -0,0 +1,11 @@
+{
+ "dataset" : ["str", "imagenet"],
+ "arch" : ["str", "resnet"],
+ "block_name" : ["str", "Bottleneck"],
+ "layers" : ["int", [3,8,36,3]],
+ "deep_stem" : ["bool", 0],
+ "zero_init_residual" : ["bool", "1"],
+ "groups" : ["int", 1],
+ "width_per_group" : ["int", 64],
+ "norm_layer" : ["none", "None"]
+}
diff --git a/AutoDL-Projects/configs/archs/ImageNet-ResNet152V2.config b/AutoDL-Projects/configs/archs/ImageNet-ResNet152V2.config
new file mode 100644
index 0000000..3d83504
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/ImageNet-ResNet152V2.config
@@ -0,0 +1,11 @@
+{
+ "dataset" : ["str", "imagenet"],
+ "arch" : ["str", "resnet"],
+ "block_name" : ["str", "Bottleneck"],
+ "layers" : ["int", [3,8,36,3]],
+ "deep_stem" : ["bool", 1],
+ "zero_init_residual" : ["bool", "1"],
+ "groups" : ["int", 1],
+ "width_per_group" : ["int", 64],
+ "norm_layer" : ["none", "None"]
+}
diff --git a/AutoDL-Projects/configs/archs/ImageNet-ResNet18V1.config b/AutoDL-Projects/configs/archs/ImageNet-ResNet18V1.config
new file mode 100644
index 0000000..36f5b8d
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/ImageNet-ResNet18V1.config
@@ -0,0 +1,11 @@
+{
+ "dataset" : ["str", "imagenet"],
+ "arch" : ["str", "resnet"],
+ "block_name" : ["str", "BasicBlock"],
+ "layers" : ["int", [2,2,2,2]],
+ "deep_stem" : ["bool", 0],
+ "zero_init_residual" : ["bool", "1"],
+ "groups" : ["int", 1],
+ "width_per_group" : ["int", 64],
+ "norm_layer" : ["none", "None"]
+}
diff --git a/AutoDL-Projects/configs/archs/ImageNet-ResNet18V2.config b/AutoDL-Projects/configs/archs/ImageNet-ResNet18V2.config
new file mode 100644
index 0000000..f14652a
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/ImageNet-ResNet18V2.config
@@ -0,0 +1,12 @@
+{
+ "dataset" : ["str", "imagenet"],
+ "arch" : ["str", "resnet"],
+ "block_name" : ["str", "BasicBlock"],
+ "layers" : ["int", [2,2,2,2]],
+ "deep_stem" : ["bool", 1],
+ "zero_init_residual" : ["bool", "1"],
+ "groups" : ["int", 1],
+ "width_per_group" : ["int", 64],
+ "norm_layer" : ["none", "None"]
+
+}
diff --git a/AutoDL-Projects/configs/archs/ImageNet-ResNet200V1.config b/AutoDL-Projects/configs/archs/ImageNet-ResNet200V1.config
new file mode 100644
index 0000000..87cd261
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/ImageNet-ResNet200V1.config
@@ -0,0 +1,11 @@
+{
+ "dataset" : ["str", "imagenet"],
+ "arch" : ["str", "resnet"],
+ "block_name" : ["str", "Bottleneck"],
+ "layers" : ["int", [3,24,36,3]],
+ "deep_stem" : ["bool", 0],
+ "zero_init_residual" : ["bool", "1"],
+ "groups" : ["int", 1],
+ "width_per_group" : ["int", 64],
+ "norm_layer" : ["none", "None"]
+}
diff --git a/AutoDL-Projects/configs/archs/ImageNet-ResNet200V2.config b/AutoDL-Projects/configs/archs/ImageNet-ResNet200V2.config
new file mode 100644
index 0000000..002a1ed
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/ImageNet-ResNet200V2.config
@@ -0,0 +1,11 @@
+{
+ "dataset" : ["str", "imagenet"],
+ "arch" : ["str", "resnet"],
+ "block_name" : ["str", "Bottleneck"],
+ "layers" : ["int", [3,24,36,3]],
+ "deep_stem" : ["bool", 1],
+ "zero_init_residual" : ["bool", "1"],
+ "groups" : ["int", 1],
+ "width_per_group" : ["int", 64],
+ "norm_layer" : ["none", "None"]
+}
diff --git a/AutoDL-Projects/configs/archs/ImageNet-ResNet34V1.config b/AutoDL-Projects/configs/archs/ImageNet-ResNet34V1.config
new file mode 100644
index 0000000..faef519
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/ImageNet-ResNet34V1.config
@@ -0,0 +1,12 @@
+{
+ "dataset" : ["str", "imagenet"],
+ "arch" : ["str", "resnet"],
+ "block_name" : ["str", "BasicBlock"],
+ "layers" : ["int", [3,4,6,3]],
+ "deep_stem" : ["bool", 0],
+ "zero_init_residual" : ["bool", "1"],
+ "groups" : ["int", 1],
+ "width_per_group" : ["int", 64],
+ "norm_layer" : ["none", "None"]
+
+}
diff --git a/AutoDL-Projects/configs/archs/ImageNet-ResNet34V2.config b/AutoDL-Projects/configs/archs/ImageNet-ResNet34V2.config
new file mode 100644
index 0000000..cccee3b
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/ImageNet-ResNet34V2.config
@@ -0,0 +1,12 @@
+{
+ "dataset" : ["str", "imagenet"],
+ "arch" : ["str", "resnet"],
+ "block_name" : ["str", "BasicBlock"],
+ "layers" : ["int", [3,4,6,3]],
+ "deep_stem" : ["bool", 1],
+ "zero_init_residual" : ["bool", "1"],
+ "groups" : ["int", 1],
+ "width_per_group" : ["int", 64],
+ "norm_layer" : ["none", "None"]
+
+}
diff --git a/AutoDL-Projects/configs/archs/ImageNet-ResNet50V1.config b/AutoDL-Projects/configs/archs/ImageNet-ResNet50V1.config
new file mode 100644
index 0000000..62b0c28
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/ImageNet-ResNet50V1.config
@@ -0,0 +1,12 @@
+{
+ "dataset" : ["str", "imagenet"],
+ "arch" : ["str", "resnet"],
+ "block_name" : ["str", "Bottleneck"],
+ "layers" : ["int", [3,4,6,3]],
+ "deep_stem" : ["bool", 0],
+ "zero_init_residual" : ["bool", "1"],
+ "groups" : ["int", 1],
+ "width_per_group" : ["int", 64],
+ "norm_layer" : ["none", "None"]
+
+}
diff --git a/AutoDL-Projects/configs/archs/ImageNet-ResNet50V2.config b/AutoDL-Projects/configs/archs/ImageNet-ResNet50V2.config
new file mode 100644
index 0000000..52f8899
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/ImageNet-ResNet50V2.config
@@ -0,0 +1,12 @@
+{
+ "dataset" : ["str", "imagenet"],
+ "arch" : ["str", "resnet"],
+ "block_name" : ["str", "Bottleneck"],
+ "layers" : ["int", [3,4,6,3]],
+ "deep_stem" : ["bool", 1],
+ "zero_init_residual" : ["bool", "1"],
+ "groups" : ["int", 1],
+ "width_per_group" : ["int", 64],
+ "norm_layer" : ["none", "None"]
+
+}
diff --git a/AutoDL-Projects/configs/archs/ImageNet-ResNext50-32x4dV2.config b/AutoDL-Projects/configs/archs/ImageNet-ResNext50-32x4dV2.config
new file mode 100644
index 0000000..4b027c4
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/ImageNet-ResNext50-32x4dV2.config
@@ -0,0 +1,12 @@
+{
+ "dataset" : ["str", "imagenet"],
+ "arch" : ["str", "resnet"],
+ "block_name" : ["str", "Bottleneck"],
+ "layers" : ["int", [3,4,6,3]],
+ "deep_stem" : ["bool", 1],
+ "zero_init_residual" : ["bool", "1"],
+ "groups" : ["int", 32],
+ "width_per_group" : ["int", 4],
+ "norm_layer" : ["none", "None"]
+
+}
diff --git a/AutoDL-Projects/configs/archs/NAS-CIFAR-DARTS.config b/AutoDL-Projects/configs/archs/NAS-CIFAR-DARTS.config
new file mode 100644
index 0000000..f19dc28
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/NAS-CIFAR-DARTS.config
@@ -0,0 +1,10 @@
+{
+ "arch" : ["str", "dxys"],
+ "genotype" : ["str", "DARTS"],
+ "dataset" : ["str", "cifar"],
+ "ichannel" : ["int", 36],
+ "layers" : ["int", 6],
+ "stem_multi": ["int", 3],
+ "auxiliary" : ["bool", 1],
+ "drop_path_prob": ["float", 0.2]
+}
diff --git a/AutoDL-Projects/configs/archs/NAS-CIFAR-GDAS_V1.config b/AutoDL-Projects/configs/archs/NAS-CIFAR-GDAS_V1.config
new file mode 100644
index 0000000..4338936
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/NAS-CIFAR-GDAS_V1.config
@@ -0,0 +1,10 @@
+{
+ "arch" : ["str", "dxys"],
+ "genotype" : ["str", "GDAS_V1"],
+ "dataset" : ["str", "cifar"],
+ "ichannel" : ["int", 36],
+ "layers" : ["int", 6],
+ "stem_multi": ["int", 3],
+ "auxiliary" : ["bool", 1],
+ "drop_path_prob": ["float", 0.2]
+}
diff --git a/AutoDL-Projects/configs/archs/NAS-CIFAR-NAS.config b/AutoDL-Projects/configs/archs/NAS-CIFAR-NAS.config
new file mode 100644
index 0000000..4911e18
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/NAS-CIFAR-NAS.config
@@ -0,0 +1,10 @@
+{
+ "arch" : ["str", "dxys"],
+ "genotype" : ["str", "NASNet"],
+ "dataset" : ["str", "cifar"],
+ "ichannel" : ["int", 33],
+ "layers" : ["int", 6],
+ "stem_multi": ["int", 3],
+ "auxiliary" : ["bool", 1],
+ "drop_path_prob": ["float", 0.2]
+}
diff --git a/AutoDL-Projects/configs/archs/NAS-CIFAR-SETN.config b/AutoDL-Projects/configs/archs/NAS-CIFAR-SETN.config
new file mode 100644
index 0000000..878d91b
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/NAS-CIFAR-SETN.config
@@ -0,0 +1,10 @@
+{
+ "arch" : ["str", "dxys"],
+ "genotype" : ["str", "SETN"],
+ "dataset" : ["str", "cifar"],
+ "ichannel" : ["int", 36],
+ "layers" : ["int", 6],
+ "stem_multi": ["int", 3],
+ "auxiliary" : ["bool", 1],
+ "drop_path_prob": ["float", 0.2]
+}
diff --git a/AutoDL-Projects/configs/archs/NAS-CIFAR-none.config b/AutoDL-Projects/configs/archs/NAS-CIFAR-none.config
new file mode 100644
index 0000000..52b3bfd
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/NAS-CIFAR-none.config
@@ -0,0 +1,10 @@
+{
+ "super_type": ["str", "infer-nasnet.cifar"],
+ "genotype" : ["none", "none"],
+ "dataset" : ["str", "cifar"],
+ "ichannel" : ["int", 33],
+ "layers" : ["int", 6],
+ "stem_multi": ["int", 3],
+ "auxiliary" : ["bool", 1],
+ "drop_path_prob": ["float", 0.2]
+}
diff --git a/AutoDL-Projects/configs/archs/NAS-IMAGENET-DARTS_V2.config b/AutoDL-Projects/configs/archs/NAS-IMAGENET-DARTS_V2.config
new file mode 100644
index 0000000..0b0745e
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/NAS-IMAGENET-DARTS_V2.config
@@ -0,0 +1,9 @@
+{
+ "arch" : ["str", "dxys"],
+ "genotype" : ["str", "DARTS_V2"],
+ "dataset" : ["str", "imagenet"],
+ "ichannel" : ["int", 48],
+ "layers" : ["int", 4],
+ "auxiliary" : ["bool", 1],
+ "drop_path_prob": ["float", 0]
+}
diff --git a/AutoDL-Projects/configs/archs/NAS-IMAGENET-GDAS_V1.config b/AutoDL-Projects/configs/archs/NAS-IMAGENET-GDAS_V1.config
new file mode 100644
index 0000000..d17b865
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/NAS-IMAGENET-GDAS_V1.config
@@ -0,0 +1,9 @@
+{
+ "arch" : ["str", "dxys"],
+ "genotype" : ["str", "GDAS_V1"],
+ "dataset" : ["str", "imagenet"],
+ "ichannel" : ["int", 50],
+ "layers" : ["int", 4],
+ "auxiliary" : ["bool", 1],
+ "drop_path_prob": ["float", 0]
+}
diff --git a/AutoDL-Projects/configs/archs/NAS-IMAGENET-SETN.config b/AutoDL-Projects/configs/archs/NAS-IMAGENET-SETN.config
new file mode 100644
index 0000000..5112135
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/NAS-IMAGENET-SETN.config
@@ -0,0 +1,9 @@
+{
+ "arch" : ["str", "dxys"],
+ "genotype" : ["str", "SETN"],
+ "dataset" : ["str", "imagenet"],
+ "ichannel" : ["int", 58],
+ "layers" : ["int", 2],
+ "auxiliary" : ["bool", 1],
+ "drop_path_prob": ["float", 0]
+}
diff --git a/AutoDL-Projects/configs/archs/NAS-IMAGENET-SETN1.config b/AutoDL-Projects/configs/archs/NAS-IMAGENET-SETN1.config
new file mode 100644
index 0000000..8a3317a
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/NAS-IMAGENET-SETN1.config
@@ -0,0 +1,9 @@
+{
+ "arch" : ["str", "dxys"],
+ "genotype" : ["str", "SETN"],
+ "dataset" : ["str", "imagenet"],
+ "ichannel" : ["int", 73],
+ "layers" : ["int", 1],
+ "auxiliary" : ["bool", 1],
+ "drop_path_prob": ["float", 0]
+}
diff --git a/AutoDL-Projects/configs/archs/NAS-IMAGENET-SETN2.config b/AutoDL-Projects/configs/archs/NAS-IMAGENET-SETN2.config
new file mode 100644
index 0000000..5112135
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/NAS-IMAGENET-SETN2.config
@@ -0,0 +1,9 @@
+{
+ "arch" : ["str", "dxys"],
+ "genotype" : ["str", "SETN"],
+ "dataset" : ["str", "imagenet"],
+ "ichannel" : ["int", 58],
+ "layers" : ["int", 2],
+ "auxiliary" : ["bool", 1],
+ "drop_path_prob": ["float", 0]
+}
diff --git a/AutoDL-Projects/configs/archs/NAS-IMAGENET-SETN3.config b/AutoDL-Projects/configs/archs/NAS-IMAGENET-SETN3.config
new file mode 100644
index 0000000..42521ff
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/NAS-IMAGENET-SETN3.config
@@ -0,0 +1,9 @@
+{
+ "arch" : ["str", "dxys"],
+ "genotype" : ["str", "SETN"],
+ "dataset" : ["str", "imagenet"],
+ "ichannel" : ["int", 49],
+ "layers" : ["int", 3],
+ "auxiliary" : ["bool", 1],
+ "drop_path_prob": ["float", 0]
+}
diff --git a/AutoDL-Projects/configs/archs/NAS-IMAGENET-SETN4.config b/AutoDL-Projects/configs/archs/NAS-IMAGENET-SETN4.config
new file mode 100644
index 0000000..44e3238
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/NAS-IMAGENET-SETN4.config
@@ -0,0 +1,9 @@
+{
+ "arch" : ["str", "dxys"],
+ "genotype" : ["str", "SETN"],
+ "dataset" : ["str", "imagenet"],
+ "ichannel" : ["int", 44],
+ "layers" : ["int", 4],
+ "auxiliary" : ["bool", 1],
+ "drop_path_prob": ["float", 0]
+}
diff --git a/AutoDL-Projects/configs/archs/NAS-IMAGENET-none.config b/AutoDL-Projects/configs/archs/NAS-IMAGENET-none.config
new file mode 100644
index 0000000..192bbbc
--- /dev/null
+++ b/AutoDL-Projects/configs/archs/NAS-IMAGENET-none.config
@@ -0,0 +1,9 @@
+{
+ "super_type": ["str", "infer-nasnet.imagenet"],
+ "genotype" : ["none", "none"],
+ "dataset" : ["str", "imagenet"],
+ "ichannel" : ["int", 50],
+ "layers" : ["int", 4],
+ "auxiliary" : ["bool", 1],
+ "drop_path_prob": ["float", 0]
+}
diff --git a/AutoDL-Projects/configs/compares/CIFAR010-TAS-R110.config b/AutoDL-Projects/configs/compares/CIFAR010-TAS-R110.config
new file mode 100644
index 0000000..53cd8b5
--- /dev/null
+++ b/AutoDL-Projects/configs/compares/CIFAR010-TAS-R110.config
@@ -0,0 +1,13 @@
+{
+ "dataset" : ["str" , "cifar"],
+ "arch" : ["str" , "resnet"],
+ "depth" : ["int" , "110"],
+ "module" : ["str" , "ResNetBasicblock"],
+ "super_type" : ["str" , "infer-shape"],
+ "zero_init_residual" : ["bool" , "0"],
+ "class_num" : ["int" , "10"],
+ "search_mode" : ["str" , "shape"],
+ "xchannels" : ["int" , ["3", "16", "14", "16", "14", "16", "16", "16", "16", "16", "14", "16", "16", "16", "12", "16", "16", "16", "9", "16", "8", "16", "4", "16", "4", "4", "4", "16", "4", "4", "4", "4", "6", "6", "4", "6", "11", "4", "32", "32", "32", "32", "32", "32", "32", "32", "28", "32", "32", "28", "22", "22", "22", "32", "32", "25", "28", "9", "9", "28", "12", "9", "12", "32", "9", "9", "22", "12", "16", "9", "12", "9", "9", "9", "64", "64", "64", "64", "64", "64", "64", "64", "64", "64", "64", "64", "64", "64", "64", "38", "64", "25", "19", "19", "19", "19", "19", "25", "32", "19", "19", "25", "25", "19", "19", "38", "38", "19", "19", "51"]],
+ "xblocks" : ["int" , ["11", "11", "9"]],
+ "estimated_FLOP" : ["float" , "117.498238"]
+}
\ No newline at end of file
diff --git a/AutoDL-Projects/configs/compares/CIFAR010-TAS-R56.config b/AutoDL-Projects/configs/compares/CIFAR010-TAS-R56.config
new file mode 100644
index 0000000..e55f110
--- /dev/null
+++ b/AutoDL-Projects/configs/compares/CIFAR010-TAS-R56.config
@@ -0,0 +1,13 @@
+{
+ "dataset" : ["str" , "cifar"],
+ "arch" : ["str" , "resnet"],
+ "depth" : ["int" , "56"],
+ "module" : ["str" , "ResNetBasicblock"],
+ "super_type" : ["str" , "infer-shape"],
+ "zero_init_residual" : ["bool" , "0"],
+ "class_num" : ["int" , "10"],
+ "search_mode" : ["str" , "shape"],
+ "xchannels" : ["int" , ["3", "16", "16", "16", "14", "14", "14", "16", "12", "16", "6", "16", "4", "4", "4", "14", "4", "4", "6", "4", "32", "32", "32", "32", "32", "32", "22", "25", "16", "32", "19", "9", "9", "16", "25", "12", "16", "9", "64", "64", "64", "64", "64", "64", "64", "64", "64", "51", "19", "19", "32", "51", "25", "32", "19", "19"]],
+ "xblocks" : ["int" , ["5", "5", "5"]],
+ "estimated_FLOP" : ["float" , "57.52595"]
+}
\ No newline at end of file
diff --git a/AutoDL-Projects/configs/compares/CIFAR100-FIX-R32.config b/AutoDL-Projects/configs/compares/CIFAR100-FIX-R32.config
new file mode 100644
index 0000000..83317b3
--- /dev/null
+++ b/AutoDL-Projects/configs/compares/CIFAR100-FIX-R32.config
@@ -0,0 +1,11 @@
+{
+ "dataset" : ["str" , "cifar"],
+ "arch" : ["str" , "resnet"],
+ "depth" : ["int" , "32"],
+ "module" : ["str" , "ResNetBasicblock"],
+ "super_type" : ["str" , "infer-width"],
+ "zero_init_residual" : ["bool" , "0"],
+ "class_num" : ["int" , "100"],
+ "xchannels" : ["int" , ["3", "12", "12", "12", "12", "12", "12", "12", "12", "12", "12", "12", "25", "25", "25", "25", "25", "25", "25", "25", "25", "25", "50", "50", "50", "50", "50", "50", "50", "50", "50", "50"]],
+ "estimated_FLOP" : ["float" , "41.095816"]
+}
diff --git a/AutoDL-Projects/configs/compares/CIFAR100-RAND-R32.config b/AutoDL-Projects/configs/compares/CIFAR100-RAND-R32.config
new file mode 100644
index 0000000..25c4963
--- /dev/null
+++ b/AutoDL-Projects/configs/compares/CIFAR100-RAND-R32.config
@@ -0,0 +1,11 @@
+{
+ "dataset" : ["str" , "cifar"],
+ "arch" : ["str" , "resnet"],
+ "depth" : ["int" , "32"],
+ "module" : ["str" , "ResNetBasicblock"],
+ "super_type" : ["str" , "infer-width"],
+ "zero_init_residual" : ["bool" , "0"],
+ "class_num" : ["int" , "100"],
+ "xchannels" : ["int" , ["3", "4", "11", "11", "11", "12", "14", "16", "8", "9", "6", "12", "28", "32", "28", "32", "12", "25", "28", "22", "28", "25", "57", "19", "38", "64", "64", "51", "57", "64", "64", "57"]],
+ "estimated_FLOP" : ["float" , "42.908996"]
+}
diff --git a/AutoDL-Projects/configs/compares/CIFAR100-TAS-R110.config b/AutoDL-Projects/configs/compares/CIFAR100-TAS-R110.config
new file mode 100644
index 0000000..a4083e7
--- /dev/null
+++ b/AutoDL-Projects/configs/compares/CIFAR100-TAS-R110.config
@@ -0,0 +1,13 @@
+{
+ "dataset" : ["str" , "cifar"],
+ "arch" : ["str" , "resnet"],
+ "depth" : ["int" , "110"],
+ "module" : ["str" , "ResNetBasicblock"],
+ "super_type" : ["str" , "infer-shape"],
+ "zero_init_residual" : ["bool" , "0"],
+ "class_num" : ["int" , "100"],
+ "search_mode" : ["str" , "shape"],
+ "xchannels" : ["int" , ["3", "16", "14", "16", "11", "14", "16", "16", "11", "16", "9", "14", "12", "16", "16", "16", "8", "16", "14", "16", "12", "4", "11", "16", "4", "4", "4", "16", "12", "4", "8", "4", "9", "4", "6", "14", "4", "4", "32", "32", "32", "32", "28", "28", "32", "32", "32", "32", "32", "28", "32", "28", "25", "32", "32", "32", "9", "9", "32", "32", "9", "25", "28", "32", "28", "9", "9", "32", "12", "12", "9", "22", "12", "9", "64", "64", "64", "64", "64", "64", "64", "64", "64", "64", "64", "64", "64", "64", "64", "44", "64", "57", "19", "19", "19", "19", "25", "19", "25", "19", "25", "19", "19", "25", "19", "19", "19", "25", "25", "19"]],
+ "xblocks" : ["int" , ["13", "9", "11"]],
+ "estimated_FLOP" : ["float" , "117.653164"]
+}
\ No newline at end of file
diff --git a/AutoDL-Projects/configs/compares/CIFAR100-TAS-R32.config b/AutoDL-Projects/configs/compares/CIFAR100-TAS-R32.config
new file mode 100644
index 0000000..f01784d
--- /dev/null
+++ b/AutoDL-Projects/configs/compares/CIFAR100-TAS-R32.config
@@ -0,0 +1,11 @@
+{
+ "dataset" : ["str" , "cifar"],
+ "arch" : ["str" , "resnet"],
+ "depth" : ["int" , "32"],
+ "module" : ["str" , "ResNetBasicblock"],
+ "super_type" : ["str" , "infer-width"],
+ "zero_init_residual" : ["bool" , "0"],
+ "class_num" : ["int" , "100"],
+ "xchannels" : ["int" , ["3", "16", "4", "4", "4", "14", "6", "4", "8", "4", "4", "4", "32", "32", "9", "28", "28", "28", "28", "28", "32", "32", "64", "64", "64", "64", "64", "64", "64", "64", "64", "64"]],
+ "estimated_FLOP" : ["float" , "42.493184"]
+}
diff --git a/AutoDL-Projects/configs/compares/CIFAR100-TAS-R56.config b/AutoDL-Projects/configs/compares/CIFAR100-TAS-R56.config
new file mode 100644
index 0000000..3baa0e7
--- /dev/null
+++ b/AutoDL-Projects/configs/compares/CIFAR100-TAS-R56.config
@@ -0,0 +1,13 @@
+{
+ "dataset" : ["str" , "cifar"],
+ "arch" : ["str" , "resnet"],
+ "depth" : ["int" , "56"],
+ "module" : ["str" , "ResNetBasicblock"],
+ "super_type" : ["str" , "infer-shape"],
+ "zero_init_residual" : ["bool" , "0"],
+ "class_num" : ["int" , "100"],
+ "search_mode" : ["str" , "shape"],
+ "xchannels" : ["int" , ["3", "16", "16", "9", "14", "16", "14", "16", "8", "16", "8", "14", "4", "4", "4", "8", "4", "6", "4", "4", "32", "32", "32", "28", "32", "32", "32", "22", "32", "32", "32", "9", "25", "19", "25", "12", "9", "9", "64", "64", "64", "64", "64", "64", "64", "64", "64", "51", "19", "19", "19", "19", "25", "38", "19", "19"]],
+ "xblocks" : ["int" , ["5", "5", "7"]],
+ "estimated_FLOP" : ["float" , "59.472556"]
+}
\ No newline at end of file
diff --git a/AutoDL-Projects/configs/nas-benchmark/CIFAR.config b/AutoDL-Projects/configs/nas-benchmark/CIFAR.config
new file mode 100644
index 0000000..b681784
--- /dev/null
+++ b/AutoDL-Projects/configs/nas-benchmark/CIFAR.config
@@ -0,0 +1,13 @@
+{
+ "scheduler": ["str", "cos"],
+ "eta_min" : ["float", "0.0"],
+ "epochs" : ["int", "200"],
+ "warmup" : ["int", "0"],
+ "optim" : ["str", "SGD"],
+ "LR" : ["float", "0.1"],
+ "decay" : ["float", "0.0005"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "1"],
+ "criterion": ["str", "Softmax"],
+ "batch_size": ["int", "256"]
+}
diff --git a/AutoDL-Projects/configs/nas-benchmark/ImageNet-16.config b/AutoDL-Projects/configs/nas-benchmark/ImageNet-16.config
new file mode 100644
index 0000000..b681784
--- /dev/null
+++ b/AutoDL-Projects/configs/nas-benchmark/ImageNet-16.config
@@ -0,0 +1,13 @@
+{
+ "scheduler": ["str", "cos"],
+ "eta_min" : ["float", "0.0"],
+ "epochs" : ["int", "200"],
+ "warmup" : ["int", "0"],
+ "optim" : ["str", "SGD"],
+ "LR" : ["float", "0.1"],
+ "decay" : ["float", "0.0005"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "1"],
+ "criterion": ["str", "Softmax"],
+ "batch_size": ["int", "256"]
+}
diff --git a/AutoDL-Projects/configs/nas-benchmark/ImageNet16-120-split.txt b/AutoDL-Projects/configs/nas-benchmark/ImageNet16-120-split.txt
new file mode 100644
index 0000000..b5338d5
--- /dev/null
+++ b/AutoDL-Projects/configs/nas-benchmark/ImageNet16-120-split.txt
@@ -0,0 +1,4 @@
+{
+ "train" : ["int" , ["1", "3", "5", "7", "8", "10", "11", "12", "15", "18", "19", "22", "25", "29", "31", "35", "38", "39", "40", "41", "42", "49", "52", "53", "55", "60", "62", "63", "65", "67", "69", "70", "71", "74", "78", "81", "82", "83", "84", "85", "87", "88", "94", "95", "97", "100", "103", "105", "107", "109", "112", "115", "116", "121", "122", "123", "124", "126", "131", "132", "133", "134", "135", "136", "137", "139", "140", "142", "143", "144", "145", "147", "149", "153", "155", "156", "157", "162", "163", "164", "165", "167", "169", "171", "172", "179", "180", "183", "184", "185", "190", "191", "193", "198", "201", "203", "204", "206", "208", "209", "212", "216", "217", "219", "220", "224", "225", "226", "227", "228", "229", "231", "236", "240", "242", "243", "245", "247", "249", "250", "251", "253", "254", "255", "256", "257", "260", "265", "266", "268", "269", "270", "272", "274", "275", "278", "280", "282", "285", "293", "294", "296", "297", "299", "300", "302", "305", "307", "308", "309", "310", "311", "313", "316", "319", "321", "322", "325", "327", "328", "331", "332", "333", "334", "337", "339", "341", "343", "346", "350", "352", "353", "355", "356", "357", "358", "360", "361", "362", "363", "366", "367", "368", "371", "373", "374", "378", "380", "382", "384", "385", "389", "390", "391", "393", "395", "399", "402", "403", "408", "410", "412", "413", "414", "416", "418", "421", "425", "426", "428", "429", "430", "432", "434", "435", "436", "442", "448", "450", "451", "456", "457", "458", "459", "461", "462", "464", "465", "466", "468", "470", "471", "474", "476", "479", "480", "481", "482", "483", "484", "488", "489", "493", "495", "497", "500", "504", "506", "507", "509", "510", "511", "514", "515", "518", "519", "526", "531", "534", "536", "538", "539", "542", "544", "545", "546", "549", "551", "552", "555", "560", "561", "563", "565", "567", "569", "570", "571", "577", "579", "580", "583", "584", "587", "588", "589", "591", "592", "595", "599", "606", "607", "608", "610", "611", "613", "614", "615", "617", "619", "620", "621", "623", "625", "626", "627", "628", "629", "633", "634", "636", "637", "640", "642", "644", "646", "647", "649", "652", "655", "657", "662", "665", "666", "668", "669", "671", "675", "676", "679", "681", "683", "684", "685", "686", "687", "688", "689", "690", "692", "694", "697", "699", "703", "704", "707", "709", "710", "713", "714", "718", "721", "723", "726", "728", "729", "730", "732", "733", "734", "735", "737", "738", "739", "740", "741", "742", "743", "745", "746", "749", "753", "756", "758", "759", "760", "762", "763", "764", "768", "770", "771", "772", "773", "775", "777", "782", "785", "786", "787", "788", "789", "790", "791", "793", "795", "796", "797", "798", "800", "801", "806", "808", "809", "810", "811", "813", "815", "817", "819", "826", "827", "828", "829", "830", "834", "835", "838", "839", "842", "844", "845", "847", "848", "853", "854", "859", "862", "863", "866", "867", "868", "872", "873", "874", "879", "881", "885", "886", "889", "890", "891", "895", "896", "897", "898", "900", "902", "905", "907", "908", "909", "910", "911", "912", "913", "915", "916", "918", "919", "920", "922", "923", "924", "929", "930", "934", "936", "937", "939", "940", "941", "942", "946", "948", "950", "951", "955", "958", "959", "960", "962", "964", "965", "966", "969", "971", "974", "976", "977", "979", "981", "983", "984", "986", "987", "991", "993", "995", "997", "998", "999", "1001", "1002", "1003", "1004", "1006", "1007", "1012", "1014", "1016", "1017", "1018", "1019", "1020", "1021", "1026", "1027", "1028", "1030", "1031", "1032", "1033", "1037", "1038", "1042", "1045", "1046", "1047", "1049", "1051", "1052", "1053", "1054", "1055", "1057", "1058", "1062", "1063", "1068", "1071", "1072", "1073", "1074", "1075", "1077", "1078", "1079", "1083", "1085", "1088", "1090", "1091", "1093", "1094", "1096", "1099", "1101", "1105", "1106", "1108", "1109", "1110", "1111", "1112", "1113", "1115", "1118", "1122", "1123", "1124", "1126", "1127", "1130", "1132", "1133", "1137", "1139", "1141", "1142", "1144", "1148", "1154", "1155", "1157", "1161", "1162", "1165", "1166", "1168", "1172", "1173", "1175", "1176", "1177", "1179", "1182", "1183", "1187", "1188", "1189", "1190", "1196", "1198", "1199", "1200", "1201", "1203", "1204", "1208", "1209", "1210", "1212", "1213", "1214", "1217", "1218", "1219", "1221", "1226", "1228", "1229", "1231", "1234", "1235", "1237", "1238", "1241", "1242", "1243", "1244", "1245", "1252", "1257", "1258", "1259", "1260", "1261", "1264", "1265", "1268", "1271", "1272", "1274", "1275", "1276", "1277", "1278", "1279", "1280", "1281", "1283", "1284", "1285", "1287", "1288", "1289", "1294", "1295", "1297", "1300", "1302", "1304", "1307", "1308", "1311", "1316", "1321", "1322", "1324", "1325", "1326", "1328", "1329", "1330", "1331", "1332", "1333", "1336", "1339", "1340", "1342", "1343", "1345", "1347", "1353", "1359", "1362", "1363", "1364", "1365", "1366", "1367", "1370", "1371", "1372", "1375", "1377", "1379", "1380", "1381", "1382", "1383", "1384", "1386", "1393", "1394", "1396", "1397", "1398", "1400", "1401", "1403", "1404", "1405", "1406", "1407", "1409", "1410", "1413", "1416", "1417", "1420", "1421", "1423", "1425", "1428", "1429", "1430", "1432", "1433", "1435", "1436", "1437", "1438", "1439", "1443", "1444", "1445", "1448", "1449", "1450", "1452", "1454", "1455", "1457", "1459", "1463", "1465", "1466", "1467", "1471", "1474", "1476", "1480", "1481", "1483", "1484", "1487", "1488", "1491", "1493", "1501", "1502", "1504", "1505", "1507", "1508", "1512", "1513", "1514", "1516", "1517", "1521", "1522", "1534", "1538", "1540", "1541", "1543", "1544", "1546", "1548", "1551", "1552", "1557", "1559", "1561", "1564", "1566", "1567", "1571", "1573", "1574", "1576", "1577", "1578", "1580", "1581", "1582", "1583", "1584", "1585", "1586", "1587", "1588", "1589", "1590", "1592", "1593", "1595", "1596", "1597", "1598", "1599", "1600", "1601", "1603", "1607", "1608", "1610", "1611", "1612", "1613", "1615", "1616", "1619", "1621", "1622", "1626", "1634", "1638", "1639", "1641", "1642", "1643", "1647", "1649", "1651", "1652", "1655", "1657", "1658", "1662", "1663", "1664", "1667", "1672", "1676", "1677", "1678", "1680", "1684", "1686", "1687", "1689", "1692", "1693", "1696", "1699", "1701", "1704", "1708", "1709", "1711", "1714", "1716", "1717", "1718", "1719", "1720", "1726", "1727", "1735", "1737", "1739", "1742", "1743", "1744", "1745", "1746", "1748", "1751", "1754", "1755", "1759", "1760", "1761", "1763", "1764", "1765", "1766", "1768", "1769", "1770", "1771", "1773", "1774", "1780", "1782", "1783", "1785", "1789", "1792", "1795", "1798", "1806", "1807", "1808", "1810", "1811", "1814", "1816", "1820", "1822", "1824", "1825", "1826", "1827", "1828", "1829", "1830", "1831", "1832", "1833", "1836", "1837", "1838", "1840", "1841", "1842", "1844", "1846", "1848", "1851", "1853", "1854", "1855", "1858", "1859", "1863", "1864", "1865", "1867", "1868", "1869", "1876", "1877", "1878", "1879", "1880", "1881", "1882", "1883", "1884", "1885", "1886", "1888", "1889", "1891", "1892", "1893", "1895", "1898", "1901", "1903", "1905", "1906", "1908", "1910", "1912", "1916", "1918", "1920", "1921", "1923", "1925", "1926", "1927", "1930", "1931", "1934", "1936", "1938", "1940", "1943", "1944", "1945", "1948", "1949", "1950", "1955", "1957", "1959", "1963", "1965", "1966", "1975", "1977", "1978", "1981", "1983", "1986", "1993", "1997", "1998", "1999", "2000", "2002", "2004", "2005", "2006", "2007", "2008", "2015", "2016", "2017", "2018", "2020", "2023", "2024", "2025", "2028", "2030", "2031", "2032", "2035", "2036", "2040", "2041", "2042", "2048", "2049", "2051", "2052", "2053", "2055", "2056", "2057", "2058", "2059", "2060", "2061", "2063", "2064", "2066", "2067", "2069", "2070", "2075", "2078", "2079", "2080", "2084", "2086", "2087", "2089", "2090", "2091", "2092", "2093", "2094", "2098", "2100", "2101", "2104", "2109", "2112", "2115", "2116", "2117", "2123", "2124", "2126", "2127", "2128", "2130", "2131", "2136", "2137", "2138", "2141", "2142", "2144", "2145", "2147", "2148", "2149", "2150", "2152", "2153", "2156", "2157", "2158", "2160", "2167", "2174", "2176", "2177", "2179", "2181", "2184", "2185", "2188", "2192", "2193", "2196", "2197", "2200", "2201", "2205", "2206", "2207", "2209", "2211", "2212", "2213", "2214", "2215", "2216", "2217", "2221", "2225", "2227", "2231", "2232", "2237", "2238", "2240", "2241", "2242", "2243", "2246", "2247", "2250", "2253", "2255", "2256", "2259", "2262", "2263", "2265", "2267", "2274", "2275", "2278", "2281", "2283", "2285", "2290", "2291", "2292", "2293", "2295", "2296", "2297", "2299", "2302", "2303", "2306", "2307", "2308", "2309", "2312", "2314", "2315", "2317", "2318", "2320", "2323", "2328", "2330", "2332", "2334", "2336", "2341", "2343", "2344", "2346", "2352", "2356", "2357", "2361", "2362", "2369", "2371", "2372", "2373", "2374", "2375", "2378", "2381", "2382", "2383", "2386", "2387", "2388", "2389", "2391", "2392", "2395", "2396", "2398", "2402", "2407", "2408", "2410", "2411", "2413", "2415", "2416", "2417", "2418", "2420", "2421", "2422", "2423", "2425", "2427", "2429", "2435", "2436", "2439", "2443", "2444", "2445", "2446", "2450", "2451", "2453", "2457", "2459", "2461", "2463", "2464", "2466", "2467", "2470", "2473", "2474", "2477", "2478", "2482", "2483", "2484", "2485", "2486", "2489", "2490", "2491", "2494", "2495", "2496", "2499", "2501", "2503", "2504", "2511", "2515", "2516", "2520", "2523", "2524", "2525", "2527", "2528", "2532", "2533", "2535", "2541", "2542", "2546", "2547", "2548", "2550", "2554", "2555", "2556", "2557", "2559", "2560", "2562", "2563", "2564", "2565", "2568", "2571", "2572", "2573", "2574", "2578", "2581", "2583", "2585", "2586", "2587", "2591", "2594", "2595", "2598", "2599", "2600", "2601", "2603", "2605", "2607", "2610", "2612", "2613", "2614", "2617", "2619", "2620", "2621", "2623", "2626", "2627", "2628", "2630", "2634", "2639", "2640", "2644", "2645", "2646", "2647", "2648", "2650", "2651", "2659", "2661", "2662", "2663", "2665", "2666", "2669", "2671", "2674", "2675", "2676", "2677", "2683", "2685", "2686", "2687", "2688", "2689", "2693", "2694", "2696", "2698", "2699", "2700", "2701", "2705", "2707", "2713", "2714", "2716", "2719", "2721", "2724", "2725", "2726", "2727", "2728", "2729", "2730", "2731", "2732", "2733", "2736", "2738", "2740", "2742", "2745", "2748", "2753", "2754", "2758", "2761", "2766", "2767", "2773", "2774", "2775", "2778", "2780", "2782", "2784", "2785", "2788", "2791", "2795", "2797", "2800", "2804", "2805", "2808", "2812", "2813", "2814", "2817", "2818", "2824", "2828", "2829", "2831", "2833", "2834", "2835", "2838", "2839", "2840", "2842", "2843", "2845", "2846", "2847", "2852", "2854", "2855", "2856", "2860", "2861", "2864", "2865", "2869", "2870", "2871", "2872", "2875", "2880", "2883", "2885", "2889", "2890", "2891", "2892", "2893", "2895", "2896", "2897", "2902", "2905", "2907", "2908", "2909", "2911", "2915", "2916", "2919", "2920", "2921", "2922", "2925", "2927", "2928", "2932", "2934", "2935", "2937", "2938", "2939", "2940", "2941", "2943", "2947", "2950", "2952", "2958", "2963", "2965", "2966", "2967", "2968", "2971", "2974", "2978", "2979", "2987", "2988", "2993", "2995", "2996", "2997", "2999", "3001", "3002", "3004", "3005", "3010", "3011", "3014", "3015", "3016", "3017", "3021", "3023", "3024", "3028", "3033", "3034", "3035", "3036", "3037", "3038", "3039", "3040", "3041", "3044", "3047", "3048", "3050", "3052", "3053", "3055", "3056", "3060", "3061", "3066", "3067", "3071", "3073", "3076", "3077", "3078", "3079", "3080", "3083", "3086", "3091", "3092", "3094", "3095", "3097", "3098", "3099", "3100", "3101", "3102", "3103", "3104", "3105", "3106", "3108", "3110", "3112", "3113", "3114", "3115", "3116", "3117", "3119", "3124", "3126", "3128", "3131", "3133", "3134", "3138", "3139", "3143", "3149", "3150", "3151", "3155", "3156", "3157", "3158", "3159", "3160", "3161", "3162", "3167", "3168", "3172", "3173", "3174", "3177", "3179", "3182", "3188", "3189", "3190", "3194", "3196", "3197", "3199", "3201", "3202", "3208", "3209", "3210", "3211", "3217", "3220", "3221", "3223", "3224", "3225", "3226", "3231", "3232", "3234", "3237", "3238", "3239", "3240", "3241", "3243", "3244", "3245", "3248", "3249", "3251", "3252", "3253", "3254", "3257", "3261", "3264", "3267", "3268", "3272", "3273", "3274", "3275", "3276", "3278", "3281", "3282", "3286", "3288", "3289", "3290", "3297", "3299", "3300", "3302", "3306", "3313", "3314", "3315", "3318", "3319", "3322", "3324", "3326", "3329", "3331", "3332", "3333", "3334", "3335", "3338", "3341", "3342", "3344", "3345", "3349", "3350", "3351", "3354", "3363", "3364", "3367", "3368", "3369", "3370", "3372", "3373", "3376", "3377", "3381", "3382", "3383", "3384", "3385", "3388", "3389", "3390", "3392", "3395", "3397", "3402", "3404", "3406", "3408", "3410", "3411", "3413", "3417", "3419", "3420", "3421", "3424", "3425", "3426", "3427", "3428", "3430", "3431", "3433", "3434", "3436", "3438", "3440", "3441", "3442", "3444", "3445", "3446", "3447", "3448", "3449", "3450", "3454", "3457", "3458", "3459", "3460", "3461", "3463", "3465", "3466", "3468", "3469", "3470", "3472", "3475", "3477", "3479", "3480", "3482", "3486", "3490", "3491", "3494", "3496", "3497", "3499", "3503", "3504", "3505", "3506", "3507", "3509", "3510", "3512", "3513", "3514", "3516", "3523", "3524", "3525", "3527", "3532", "3534", "3536", "3539", "3540", "3541", "3542", "3543", "3545", "3546", "3549", "3551", "3556", "3558", "3559", "3560", "3562", "3564", "3570", "3571", "3573", "3574", "3577", "3578", "3580", "3587", "3589", "3590", "3595", "3596", "3598", "3601", "3604", "3606", "3607", "3609", "3611", "3612", "3613", "3618", "3620", "3621", "3622", "3625", "3629", "3631", "3634", "3636", "3637", "3639", "3640", "3642", "3645", "3647", "3648", "3649", "3653", "3654", "3656", "3658", "3659", "3660", "3663", "3664", "3666", "3667", "3668", "3669", "3671", "3672", "3673", "3674", "3675", "3676", "3678", "3680", "3681", "3685", "3687", "3688", "3690", "3691", "3692", "3693", "3694", "3698", "3700", "3703", "3706", "3708", "3710", "3712", "3714", "3716", "3717", "3718", "3721", "3722", "3724", "3726", "3727", "3730", "3731", "3733", "3735", "3740", "3742", "3744", "3745", "3746", "3747", "3749", "3751", "3752", "3755", "3756", "3761", "3762", "3764", "3765", "3766", "3767", "3769", "3770", "3771", "3772", "3774", "3776", "3780", "3781", "3782", "3783", "3785", "3787", "3788", "3789", "3790", "3791", "3792", "3796", "3798", "3799", "3800", "3801", "3802", "3804", "3806", "3807", "3808", "3810", "3812", "3813", "3816", "3818", "3819", "3822", "3824", "3828", "3830", "3833", "3837", "3838", "3840", "3841", "3843", "3847", "3848", "3849", "3850", "3851", "3855", "3856", "3860", "3861", "3862", "3863", "3866", "3867", "3875", "3878", "3879", "3880", "3883", "3884", "3885", "3886", "3887", "3888", "3889", "3894", "3896", "3898", "3900", "3903", "3904", "3905", "3906", "3908", "3914", "3920", "3921", "3923", "3924", "3928", "3930", "3932", "3933", "3934", "3938", "3939", "3943", "3944", "3945", "3946", "3951", "3955", "3957", "3963", "3965", "3966", "3968", "3969", "3970", "3971", "3973", "3976", "3978", "3980", "3983", "3988", "3989", "3990", "3992", "3995", "3997", "3998", "4001", "4003", "4004", "4011", "4016", "4017", "4020", "4022", "4023", "4025", "4026", "4028", "4030", "4031", "4033", "4036", "4041", "4046", "4047", "4048", "4049", "4050", "4052", "4053", "4055", "4058", "4059", "4060", "4061", "4062", "4063", "4067", "4068", "4070", "4071", "4075", "4076", "4077", "4079", "4081", "4082", "4085", "4086", "4087", "4088", "4091", "4096", "4097", "4099", "4102", "4105", "4106", "4109", "4111", "4115", "4116", "4117", "4118", "4119", "4120", "4121", "4125", "4126", "4128", "4130", "4131", "4134", "4137", "4138", "4139", "4146", "4153", "4155", "4157", "4158", "4159", "4161", "4162", "4163", "4165", "4166", "4167", "4169", "4170", "4176", "4177", "4178", "4179", "4187", "4188", "4189", "4190", "4192", "4194", "4196", "4205", "4206", "4208", "4209", "4210", "4211", "4213", "4215", "4217", "4219", "4220", "4221", "4227", "4228", "4229", "4231", "4233", "4235", "4236", "4240", "4241", "4244", "4247", "4251", "4252", "4253", "4254", "4255", "4259", "4265", "4267", "4270", "4271", "4272", "4276", "4277", "4279", "4280", "4281", "4283", "4286", "4288", "4290", "4291", "4293", "4296", "4298", "4300", "4303", "4306", "4308", "4309", "4311", "4312", "4313", "4315", "4318", "4319", "4320", "4321", "4323", "4324", "4330", "4333", "4335", "4338", "4339", "4342", "4343", "4344", "4346", "4348", "4349", "4351", "4353", "4355", "4356", "4357", "4360", "4362", "4363", "4364", "4365", "4366", "4368", "4369", "4372", "4373", "4374", "4376", "4377", "4378", "4379", "4382", "4383", "4390", "4393", "4395", "4401", "4402", "4410", "4411", "4414", "4415", "4419", "4421", "4422", "4429", "4430", "4431", "4433", "4435", "4437", "4439", "4440", "4441", "4444", "4445", "4449", "4450", "4451", "4452", "4453", "4458", "4460", "4461", "4462", "4463", "4465", "4466", "4467", "4468", "4474", "4475", "4478", "4479", "4480", "4481", "4484", "4488", "4489", "4490", "4491", "4492", "4494", "4495", "4497", "4500", "4501", "4504", "4505", "4512", "4514", "4515", "4516", "4519", "4522", "4524", "4525", "4529", "4532", "4535", "4539", "4543", "4545", "4547", "4549", "4551", "4553", "4554", "4555", "4558", "4559", "4561", "4563", "4569", "4570", "4571", "4572", "4573", "4576", "4580", "4581", "4585", "4587", "4589", "4593", "4594", "4595", "4597", "4598", "4600", "4601", "4602", "4604", "4608", "4609", "4610", "4611", "4612", "4614", "4615", "4618", "4622", "4625", "4626", "4627", "4628", "4629", "4631", "4632", "4633", "4634", "4635", "4636", "4639", "4643", "4644", "4646", "4648", "4649", "4651", "4652", "4653", "4654", "4655", "4657", "4660", "4662", "4665", "4666", "4668", "4669", "4670", "4672", "4675", "4676", "4677", "4681", "4682", "4688", "4694", "4695", "4698", "4699", "4700", "4703", "4704", "4705", "4706", "4708", "4710", "4712", "4714", "4715", "4716", "4718", "4721", "4722", "4726", "4727", "4730", "4735", "4737", "4739", "4741", "4742", "4744", "4746", "4747", "4748", "4755", "4756", "4757", "4758", "4760", "4761", "4762", "4763", "4764", "4766", "4771", "4772", "4775", "4778", "4779", "4782", "4786", "4788", "4792", "4795", "4796", "4800", "4801", "4803", "4804", "4806", "4807", "4815", "4816", "4822", "4824", "4827", "4828", "4831", "4833", "4835", "4838", "4840", "4843", "4845", "4847", "4848", "4849", "4853", "4857", "4858", "4863", "4865", "4868", "4869", "4870", "4872", "4873", "4874", "4875", "4877", "4881", "4882", "4883", "4886", "4887", "4888", "4889", "4891", "4893", "4895", "4897", "4899", "4900", "4905", "4906", "4907", "4908", "4909", "4910", "4914", "4919", "4920", "4922", "4924", "4928", "4930", "4931", "4936", "4937", "4938", "4941", "4942", "4944", "4945", "4946", "4948", "4951", "4952", "4956", "4959", "4960", "4962", "4965", "4968", "4969", "4971", "4978", "4980", "4981", "4982", "4984", "4988", "4989", "4990", "4991", "4994", "4995", "4999", "5003", "5006", "5008", "5009", "5010", "5011", "5014", "5017", "5018", "5019", "5020", "5021", "5023", "5025", "5026", "5028", "5030", "5037", "5038", "5039", "5040", "5041", "5043", "5044", "5046", "5047", "5048", "5049", "5050", "5052", "5053", "5055", "5056", "5057", "5058", "5059", "5063", "5064", "5066", "5067", "5069", "5070", "5072", "5073", "5075", "5079", "5085", "5086", "5090", "5091", "5092", "5093", "5095", "5096", "5097", "5098", "5100", "5101", "5102", "5104", "5105", "5106", "5107", "5109", "5112", "5118", "5119", "5120", "5122", "5127", "5128", "5130", "5131", "5140", "5143", "5145", "5146", "5147", "5148", "5150", "5152", "5153", "5156", "5159", "5161", "5162", "5163", "5164", "5165", "5166", "5167", "5169", "5170", "5171", "5174", "5176", "5180", "5181", "5182", "5184", "5187", "5188", "5189", "5191", "5194", "5198", "5199", "5200", "5201", "5202", "5203", "5204", "5209", "5211", "5212", "5213", "5214", "5217", "5221", "5224", "5230", "5231", "5235", "5240", "5242", "5244", "5245", "5246", "5247", "5248", "5250", "5251", "5255", "5256", "5258", "5260", "5265", "5266", "5267", "5271", "5275", "5276", "5277", "5278", "5281", "5283", "5287", "5288", "5289", "5290", "5295", "5297", "5300", "5301", "5305", "5308", "5312", "5313", "5315", "5317", "5318", "5319", "5320", "5321", "5323", "5325", "5328", "5329", "5331", "5332", "5335", "5337", "5339", "5342", "5344", "5347", "5348", "5349", "5351", "5352", "5354", "5355", "5357", "5360", "5362", "5363", "5364", "5367", "5368", "5369", "5370", "5372", "5375", "5376", "5377", "5379", "5383", "5384", "5388", "5399", "5401", "5402", "5404", "5406", "5407", "5408", "5411", "5412", "5414", "5415", "5417", "5418", "5421", "5422", "5423", "5426", "5428", "5429", "5432", "5434", "5435", "5436", "5437", "5446", "5447", "5449", "5452", "5454", "5457", "5458", "5460", "5461", "5462", "5464", "5465", "5468", "5469", "5470", "5471", "5475", "5476", "5477", "5480", "5481", "5482", "5483", "5485", "5489", "5491", "5493", "5498", "5500", "5502", "5503", "5504", "5507", "5508", "5511", "5513", "5514", "5516", "5518", "5521", "5523", "5524", "5531", "5534", "5536", "5537", "5538", "5539", "5540", "5542", "5545", "5546", "5549", "5552", "5555", "5556", "5557", "5559", "5562", "5564", "5565", "5567", "5572", "5574", "5576", "5577", "5579", "5580", "5581", "5582", "5584", "5587", "5588", "5589", "5590", "5595", "5597", "5598", "5599", "5601", "5603", "5604", "5606", "5608", "5609", "5610", "5618", "5624", "5625", "5629", "5630", "5632", "5637", "5638", "5640", "5641", "5643", "5645", "5646", "5650", "5653", "5654", "5655", "5656", "5657", "5658", "5659", "5662", "5664", "5665", "5666", "5668", "5671", "5672", "5673", "5674", "5675", "5676", "5678", "5680", "5681", "5685", "5686", "5687", "5688", "5690", "5691", "5694", "5695", "5696", "5699", "5700", "5702", "5703", "5704", "5706", "5708", "5710", "5711", "5712", "5713", "5718", "5720", "5721", "5722", "5725", "5731", "5734", "5736", "5742", "5743", "5744", "5745", "5746", "5747", "5749", "5750", "5752", "5753", "5754", "5756", "5757", "5758", "5759", "5763", "5764", "5765", "5766", "5768", "5769", "5770", "5771", "5772", "5774", "5778", "5784", "5790", "5792", "5793", "5798", "5800", "5801", "5804", "5807", "5809", "5812", "5814", "5815", "5816", "5817", "5818", "5819", "5820", "5821", "5822", "5828", "5834", "5835", "5839", "5840", "5843", "5844", "5847", "5848", "5850", "5852", "5853", "5854", "5855", "5859", "5863", "5865", "5869", "5870", "5871", "5874", "5875", "5876", "5878", "5879", "5881", "5883", "5884", "5885", "5887", "5889", "5891", "5893", "5894", "5896", "5898", "5899", "5902", "5903", "5904", "5906", "5907", "5910", "5911", "5913", "5916", "5917", "5920", "5923", "5924", "5925", "5932", "5933", "5934", "5937", "5938", "5940", "5943", "5944", "5946", "5947", "5950", "5952", "5953", "5954", "5962", "5970", "5971", "5972", "5973", "5982", "5983", "5987", "5988", "5990", "5991", "5992", "5993", "5997", "6000", "6001", "6003", "6004", "6005", "6009", "6010", "6011", "6012", "6014", "6016", "6019", "6021", "6026", "6028", "6029", "6030", "6032", "6033", "6035", "6036", "6038", "6039", "6040", "6043", "6044", "6045", "6046", "6047", "6048", "6050", "6054", "6055", "6059", "6060", "6064", "6066", "6068", "6070", "6071", "6072", "6074", "6076", "6077", "6080", "6081", "6083", "6085", "6086", "6088", "6090", "6092", "6093", "6097", "6098", "6101", "6102", "6103", "6107", "6111", "6113", "6114", "6116", "6117", "6119", "6121", "6122", "6124", "6125", "6126", "6127", "6131", "6133", "6135", "6137", "6139", "6140", "6141", "6142", "6143", "6144", "6145", "6146", "6153", "6155", "6156", "6158", "6161", "6166", "6167", "6169", "6170", "6180", "6181", "6182", "6183", "6185", "6186", "6187", "6191", "6192", "6193", "6194", "6196", "6198", "6199", "6201", "6202", "6204", "6212", "6214", "6215", "6217", "6218", "6220", "6221", "6223", "6226", "6229", "6236", "6240", "6242", "6244", "6246", "6248", "6249", "6251", "6253", "6257", "6259", "6260", "6262", "6263", "6264", "6266", "6267", "6268", "6274", "6275", "6276", "6277", "6279", "6280", "6284", "6285", "6287", "6291", "6292", "6293", "6296", "6297", "6298", "6300", "6302", "6304", "6306", "6312", "6315", "6316", "6317", "6319", "6327", "6328", "6331", "6333", "6334", "6335", "6337", "6338", "6341", "6343", "6344", "6347", "6354", "6360", "6362", "6368", "6376", "6378", "6380", "6386", "6387", "6391", "6394", "6396", "6398", "6399", "6401", "6402", "6408", "6409", "6410", "6411", "6412", "6413", "6420", "6422", "6423", "6424", "6425", "6427", "6428", "6431", "6432", "6435", "6436", "6438", "6439", "6441", "6445", "6449", "6450", "6452", "6455", "6456", "6458", "6459", "6460", "6461", "6462", "6463", "6464", "6465", "6466", "6467", "6468", "6469", "6471", "6472", "6473", "6474", "6478", "6479", "6480", "6482", "6483", "6486", "6487", "6500", "6508", "6511", "6512", "6515", "6516", "6517", "6518", "6520", "6523", "6524", "6526", "6529", "6531", "6532", "6536", "6539", "6540", "6542", "6543", "6545", "6546", "6548", "6549", "6552", "6554", "6555", "6557", "6558", "6561", "6566", "6568", "6572", "6575", "6578", "6579", "6580", "6581", "6584", "6585", "6586", "6589", "6590", "6591", "6592", "6593", "6594", "6596", "6597", "6601", "6604", "6607", "6611", "6614", "6616", "6617", "6618", "6622", "6625", "6627", "6628", "6629", "6631", "6632", "6635", "6636", "6639", "6641", "6644", "6645", "6646", "6649", "6650", "6651", "6652", "6653", "6656", "6657", "6659", "6660", "6663", "6664", "6665", "6666", "6667", "6670", "6671", "6672", "6673", "6674", "6675", "6677", "6678", "6682", "6683", "6684", "6685", "6686", "6687", "6688", "6690", "6693", "6695", "6697", "6698", "6700", "6701", "6702", "6705", "6706", "6710", "6714", "6715", "6717", "6718", "6719", "6720", "6721", "6722", "6723", "6724", "6728", "6731", "6734", "6735", "6737", "6743", "6745", "6746", "6748", "6750", "6751", "6752", "6753", "6754", "6755", "6757", "6759", "6761", "6762", "6765", "6767", "6768", "6769", "6772", "6773", "6774", "6779", "6780", "6781", "6783", "6785", "6786", "6788", "6789", "6791", "6799", "6804", "6807", "6810", "6812", "6816", "6817", "6821", "6823", "6824", "6825", "6826", "6827", "6830", "6831", "6832", "6833", "6834", "6835", "6836", "6837", "6838", "6839", "6841", "6843", "6844", "6846", "6852", "6854", "6856", "6857", "6859", "6860", "6861", "6862", "6863", "6868", "6871", "6872", "6873", "6875", "6876", "6877", "6878", "6880", "6882", "6883", "6885", "6886", "6887", "6889", "6891", "6893", "6898", "6899", "6901", "6902", "6903", "6905", "6909", "6910", "6911", "6913", "6914", "6916", "6917", "6919", "6921", "6922", "6923", "6926", "6928", "6929", "6930", "6931", "6932", "6933", "6937", "6939", "6941", "6942", "6944", "6948", "6950", "6951", "6954", "6955", "6957", "6960", "6962", "6963", "6964", "6966", "6970", "6971", "6972", "6974", "6975", "6981", "6982", "6985", "6986", "6988", "6990", "6992", "6996", "7000", "7003", "7005", "7007", "7009", "7010", "7011", "7012", "7013", "7014", "7017", "7020", "7024", "7027", "7031", "7032", "7033", "7034", "7035", "7038", "7039", "7040", "7043", "7044", "7045", "7047", "7048", "7051", "7054", "7055", "7057", "7058", "7063", "7064", "7065", "7067", "7069", "7071", "7072", "7074", "7076", "7078", "7079", "7080", "7081", "7082", "7083", "7086", "7087", "7090", "7091", "7092", "7094", "7096", "7097", "7098", "7099", "7104", "7110", "7111", "7113", "7114", "7118", "7122", "7123", "7124", "7125", "7129", "7131", "7132", "7133", "7135", "7136", "7139", "7140", "7146", "7147", "7149", "7150", "7152", "7154", "7158", "7159", "7160", "7164", "7165", "7167", "7170", "7172", "7173", "7176", "7177", "7181", "7182", "7183", "7186", "7189", "7190", "7191", "7193", "7194", "7197", "7199", "7200", "7201", "7202", "7203", "7204", "7210", "7211", "7212", "7215", "7216", "7217", "7218", "7220", "7222", "7224", "7225", "7227", "7231", "7236", "7237", "7239", "7242", "7245", "7246", "7247", "7249", "7252", "7253", "7254", "7255", "7258", "7260", "7261", "7262", "7263", "7265", "7266", "7275", "7276", "7277", "7279", "7280", "7281", "7283", "7284", "7294", "7295", "7299", "7300", "7301", "7303", "7306", "7309", "7311", "7312", "7313", "7317", "7318", "7321", "7322", "7324", "7326", "7328", "7331", "7332", "7334", "7336", "7337", "7352", "7354", "7362", "7363", "7366", "7367", "7368", "7376", "7382", "7383", "7384", "7385", "7386", "7389", "7393", "7395", "7396", "7397", "7398", "7399", "7400", "7403", "7404", "7406", "7407", "7408", "7409", "7410", "7411", "7414", "7416", "7419", "7420", "7421", "7422", "7428", "7431", "7434", "7435", "7437", "7438", "7439", "7440", "7441", "7442", "7444", "7445", "7448", "7449", "7450", "7452", "7453", "7454", "7455", "7456", "7457", "7459", "7461", "7462", "7463", "7467", "7469", "7471", "7475", "7476", "7478", "7479", "7480", "7481", "7482", "7484", "7485", "7487", "7488", "7489", "7492", "7497", "7502", "7503", "7505", "7506", "7507", "7510", "7512", "7514", "7519", "7520", "7521", "7522", "7523", "7527", "7530", "7531", "7533", "7537", "7538", "7540", "7542", "7543", "7544", "7545", "7548", "7550", "7554", "7557", "7558", "7559", "7561", "7562", "7563", "7564", "7565", "7569", "7571", "7572", "7574", "7579", "7580", "7581", "7582", "7584", "7586", "7587", "7589", "7591", "7598", "7599", "7600", "7602", "7603", "7604", "7605", "7606", "7608", "7612", "7613", "7614", "7617", "7619", "7620", "7623", "7624", "7627", "7628", "7631", "7632", "7634", "7635", "7637", "7640", "7644", "7646", "7648", "7650", "7652", "7653", "7656", "7659", "7662", "7666", "7667", "7668", "7669", "7670", "7672", "7673", "7675", "7676", "7678", "7681", "7682", "7685", "7687", "7690", "7692", "7694", "7695", "7696", "7698", "7699", "7701", "7702", "7703", "7708", "7709", "7710", "7714", "7715", "7716", "7717", "7719", "7720", "7723", "7724", "7729", "7730", "7731", "7734", "7735", "7737", "7738", "7739", "7745", "7746", "7747", "7749", "7750", "7751", "7752", "7754", "7756", "7757", "7759", "7761", "7764", "7770", "7771", "7773", "7776", "7777", "7784", "7788", "7791", "7792", "7793", "7794", "7797", "7798", "7800", "7803", "7804", "7807", "7809", "7811", "7812", "7813", "7816", "7817", "7820", "7821", "7822", "7823", "7826", "7827", "7829", "7831", "7832", "7833", "7834", "7836", "7840", "7841", "7850", "7851", "7853", "7855", "7856", "7858", "7860", "7862", "7868", "7870", "7873", "7874", "7876", "7877", "7878", "7879", "7880", "7881", "7883", "7886", "7887", "7888", "7890", "7893", "7894", "7897", "7900", "7901", "7902", "7905", "7907", "7913", "7916", "7918", "7919", "7922", "7927", "7928", "7929", "7931", "7933", "7939", "7940", "7941", "7945", "7947", "7949", "7950", "7951", "7952", "7953", "7957", "7960", "7962", "7966", "7968", "7972", "7974", "7975", "7976", "7977", "7980", "7981", "7983", "7985", "7987", "7989", "7992", "7993", "7994", "7995", "7997", "7999", "8000", "8001", "8002", "8003", "8005", "8008", "8009", "8010", "8012", "8013", "8017", "8018", "8020", "8021", "8022", "8026", "8031", "8032", "8033", "8034", "8036", "8037", "8039", "8041", "8042", "8046", "8047", "8048", "8049", "8050", "8056", "8058", "8059", "8062", "8063", "8065", "8067", "8069", "8070", "8071", "8072", "8075", "8076", "8080", "8081", "8083", "8087", "8089", "8090", "8091", "8092", "8097", "8101", "8102", "8103", "8104", "8106", "8115", "8116", "8117", "8119", "8120", "8123", "8125", "8126", "8130", "8134", "8135", "8136", "8138", "8142", "8144", "8146", "8147", "8149", "8152", "8153", "8154", "8155", "8157", "8159", "8160", "8161", "8164", "8166", "8169", "8174", "8175", "8178", "8181", "8183", "8189", "8190", "8191", "8192", "8194", "8195", "8196", "8198", "8200", "8203", "8204", "8205", "8208", "8216", "8221", "8222", "8223", "8227", "8229", "8233", "8234", "8235", "8236", "8239", "8240", "8241", "8246", "8249", "8251", "8254", "8255", "8256", "8257", "8259", "8260", "8261", "8262", "8265", "8266", "8268", "8270", "8271", "8272", "8275", "8277", "8278", "8284", "8285", "8288", "8289", "8293", "8294", "8296", "8301", "8302", "8303", "8307", "8308", "8314", "8315", "8320", "8321", "8323", "8324", "8325", "8326", "8327", "8331", "8334", "8340", "8341", "8342", "8345", "8346", "8347", "8348", "8352", "8353", "8354", "8356", "8357", "8360", "8363", "8364", "8366", "8371", "8373", "8376", "8380", "8381", "8382", "8385", "8386", "8390", "8392", "8393", "8396", "8397", "8399", "8400", "8401", "8402", "8403", "8404", "8405", "8406", "8407", "8408", "8410", "8411", "8414", "8416", "8417", "8426", "8427", "8428", "8430", "8433", "8437", "8439", "8444", "8445", "8446", "8451", "8453", "8455", "8456", "8457", "8458", "8459", "8462", "8467", "8470", "8471", "8472", "8476", "8478", "8479", "8481", "8482", "8487", "8491", "8492", "8494", "8496", "8500", "8501", "8502", "8505", "8511", "8513", "8518", "8519", "8521", "8522", "8524", "8529", "8531", "8534", "8536", "8537", "8543", "8544", "8548", "8550", "8551", "8556", "8560", "8561", "8562", "8564", "8565", "8568", "8569", "8575", "8577", "8578", "8582", "8583", "8586", "8587", "8590", "8591", "8592", "8594", "8596", "8599", "8601", "8602", "8607", "8608", "8609", "8610", "8611", "8612", "8614", "8616", "8617", "8622", "8628", "8630", "8632", "8633", "8634", "8636", "8637", "8640", "8645", "8650", "8652", "8654", "8655", "8662", "8663", "8664", "8665", "8667", "8669", "8670", "8671", "8673", "8680", "8681", "8684", "8685", "8688", "8691", "8697", "8704", "8705", "8708", "8709", "8715", "8716", "8718", "8719", "8723", "8724", "8729", "8733", "8735", "8737", "8740", "8741", "8743", "8745", "8746", "8748", "8749", "8750", "8751", "8752", "8753", "8754", "8757", "8758", "8759", "8761", "8762", "8768", "8769", "8770", "8771", "8772", "8773", "8774", "8775", "8776", "8777", "8778", "8779", "8783", "8785", "8786", "8787", "8788", "8790", "8791", "8792", "8793", "8797", "8799", "8801", "8802", "8804", "8808", "8813", "8814", "8816", "8817", "8818", "8820", "8822", "8823", "8825", "8827", "8828", "8834", "8835", "8836", "8837", "8840", "8841", "8844", "8845", "8846", "8850", "8852", "8853", "8854", "8856", "8857", "8858", "8860", "8861", "8864", "8865", "8868", "8872", "8874", "8875", "8879", "8880", "8881", "8884", "8891", "8893", "8894", "8896", "8901", "8902", "8903", "8904", "8905", "8906", "8907", "8909", "8914", "8915", "8916", "8917", "8918", "8919", "8920", "8922", "8923", "8924", "8929", "8930", "8932", "8938", "8942", "8944", "8945", "8947", "8948", "8949", "8950", "8953", "8954", "8957", "8961", "8962", "8963", "8970", "8971", "8972", "8974", "8975", "8976", "8981", "8982", "8985", "8986", "8987", "8992", "8993", "8994", "8995", "8996", "8997", "8998", "8999", "9001", "9004", "9005", "9006", "9008", "9009", "9012", "9013", "9014", "9016", "9017", "9018", "9020", "9021", "9022", "9023", "9024", "9025", "9026", "9047", "9048", "9051", "9053", "9054", "9055", "9057", "9058", "9059", "9060", "9062", "9063", "9064", "9066", "9069", "9070", "9072", "9074", "9076", "9080", "9082", "9083", "9085", "9086", "9087", "9088", "9091", "9092", "9097", "9098", "9101", "9102", "9103", "9104", "9106", "9107", "9108", "9109", "9111", "9122", "9126", "9129", "9130", "9131", "9132", "9134", "9136", "9137", "9140", "9142", "9144", "9147", "9148", "9151", "9156", "9157", "9161", "9163", "9164", "9165", "9166", "9167", "9172", "9176", "9177", "9179", "9183", "9184", "9188", "9189", "9195", "9196", "9202", "9204", "9205", "9206", "9208", "9209", "9210", "9211", "9214", "9215", "9216", "9220", "9222", "9224", "9226", "9227", "9228", "9229", "9230", "9231", "9232", "9239", "9242", "9245", "9246", "9249", "9250", "9251", "9253", "9256", "9260", "9262", "9264", "9266", "9272", "9273", "9274", "9277", "9279", "9281", "9282", "9285", "9286", "9289", "9290", "9293", "9294", "9295", "9303", "9304", "9308", "9310", "9311", "9313", "9314", "9318", "9319", "9321", "9322", "9324", "9327", "9331", "9332", "9334", "9337", "9338", "9339", "9341", "9342", "9345", "9346", "9347", "9350", "9351", "9352", "9354", "9357", "9358", "9364", "9365", "9367", "9368", "9371", "9372", "9373", "9375", "9377", "9381", "9384", "9385", "9386", "9393", "9394", "9395", "9396", "9397", "9399", "9400", "9405", "9406", "9409", "9410", "9414", "9415", "9417", "9418", "9420", "9421", "9422", "9427", "9428", "9430", "9432", "9437", "9438", "9439", "9440", "9442", "9444", "9445", "9448", "9450", "9451", "9453", "9454", "9456", "9457", "9458", "9460", "9461", "9463", "9465", "9466", "9467", "9470", "9471", "9472", "9474", "9478", "9479", "9483", "9484", "9485", "9486", "9488", "9491", "9493", "9494", "9495", "9497", "9502", "9503", "9504", "9507", "9511", "9512", "9513", "9516", "9521", "9522", "9524", "9526", "9528", "9529", "9531", "9532", "9537", "9539", "9540", "9541", "9544", "9548", "9550", "9551", "9553", "9558", "9559", "9563", "9564", "9566", "9567", "9572", "9573", "9575", "9576", "9577", "9578", "9583", "9584", "9585", "9586", "9588", "9593", "9594", "9599", "9600", "9601", "9602", "9603", "9605", "9606", "9608", "9612", "9614", "9616", "9617", "9620", "9626", "9628", "9629", "9631", "9632", "9634", "9635", "9637", "9640", "9644", "9646", "9648", "9651", "9652", "9654", "9655", "9658", "9666", "9670", "9671", "9672", "9674", "9680", "9681", "9683", "9684", "9685", "9689", "9691", "9693", "9695", "9697", "9699", "9700", "9701", "9702", "9703", "9706", "9708", "9709", "9710", "9711", "9717", "9719", "9720", "9723", "9724", "9725", "9726", "9729", "9730", "9733", "9735", "9738", "9739", "9740", "9741", "9744", "9745", "9746", "9750", "9755", "9756", "9757", "9758", "9759", "9762", "9763", "9764", "9765", "9766", "9767", "9772", "9777", "9778", "9779", "9780", "9781", "9782", "9783", "9784", "9785", "9787", "9789", "9791", "9795", "9796", "9800", "9801", "9802", "9807", "9811", "9814", "9815", "9816", "9817", "9818", "9819", "9823", "9828", "9829", "9838", "9839", "9841", "9842", "9845", "9846", "9847", "9851", "9855", "9856", "9857", "9860", "9863", "9866", "9868", "9869", "9871", "9874", "9875", "9876", "9878", "9879", "9880", "9882", "9883", "9884", "9886", "9890", "9891", "9893", "9895", "9896", "9897", "9898", "9899", "9902", "9904", "9905", "9907", "9908", "9909", "9911", "9913", "9914", "9915", "9916", "9918", "9920", "9922", "9925", "9926", "9927", "9929", "9932", "9933", "9935", "9936", "9937", "9938", "9940", "9942", "9943", "9944", "9946", "9947", "9948", "9954", "9957", "9960", "9962", "9963", "9964", "9965", "9969", "9972", "9973", "9974", "9976", "9979", "9980", "9983", "9984", "9986", "9988", "9989", "9991", "9992", "9993", "9998", "9999", "10001", "10003", "10006", "10007", "10008", "10010", "10013", "10014", "10017", "10020", "10023", "10024", "10028", "10029", "10032", "10034", "10035", "10036", "10038", "10040", "10041", "10042", "10043", "10044", "10045", "10046", "10047", "10050", "10054", "10055", "10058", "10059", "10060", "10067", "10068", "10069", "10072", "10074", "10075", "10077", "10078", "10080", "10081", "10084", "10086", "10089", "10090", "10091", "10098", "10100", "10104", "10109", "10110", "10111", "10112", "10115", "10117", "10119", "10120", "10121", "10124", "10125", "10126", "10127", "10128", "10130", "10131", "10132", "10133", "10137", "10140", "10141", "10142", "10143", "10144", "10145", "10147", "10150", "10152", "10154", "10158", "10159", "10160", "10161", "10163", "10164", "10165", "10169", "10172", "10173", "10177", "10178", "10179", "10180", "10181", "10184", "10185", "10186", "10189", "10191", "10193", "10195", "10198", "10199", "10203", "10204", "10209", "10210", "10211", "10215", "10216", "10217", "10218", "10220", "10222", "10225", "10226", "10227", "10228", "10231", "10234", "10236", "10237", "10239", "10241", "10244", "10245", "10246", "10247", "10249", "10251", "10254", "10255", "10256", "10259", "10260", "10261", "10262", "10264", "10265", "10267", "10268", "10273", "10274", "10275", "10278", "10281", "10283", "10284", "10287", "10288", "10289", "10290", "10294", "10295", "10296", "10298", "10299", "10300", "10301", "10303", "10305", "10306", "10309", "10310", "10311", "10313", "10316", "10317", "10321", "10322", "10323", "10324", "10325", "10326", "10328", "10329", "10330", "10334", "10335", "10336", "10337", "10340", "10345", "10346", "10352", "10354", "10356", "10357", "10358", "10360", "10362", "10363", "10366", "10367", "10370", "10374", "10375", "10379", "10382", "10386", "10387", "10388", "10389", "10390", "10391", "10392", "10393", "10395", "10397", "10398", "10399", "10400", "10401", "10404", "10405", "10407", "10411", "10412", "10413", "10414", "10415", "10416", "10417", "10420", "10421", "10422", "10425", "10427", "10428", "10432", "10435", "10437", "10440", "10442", "10443", "10445", "10447", "10449", "10451", "10454", "10455", "10457", "10459", "10460", "10462", "10463", "10466", "10470", "10472", "10474", "10475", "10476", "10477", "10478", "10479", "10480", "10482", "10483", "10484", "10486", "10487", "10489", "10493", "10496", "10498", "10500", "10501", "10502", "10507", "10509", "10511", "10512", "10513", "10514", "10518", "10519", "10521", "10522", "10526", "10531", "10534", "10535", "10540", "10541", "10546", "10547", "10549", "10551", "10554", "10556", "10560", "10561", "10564", "10565", "10567", "10569", "10571", "10575", "10577", "10579", "10580", "10581", "10586", "10588", "10589", "10594", "10596", "10597", "10599", "10600", "10602", "10603", "10605", "10607", "10608", "10610", "10611", "10612", "10615", "10616", "10617", "10619", "10621", "10623", "10624", "10628", "10630", "10632", "10633", "10635", "10640", "10641", "10644", "10647", "10649", "10651", "10654", "10655", "10661", "10664", "10665", "10667", "10669", "10670", "10674", "10676", "10678", "10682", "10687", "10688", "10689", "10690", "10693", "10694", "10695", "10696", "10698", "10699", "10700", "10702", "10707", "10712", "10715", "10716", "10718", "10720", "10723", "10727", "10728", "10729", "10732", "10733", "10734", "10735", "10736", "10739", "10740", "10741", "10743", "10746", "10751", "10752", "10756", "10761", "10762", "10766", "10771", "10772", "10773", "10775", "10778", "10783", "10786", "10787", "10788", "10791", "10792", "10793", "10796", "10797", "10805", "10811", "10818", "10821", "10822", "10823", "10824", "10826", "10828", "10829", "10833", "10834", "10835", "10837", "10838", "10840", "10842", "10843", "10845", "10846", "10847", "10848", "10849", "10852", "10853", "10854", "10857", "10858", "10860", "10861", "10862", "10863", "10864", "10867", "10868", "10878", "10879", "10881", "10883", "10884", "10885", "10887", "10890", "10891", "10892", "10896", "10903", "10904", "10906", "10910", "10912", "10915", "10917", "10920", "10921", "10924", "10926", "10928", "10929", "10931", "10932", "10934", "10938", "10940", "10943", "10946", "10950", "10951", "10952", "10953", "10954", "10955", "10956", "10957", "10958", "10960", "10962", "10963", "10966", "10967", "10969", "10970", "10971", "10975", "10976", "10977", "10982", "10984", "10985", "10986", "10988", "10989", "10993", "10994", "10998", "10999", "11001", "11004", "11006", "11009", "11012", "11013", "11014", "11016", "11017", "11020", "11021", "11022", "11023", "11027", "11031", "11032", "11034", "11035", "11036", "11042", "11043", "11044", "11047", "11051", "11053", "11055", "11057", "11058", "11059", "11060", "11061", "11062", "11063", "11064", "11065", "11066", "11068", "11071", "11072", "11073", "11074", "11078", "11079", "11080", "11087", "11088", "11094", "11097", "11099", "11100", "11101", "11102", "11104", "11108", "11109", "11111", "11112", "11117", "11118", "11119", "11122", "11123", "11124", "11125", "11126", "11127", "11132", "11133", "11134", "11135", "11136", "11139", "11142", "11143", "11144", "11145", "11146", "11150", "11151", "11155", "11158", "11159", "11160", "11166", "11167", "11168", "11169", "11170", "11171", "11175", "11180", "11183", "11184", "11186", "11187", "11189", "11190", "11192", "11194", "11195", "11197", "11198", "11199", "11200", "11201", "11204", "11206", "11208", "11210", "11213", "11214", "11215", "11217", "11219", "11224", "11225", "11227", "11228", "11232", "11233", "11236", "11237", "11239", "11240", "11241", "11243", "11245", "11247", "11248", "11249", "11250", "11251", "11252", "11253", "11255", "11256", "11258", "11260", "11261", "11263", "11264", "11267", "11268", "11269", "11270", "11272", "11274", "11280", "11281", "11282", "11283", "11284", "11285", "11286", "11289", "11290", "11292", "11293", "11294", "11295", "11297", "11298", "11300", "11303", "11304", "11310", "11313", "11315", "11316", "11319", "11320", "11321", "11324", "11326", "11329", "11330", "11331", "11336", "11337", "11339", "11340", "11342", "11343", "11344", "11345", "11347", "11349", "11352", "11353", "11354", "11356", "11359", "11360", "11362", "11363", "11364", "11365", "11369", "11370", "11371", "11372", "11375", "11378", "11380", "11383", "11384", "11385", "11386", "11387", "11390", "11391", "11393", "11394", "11395", "11401", "11402", "11405", "11406", "11409", "11413", "11418", "11420", "11421", "11422", "11423", "11425", "11428", "11434", "11436", "11439", "11441", "11442", "11443", "11444", "11448", "11449", "11452", "11455", "11456", "11457", "11458", "11459", "11460", "11463", "11464", "11465", "11466", "11467", "11468", "11470", "11472", "11473", "11475", "11476", "11479", "11480", "11481", "11484", "11485", "11486", "11487", "11488", "11491", "11492", "11493", "11494", "11495", "11496", "11500", "11501", "11503", "11505", "11506", "11510", "11513", "11514", "11516", "11517", "11523", "11528", "11529", "11530", "11537", "11538", "11540", "11542", "11543", "11546", "11552", "11553", "11555", "11556", "11559", "11560", "11561", "11562", "11563", "11567", "11568", "11570", "11574", "11579", "11581", "11583", "11589", "11591", "11593", "11596", "11597", "11598", "11601", "11602", "11603", "11608", "11612", "11614", "11616", "11618", "11619", "11620", "11622", "11624", "11625", "11626", "11627", "11628", "11629", "11630", "11631", "11634", "11635", "11638", "11639", "11640", "11646", "11647", "11649", "11650", "11658", "11660", "11661", "11663", "11667", "11668", "11670", "11671", "11674", "11676", "11678", "11680", "11682", "11683", "11684", "11685", "11686", "11689", "11690", "11692", "11693", "11694", "11699", "11701", "11704", "11705", "11707", "11708", "11713", "11716", "11722", "11723", "11725", "11727", "11729", "11730", "11731", "11735", "11736", "11737", "11740", "11741", "11743", "11744", "11748", "11750", "11751", "11752", "11754", "11756", "11758", "11759", "11760", "11763", "11764", "11767", "11768", "11770", "11776", "11780", "11781", "11783", "11784", "11787", "11790", "11794", "11795", "11796", "11797", "11798", "11802", "11804", "11805", "11807", "11809", "11810", "11811", "11812", "11814", "11816", "11817", "11818", "11820", "11821", "11824", "11825", "11826", "11829", "11830", "11831", "11833", "11834", "11835", "11837", "11838", "11839", "11840", "11841", "11846", "11847", "11848", "11849", "11852", "11857", "11858", "11859", "11861", "11862", "11866", "11867", "11868", "11874", "11881", "11882", "11883", "11886", "11887", "11890", "11892", "11895", "11896", "11897", "11898", "11900", "11902", "11903", "11904", "11905", "11908", "11910", "11911", "11912", "11913", "11915", "11919", "11922", "11923", "11925", "11926", "11927", "11928", "11933", "11934", "11935", "11936", "11937", "11938", "11939", "11940", "11944", "11946", "11949", "11951", "11954", "11955", "11959", "11960", "11963", "11964", "11969", "11970", "11974", "11975", "11976", "11977", "11981", "11982", "11983", "11989", "11990", "11993", "11994", "11995", "11996", "11997", "11999", "12000", "12002", "12006", "12007", "12012", "12013", "12014", "12015", "12017", "12022", "12023", "12024", "12027", "12029", "12031", "12032", "12034", "12035", "12036", "12040", "12043", "12044", "12046", "12047", "12049", "12050", "12052", "12053", "12054", "12055", "12056", "12060", "12061", "12063", "12067", "12068", "12070", "12071", "12074", "12075", "12077", "12078", "12079", "12081", "12085", "12089", "12090", "12094", "12097", "12099", "12100", "12103", "12106", "12107", "12108", "12112", "12117", "12118", "12119", "12120", "12121", "12123", "12125", "12126", "12127", "12129", "12130", "12133", "12134", "12136", "12137", "12139", "12140", "12141", "12143", "12145", "12146", "12147", "12148", "12149", "12152", "12154", "12156", "12157", "12158", "12159", "12163", "12165", "12168", "12169", "12171", "12172", "12173", "12177", "12179", "12188", "12190", "12192", "12195", "12196", "12197", "12198", "12199", "12200", "12201", "12204", "12205", "12208", "12210", "12211", "12215", "12216", "12217", "12218", "12219", "12220", "12221", "12223", "12225", "12226", "12227", "12228", "12231", "12233", "12234", "12239", "12242", "12244", "12245", "12248", "12253", "12254", "12255", "12259", "12260", "12261", "12262", "12264", "12265", "12266", "12267", "12268", "12269", "12270", "12272", "12275", "12276", "12277", "12279", "12280", "12281", "12282", "12283", "12284", "12285", "12286", "12287", "12288", "12290", "12292", "12293", "12294", "12295", "12296", "12297", "12299", "12300", "12307", "12308", "12310", "12311", "12314", "12318", "12323", "12327", "12328", "12332", "12333", "12334", "12335", "12337", "12338", "12339", "12340", "12350", "12353", "12356", "12357", "12359", "12361", "12364", "12365", "12367", "12369", "12370", "12372", "12373", "12374", "12375", "12379", "12380", "12381", "12383", "12384", "12385", "12387", "12389", "12390", "12391", "12394", "12395", "12398", "12400", "12402", "12403", "12404", "12407", "12408", "12410", "12416", "12417", "12421", "12422", "12423", "12425", "12427", "12428", "12429", "12430", "12432", "12433", "12437", "12438", "12440", "12441", "12442", "12444", "12445", "12447", "12450", "12454", "12457", "12462", "12467", "12468", "12469", "12472", "12473", "12474", "12476", "12477", "12478", "12485", "12486", "12489", "12490", "12491", "12492", "12498", "12499", "12501", "12503", "12506", "12508", "12509", "12510", "12513", "12514", "12517", "12518", "12521", "12523", "12526", "12527", "12528", "12529", "12531", "12534", "12535", "12536", "12538", "12541", "12542", "12545", "12549", "12553", "12554", "12556", "12560", "12561", "12562", "12563", "12564", "12565", "12567", "12568", "12570", "12573", "12575", "12576", "12577", "12579", "12581", "12582", "12584", "12586", "12589", "12593", "12594", "12595", "12596", "12597", "12599", "12601", "12602", "12604", "12606", "12607", "12610", "12611", "12614", "12616", "12622", "12624", "12625", "12629", "12630", "12631", "12632", "12636", "12638", "12642", "12652", "12653", "12654", "12655", "12657", "12661", "12663", "12666", "12668", "12671", "12672", "12674", "12675", "12676", "12679", "12680", "12682", "12683", "12684", "12685", "12686", "12689", "12692", "12695", "12696", "12697", "12698", "12699", "12702", "12703", "12704", "12705", "12706", "12708", "12711", "12715", "12719", "12720", "12723", "12724", "12725", "12726", "12729", "12730", "12733", "12734", "12735", "12737", "12738", "12739", "12740", "12741", "12742", "12744", "12747", "12748", "12752", "12753", "12755", "12757", "12758", "12760", "12762", "12764", "12765", "12766", "12768", "12769", "12770", "12773", "12774", "12775", "12776", "12777", "12778", "12783", "12785", "12786", "12793", "12794", "12796", "12797", "12801", "12802", "12803", "12805", "12806", "12807", "12808", "12815", "12818", "12819", "12821", "12824", "12826", "12827", "12828", "12831", "12832", "12834", "12838", "12843", "12844", "12845", "12850", "12851", "12852", "12853", "12856", "12859", "12860", "12861", "12862", "12863", "12868", "12869", "12870", "12872", "12873", "12874", "12875", "12877", "12879", "12881", "12882", "12884", "12887", "12889", "12890", "12893", "12895", "12896", "12897", "12899", "12902", "12903", "12904", "12908", "12909", "12910", "12918", "12919", "12923", "12928", "12929", "12930", "12934", "12936", "12939", "12940", "12941", "12942", "12943", "12944", "12945", "12946", "12948", "12949", "12950", "12953", "12954", "12956", "12958", "12959", "12962", "12963", "12964", "12966", "12967", "12969", "12970", "12971", "12974", "12975", "12976", "12977", "12978", "12980", "12984", "12985", "12988", "12990", "12993", "12994", "12996", "12997", "12998", "12999", "13000", "13001", "13003", "13009", "13011", "13013", "13018", "13019", "13023", "13024", "13025", "13026", "13028", "13029", "13031", "13032", "13033", "13035", "13036", "13039", "13042", "13044", "13047", "13048", "13050", "13052", "13054", "13056", "13057", "13058", "13060", "13061", "13063", "13065", "13066", "13067", "13071", "13072", "13075", "13077", "13079", "13080", "13081", "13083", "13084", "13085", "13088", "13090", "13092", "13093", "13098", "13099", "13102", "13103", "13104", "13105", "13106", "13109", "13112", "13114", "13117", "13119", "13122", "13125", "13126", "13131", "13132", "13134", "13140", "13141", "13142", "13144", "13145", "13146", "13147", "13148", "13149", "13152", "13157", "13158", "13159", "13162", "13163", "13164", "13168", "13173", "13174", "13175", "13177", "13180", "13184", "13191", "13192", "13193", "13194", "13196", "13197", "13198", "13200", "13201", "13202", "13205", "13206", "13208", "13210", "13211", "13212", "13213", "13214", "13215", "13217", "13218", "13220", "13222", "13223", "13224", "13226", "13229", "13230", "13232", "13237", "13242", "13243", "13244", "13245", "13247", "13248", "13249", "13250", "13255", "13257", "13258", "13260", "13261", "13262", "13264", "13266", "13269", "13275", "13277", "13278", "13280", "13281", "13282", "13283", "13284", "13285", "13288", "13290", "13294", "13295", "13298", "13300", "13302", "13303", "13305", "13313", "13315", "13317", "13318", "13322", "13325", "13326", "13327", "13332", "13333", "13334", "13337", "13338", "13341", "13343", "13344", "13346", "13347", "13348", "13349", "13350", "13352", "13353", "13354", "13355", "13356", "13361", "13362", "13363", "13364", "13365", "13366", "13367", "13368", "13369", "13373", "13375", "13378", "13379", "13381", "13382", "13384", "13385", "13388", "13390", "13391", "13394", "13397", "13401", "13405", "13406", "13408", "13410", "13411", "13412", "13416", "13417", "13418", "13421", "13422", "13424", "13426", "13427", "13429", "13430", "13434", "13436", "13440", "13441", "13442", "13444", "13445", "13446", "13447", "13448", "13449", "13450", "13452", "13461", "13462", "13463", "13466", "13468", "13470", "13473", "13474", "13475", "13477", "13480", "13482", "13483", "13486", "13487", "13490", "13493", "13494", "13498", "13499", "13502", "13503", "13507", "13508", "13509", "13510", "13511", "13512", "13513", "13516", "13517", "13518", "13519", "13520", "13530", "13531", "13536", "13537", "13538", "13539", "13541", "13544", "13545", "13547", "13548", "13549", "13550", "13551", "13552", "13553", "13556", "13558", "13560", "13563", "13564", "13566", "13569", "13571", "13573", "13574", "13576", "13578", "13579", "13581", "13584", "13585", "13589", "13590", "13591", "13592", "13596", "13598", "13601", "13604", "13605", "13607", "13610", "13611", "13612", "13614", "13615", "13617", "13621", "13622", "13624", "13625", "13626", "13627", "13628", "13629", "13630", "13631", "13632", "13635", "13636", "13638", "13643", "13644", "13645", "13646", "13647", "13648", "13649", "13650", "13651", "13652", "13653", "13656", "13664", "13666", "13667", "13668", "13670", "13676", "13677", "13680", "13681", "13682", "13683", "13684", "13686", "13687", "13688", "13689", "13691", "13692", "13693", "13694", "13696", "13697", "13698", "13699", "13700", "13702", "13704", "13707", "13709", "13710", "13711", "13712", "13713", "13715", "13716", "13717", "13719", "13720", "13723", "13724", "13725", "13726", "13729", "13733", "13735", "13738", "13744", "13746", "13751", "13752", "13753", "13756", "13759", "13760", "13762", "13764", "13767", "13768", "13771", "13774", "13776", "13777", "13778", "13780", "13781", "13783", "13788", "13790", "13791", "13792", "13793", "13794", "13796", "13798", "13804", "13805", "13808", "13809", "13811", "13815", "13818", "13819", "13823", "13824", "13825", "13826", "13828", "13829", "13830", "13833", "13837", "13838", "13839", "13840", "13842", "13844", "13845", "13846", "13850", "13851", "13854", "13856", "13858", "13861", "13866", "13868", "13869", "13873", "13875", "13876", "13878", "13881", "13883", "13885", "13889", "13890", "13892", "13893", "13894", "13898", "13900", "13904", "13907", "13912", "13915", "13917", "13918", "13919", "13920", "13921", "13922", "13925", "13926", "13931", "13932", "13933", "13934", "13936", "13937", "13939", "13941", "13945", "13946", "13947", "13948", "13949", "13951", "13952", "13953", "13954", "13957", "13958", "13959", "13960", "13963", "13965", "13966", "13967", "13969", "13972", "13973", "13974", "13975", "13977", "13979", "13980", "13981", "13983", "13985", "13986", "13987", "13989", "13991", "13992", "13994", "13995", "13996", "14000", "14001", "14004", "14011", "14013", "14015", "14016", "14017", "14018", "14019", "14021", "14023", "14029", "14031", "14032", "14033", "14034", "14037", "14039", "14040", "14047", "14052", "14056", "14057", "14061", "14067", "14070", "14074", "14076", "14077", "14079", "14080", "14081", "14082", "14083", "14085", "14089", "14090", "14091", "14096", "14098", "14101", "14103", "14104", "14105", "14108", "14109", "14110", "14113", "14115", "14117", "14120", "14122", "14123", "14127", "14129", "14130", "14131", "14132", "14138", "14140", "14143", "14146", "14147", "14148", "14149", "14150", "14153", "14154", "14156", "14157", "14159", "14160", "14161", "14165", "14166", "14169", "14173", "14176", "14178", "14179", "14180", "14181", "14182", "14184", "14186", "14188", "14189", "14191", "14192", "14196", "14197", "14199", "14201", "14202", "14205", "14206", "14208", "14209", "14211", "14213", "14216", "14217", "14218", "14219", "14221", "14223", "14224", "14225", "14226", "14227", "14229", "14230", "14231", "14232", "14233", "14235", "14236", "14237", "14239", "14240", "14244", "14246", "14247", "14250", "14254", "14256", "14257", "14258", "14261", "14266", "14268", "14270", "14271", "14277", "14278", "14279", "14281", "14283", "14285", "14286", "14288", "14290", "14293", "14299", "14301", "14302", "14303", "14304", "14305", "14306", "14307", "14309", "14312", "14314", "14318", "14323", "14327", "14333", "14334", "14335", "14336", "14338", "14342", "14344", "14351", "14352", "14353", "14354", "14355", "14356", "14360", "14363", "14366", "14370", "14371", "14372", "14376", "14378", "14379", "14380", "14382", "14384", "14385", "14386", "14387", "14388", "14389", "14391", "14392", "14393", "14396", "14397", "14398", "14399", "14401", "14403", "14404", "14405", "14406", "14407", "14413", "14414", "14415", "14416", "14417", "14418", "14425", "14426", "14427", "14428", "14434", "14437", "14438", "14442", "14443", "14445", "14448", "14449", "14450", "14452", "14455", "14456", "14460", "14461", "14464", "14466", "14467", "14468", "14471", "14475", "14476", "14477", "14480", "14481", "14482", "14483", "14485", "14486", "14487", "14488", "14489", "14490", "14492", "14501", "14502", "14503", "14505", "14507", "14509", "14510", "14511", "14512", "14513", "14515", "14516", "14517", "14519", "14520", "14521", "14526", "14527", "14530", "14533", "14534", "14535", "14536", "14537", "14541", "14544", "14545", "14546", "14547", "14548", "14549", "14550", "14551", "14553", "14555", "14557", "14559", "14560", "14561", "14565", "14567", "14572", "14573", "14574", "14575", "14577", "14579", "14581", "14582", "14583", "14585", "14590", "14591", "14592", "14596", "14598", "14599", "14600", "14601", "14602", "14604", "14606", "14607", "14608", "14610", "14611", "14612", "14613", "14614", "14617", "14618", "14620", "14621", "14622", "14623", "14624", "14626", "14630", "14631", "14632", "14633", "14636", "14637", "14638", "14639", "14641", "14642", "14644", "14645", "14653", "14655", "14658", "14659", "14661", "14662", "14665", "14666", "14670", "14675", "14677", "14678", "14679", "14680", "14682", "14688", "14693", "14697", "14699", "14701", "14704", "14705", "14707", "14708", "14710", "14711", "14712", "14713", "14714", "14715", "14716", "14717", "14719", "14720", "14722", "14727", "14734", "14735", "14736", "14737", "14738", "14740", "14743", "14744", "14745", "14746", "14750", "14751", "14753", "14754", "14755", "14756", "14757", "14760", "14762", "14764", "14765", "14767", "14768", "14769", "14771", "14773", "14774", "14777", "14782", "14783", "14784", "14785", "14786", "14789", "14790", "14791", "14792", "14793", "14795", "14797", "14800", "14802", "14803", "14806", "14812", "14813", "14814", "14815", "14818", "14821", "14823", "14826", "14828", "14829", "14831", "14832", "14839", "14841", "14844", "14845", "14848", "14852", "14853", "14854", "14857", "14859", "14861", "14862", "14865", "14866", "14871", "14874", "14878", "14881", "14882", "14885", "14886", "14887", "14888", "14889", "14893", "14894", "14900", "14904", "14906", "14907", "14909", "14910", "14912", "14913", "14915", "14916", "14917", "14918", "14920", "14922", "14923", "14924", "14929", "14930", "14931", "14932", "14934", "14940", "14945", "14948", "14951", "14952", "14953", "14956", "14959", "14961", "14964", "14965", "14966", "14967", "14968", "14972", "14974", "14975", "14976", "14979", "14980", "14982", "14984", "14985", "14988", "14992", "14994", "14995", "14998", "14999", "15003", "15005", "15009", "15010", "15013", "15015", "15016", "15017", "15018", "15019", "15020", "15021", "15022", "15023", "15024", "15025", "15027", "15031", "15032", "15033", "15035", "15036", "15037", "15038", "15042", "15043", "15046", "15049", "15050", "15053", "15056", "15059", "15060", "15061", "15063", "15068", "15073", "15075", "15076", "15079", "15080", "15081", "15082", "15083", "15084", "15085", "15086", "15089", "15090", "15097", "15099", "15102", "15104", "15105", "15109", "15111", "15116", "15117", "15119", "15120", "15122", "15129", "15130", "15134", "15136", "15137", "15138", "15144", "15149", "15151", "15152", "15156", "15158", "15160", "15161", "15165", "15167", "15169", "15171", "15174", "15175", "15176", "15177", "15179", "15180", "15181", "15186", "15187", "15188", "15189", "15190", "15192", "15193", "15194", "15195", "15196", "15197", "15198", "15199", "15200", "15202", "15203", "15204", "15205", "15206", "15210", "15211", "15212", "15214", "15216", "15219", "15221", "15223", "15224", "15225", "15226", "15227", "15231", "15235", "15236", "15237", "15238", "15239", "15240", "15241", "15252", "15253", "15255", "15258", "15260", "15262", "15264", "15265", "15266", "15267", "15270", "15272", "15273", "15275", "15280", "15281", "15284", "15291", "15292", "15296", "15297", "15299", "15300", "15301", "15303", "15304", "15305", "15306", "15307", "15308", "15310", "15313", "15315", "15320", "15321", "15322", "15323", "15324", "15327", "15331", "15333", "15334", "15336", "15337", "15338", "15339", "15340", "15342", "15343", "15348", "15350", "15352", "15356", "15357", "15358", "15359", "15362", "15363", "15364", "15368", "15371", "15372", "15373", "15376", "15378", "15382", "15383", "15384", "15387", "15388", "15389", "15390", "15391", "15392", "15396", "15398", "15403", "15405", "15406", "15407", "15412", "15414", "15417", "15418", "15419", "15420", "15422", "15423", "15424", "15426", "15427", "15429", "15430", "15431", "15432", "15435", "15439", "15440", "15442", "15443", "15444", "15445", "15447", "15451", "15452", "15455", "15463", "15464", "15467", "15468", "15469", "15472", "15473", "15476", "15477", "15480", "15482", "15484", "15486", "15490", "15491", "15493", "15495", "15499", "15502", "15504", "15505", "15509", "15512", "15513", "15514", "15517", "15518", "15519", "15522", "15526", "15528", "15529", "15531", "15533", "15534", "15535", "15536", "15538", "15542", "15544", "15545", "15546", "15547", "15553", "15554", "15556", "15561", "15565", "15566", "15570", "15571", "15573", "15574", "15579", "15580", "15583", "15587", "15589", "15591", "15594", "15595", "15603", "15604", "15605", "15606", "15608", "15609", "15610", "15613", "15615", "15616", "15617", "15618", "15620", "15622", "15623", "15627", "15629", "15632", "15636", "15638", "15639", "15641", "15643", "15644", "15648", "15650", "15651", "15652", "15653", "15654", "15657", "15662", "15663", "15665", "15666", "15671", "15673", "15678", "15679", "15680", "15681", "15684", "15685", "15686", "15693", "15698", "15700", "15706", "15707", "15711", "15712", "15713", "15715", "15716", "15717", "15718", "15719", "15724", "15730", "15732", "15736", "15742", "15743", "15750", "15751", "15752", "15753", "15758", "15760", "15761", "15762", "15763", "15772", "15773", "15774", "15775", "15776", "15781", "15782", "15783", "15785", "15787", "15790", "15791", "15792", "15793", "15795", "15796", "15800", "15802", "15803", "15804", "15805", "15807", "15809", "15810", "15812", "15813", "15815", "15816", "15823", "15824", "15825", "15826", "15827", "15828", "15830", "15835", "15842", "15843", "15845", "15846", "15849", "15850", "15851", "15853", "15857", "15861", "15862", "15863", "15864", "15866", "15870", "15872", "15873", "15875", "15876", "15877", "15878", "15879", "15881", "15883", "15886", "15888", "15890", "15893", "15896", "15900", "15903", "15904", "15906", "15907", "15908", "15909", "15913", "15914", "15916", "15919", "15920", "15921", "15922", "15923", "15925", "15926", "15927", "15930", "15931", "15935", "15938", "15947", "15948", "15950", "15951", "15953", "15957", "15959", "15961", "15966", "15967", "15971", "15974", "15975", "15976", "15978", "15981", "15982", "15983", "15984", "15985", "15987", "15988", "15989", "15990", "15991", "15992", "15994", "15996", "15997", "16002", "16003", "16004", "16005", "16006", "16008", "16011", "16014", "16019", "16020", "16021", "16023", "16026", "16027", "16029", "16031", "16032", "16034", "16036", "16037", "16039", "16040", "16041", "16042", "16043", "16045", "16047", "16048", "16056", "16059", "16061", "16062", "16064", "16066", "16068", "16069", "16072", "16073", "16076", "16080", "16081", "16082", "16083", "16085", "16086", "16087", "16092", "16093", "16095", "16098", "16099", "16102", "16103", "16107", "16108", "16110", "16118", "16119", "16120", "16122", "16123", "16124", "16125", "16126", "16127", "16128", "16129", "16131", "16132", "16135", "16140", "16142", "16145", "16147", "16148", "16149", "16152", "16153", "16154", "16155", "16156", "16162", "16164", "16165", "16168", "16169", "16171", "16172", "16173", "16176", "16177", "16182", "16184", "16185", "16187", "16188", "16189", "16193", "16195", "16196", "16197", "16200", "16203", "16204", "16205", "16206", "16207", "16209", "16210", "16211", "16212", "16214", "16218", "16219", "16221", "16223", "16224", "16227", "16229", "16230", "16233", "16234", "16235", "16236", "16239", "16240", "16241", "16244", "16245", "16247", "16248", "16253", "16254", "16257", "16258", "16263", "16265", "16267", "16268", "16269", "16271", "16273", "16275", "16277", "16279", "16283", "16285", "16286", "16287", "16289", "16290", "16291", "16292", "16294", "16295", "16296", "16298", "16299", "16301", "16302", "16303", "16304", "16306", "16309", "16311", "16312", "16313", "16314", "16315", "16316", "16317", "16318", "16320", "16321", "16326", "16328", "16329", "16332", "16333", "16336", "16337", "16338", "16340", "16342", "16343", "16345", "16348", "16349", "16350", "16353", "16354", "16355", "16356", "16362", "16366", "16367", "16368", "16371", "16372", "16373", "16374", "16375", "16376", "16377", "16379", "16386", "16389", "16391", "16392", "16394", "16398", "16400", "16404", "16406", "16409", "16410", "16412", "16415", "16417", "16418", "16420", "16423", "16424", "16425", "16428", "16430", "16432", "16433", "16435", "16441", "16444", "16445", "16446", "16449", "16453", "16454", "16455", "16456", "16461", "16462", "16466", "16469", "16471", "16473", "16476", "16477", "16478", "16481", "16482", "16483", "16485", "16491", "16492", "16493", "16494", "16495", "16496", "16497", "16498", "16500", "16502", "16503", "16504", "16506", "16509", "16510", "16511", "16512", "16513", "16515", "16516", "16517", "16520", "16523", "16525", "16528", "16533", "16534", "16536", "16537", "16538", "16540", "16541", "16545", "16546", "16550", "16552", "16554", "16556", "16558", "16564", "16566", "16567", "16571", "16576", "16578", "16582", "16583", "16585", "16590", "16592", "16594", "16597", "16599", "16600", "16601", "16602", "16603", "16604", "16605", "16613", "16615", "16617", "16618", "16619", "16620", "16621", "16623", "16624", "16626", "16627", "16628", "16633", "16634", "16639", "16645", "16646", "16647", "16648", "16652", "16655", "16657", "16658", "16659", "16660", "16669", "16670", "16671", "16673", "16675", "16676", "16680", "16683", "16684", "16686", "16688", "16689", "16690", "16695", "16698", "16701", "16709", "16711", "16712", "16713", "16715", "16717", "16718", "16720", "16721", "16722", "16723", "16724", "16725", "16726", "16728", "16730", "16731", "16732", "16733", "16734", "16735", "16737", "16744", "16747", "16750", "16754", "16759", "16760", "16764", "16765", "16766", "16768", "16769", "16771", "16773", "16775", "16780", "16782", "16786", "16787", "16789", "16794", "16795", "16796", "16799", "16801", "16802", "16805", "16809", "16810", "16812", "16814", "16815", "16817", "16818", "16819", "16821", "16823", "16825", "16828", "16829", "16830", "16831", "16832", "16836", "16837", "16838", "16850", "16853", "16856", "16858", "16865", "16866", "16867", "16868", "16869", "16871", "16872", "16874", "16878", "16881", "16883", "16888", "16890", "16892", "16894", "16895", "16896", "16897", "16899", "16900", "16902", "16904", "16906", "16907", "16909", "16911", "16912", "16914", "16915", "16918", "16919", "16922", "16923", "16925", "16927", "16931", "16932", "16933", "16934", "16935", "16939", "16940", "16944", "16945", "16951", "16952", "16955", "16957", "16961", "16962", "16967", "16969", "16973", "16974", "16975", "16978", "16983", "16984", "16985", "16988", "16991", "16993", "16996", "16997", "17002", "17005", "17008", "17010", "17014", "17017", "17019", "17020", "17021", "17022", "17023", "17025", "17027", "17031", "17033", "17034", "17035", "17041", "17042", "17043", "17044", "17047", "17050", "17051", "17054", "17056", "17057", "17058", "17060", "17061", "17062", "17063", "17064", "17068", "17071", "17073", "17077", "17078", "17082", "17084", "17087", "17089", "17093", "17094", "17095", "17102", "17105", "17106", "17107", "17111", "17112", "17113", "17116", "17117", "17119", "17123", "17124", "17126", "17128", "17129", "17130", "17134", "17137", "17139", "17140", "17142", "17149", "17152", "17153", "17154", "17156", "17157", "17158", "17159", "17161", "17163", "17165", "17166", "17168", "17169", "17170", "17173", "17176", "17177", "17180", "17182", "17184", "17185", "17186", "17187", "17188", "17189", "17191", "17192", "17194", "17195", "17196", "17197", "17198", "17200", "17201", "17204", "17206", "17207", "17208", "17210", "17212", "17220", "17221", "17222", "17225", "17228", "17229", "17230", "17232", "17234", "17238", "17239", "17240", "17242", "17245", "17247", "17248", "17250", "17253", "17254", "17255", "17257", "17258", "17263", "17264", "17265", "17267", "17271", "17272", "17273", "17274", "17279", "17282", "17284", "17285", "17286", "17291", "17292", "17294", "17296", "17297", "17299", "17301", "17304", "17305", "17307", "17308", "17309", "17310", "17312", "17313", "17317", "17322", "17323", "17324", "17326", "17330", "17331", "17334", "17339", "17341", "17342", "17343", "17344", "17345", "17350", "17356", "17358", "17362", "17364", "17369", "17370", "17371", "17372", "17374", "17376", "17378", "17379", "17380", "17382", "17383", "17385", "17386", "17387", "17390", "17391", "17393", "17394", "17395", "17397", "17400", "17402", "17403", "17404", "17407", "17408", "17409", "17410", "17411", "17412", "17413", "17414", "17415", "17416", "17419", "17421", "17422", "17424", "17425", "17426", "17428", "17431", "17433", "17435", "17436", "17437", "17438", "17439", "17440", "17441", "17443", "17447", "17449", "17450", "17452", "17454", "17455", "17456", "17457", "17458", "17460", "17462", "17463", "17464", "17465", "17467", "17468", "17469", "17471", "17474", "17477", "17478", "17479", "17484", "17485", "17489", "17491", "17492", "17493", "17494", "17496", "17498", "17499", "17503", "17504", "17505", "17507", "17509", "17510", "17513", "17515", "17516", "17517", "17518", "17519", "17525", "17531", "17532", "17533", "17535", "17536", "17537", "17542", "17551", "17554", "17557", "17558", "17560", "17561", "17562", "17563", "17564", "17566", "17567", "17568", "17571", "17572", "17575", "17576", "17578", "17579", "17585", "17586", "17590", "17592", "17595", "17597", "17598", "17600", "17601", "17602", "17604", "17610", "17611", "17612", "17615", "17616", "17621", "17622", "17623", "17624", "17628", "17631", "17632", "17635", "17636", "17638", "17642", "17643", "17644", "17647", "17649", "17650", "17657", "17658", "17659", "17661", "17662", "17663", "17665", "17667", "17669", "17670", "17672", "17674", "17676", "17679", "17684", "17687", "17690", "17691", "17695", "17698", "17699", "17700", "17703", "17705", "17706", "17708", "17709", "17710", "17715", "17718", "17719", "17720", "17724", "17726", "17729", "17734", "17736", "17737", "17739", "17740", "17741", "17742", "17747", "17751", "17752", "17754", "17756", "17758", "17760", "17763", "17764", "17767", "17768", "17772", "17773", "17775", "17776", "17778", "17785", "17786", "17789", "17791", "17794", "17795", "17798", "17804", "17809", "17811", "17815", "17819", "17825", "17826", "17827", "17829", "17831", "17832", "17833", "17834", "17836", "17842", "17844", "17846", "17852", "17854", "17857", "17859", "17862", "17863", "17866", "17867", "17869", "17870", "17872", "17875", "17879", "17880", "17882", "17883", "17884", "17886", "17888", "17890", "17892", "17893", "17894", "17895", "17896", "17898", "17899", "17900", "17902", "17903", "17906", "17908", "17910", "17911", "17913", "17914", "17915", "17919", "17922", "17923", "17926", "17927", "17928", "17929", "17930", "17931", "17932", "17933", "17937", "17940", "17942", "17949", "17950", "17951", "17952", "17956", "17959", "17966", "17968", "17969", "17971", "17972", "17974", "17975", "17976", "17977", "17978", "17980", "17983", "17984", "17985", "17987", "17988", "17989", "17990", "17991", "17993", "17994", "17996", "17998", "18000", "18003", "18004", "18005", "18007", "18008", "18009", "18010", "18011", "18012", "18014", "18015", "18016", "18018", "18020", "18022", "18026", "18027", "18030", "18031", "18032", "18033", "18034", "18035", "18038", "18040", "18041", "18042", "18043", "18046", "18047", "18050", "18052", "18053", "18055", "18059", "18060", "18065", "18069", "18071", "18073", "18075", "18076", "18078", "18079", "18080", "18081", "18082", "18083", "18084", "18085", "18089", "18092", "18095", "18097", "18098", "18100", "18104", "18108", "18113", "18116", "18117", "18118", "18119", "18120", "18125", "18126", "18130", "18132", "18135", "18136", "18140", "18141", "18147", "18149", "18150", "18151", "18154", "18156", "18157", "18159", "18160", "18161", "18162", "18164", "18165", "18167", "18169", "18173", "18174", "18175", "18182", "18183", "18184", "18186", "18187", "18188", "18190", "18192", "18195", "18198", "18199", "18201", "18202", "18203", "18204", "18206", "18207", "18208", "18209", "18210", "18211", "18212", "18213", "18215", "18216", "18218", "18219", "18220", "18222", "18223", "18228", "18229", "18233", "18236", "18237", "18239", "18241", "18245", "18248", "18249", "18250", "18251", "18252", "18253", "18254", "18256", "18259", "18262", "18264", "18265", "18269", "18272", "18274", "18275", "18276", "18277", "18278", "18279", "18283", "18284", "18285", "18289", "18292", "18295", "18296", "18297", "18298", "18299", "18302", "18306", "18310", "18312", "18315", "18316", "18322", "18323", "18324", "18326", "18327", "18330", "18331", "18332", "18333", "18335", "18341", "18342", "18343", "18350", "18352", "18354", "18358", "18361", "18362", "18369", "18373", "18375", "18376", "18377", "18378", "18379", "18381", "18382", "18387", "18389", "18391", "18396", "18398", "18400", "18402", "18407", "18408", "18409", "18411", "18412", "18413", "18414", "18416", "18417", "18419", "18421", "18424", "18426", "18427", "18428", "18431", "18433", "18435", "18436", "18437", "18438", "18439", "18441", "18443", "18444", "18445", "18447", "18449", "18450", "18451", "18454", "18455", "18456", "18457", "18458", "18462", "18465", "18466", "18469", "18471", "18474", "18475", "18478", "18479", "18480", "18484", "18487", "18488", "18489", "18490", "18491", "18495", "18496", "18497", "18499", "18500", "18501", "18502", "18507", "18509", "18511", "18512", "18514", "18517", "18518", "18519", "18520", "18523", "18524", "18526", "18527", "18528", "18529", "18530", "18534", "18535", "18537", "18541", "18542", "18543", "18546", "18547", "18549", "18550", "18551", "18552", "18553", "18555", "18556", "18557", "18563", "18565", "18566", "18569", "18570", "18571", "18574", "18575", "18576", "18578", "18579", "18580", "18583", "18584", "18586", "18587", "18588", "18591", "18592", "18594", "18598", "18599", "18601", "18603", "18604", "18605", "18606", "18608", "18612", "18613", "18614", "18618", "18619", "18621", "18623", "18625", "18626", "18628", "18629", "18630", "18631", "18633", "18635", "18636", "18637", "18639", "18644", "18647", "18648", "18649", "18650", "18654", "18655", "18656", "18657", "18661", "18664", "18665", "18667", "18669", "18670", "18671", "18672", "18677", "18679", "18682", "18685", "18686", "18690", "18692", "18694", "18698", "18700", "18701", "18703", "18704", "18714", "18715", "18719", "18722", "18727", "18729", "18733", "18734", "18735", "18736", "18738", "18739", "18741", "18742", "18744", "18746", "18747", "18749", "18750", "18754", "18755", "18759", "18760", "18761", "18766", "18768", "18769", "18770", "18772", "18773", "18774", "18775", "18779", "18782", "18783", "18785", "18786", "18787", "18788", "18790", "18792", "18794", "18795", "18796", "18797", "18799", "18803", "18804", "18805", "18809", "18810", "18811", "18813", "18814", "18816", "18817", "18820", "18822", "18825", "18827", "18830", "18831", "18834", "18835", "18837", "18838", "18839", "18840", "18843", "18845", "18846", "18847", "18848", "18850", "18854", "18855", "18860", "18861", "18863", "18865", "18866", "18867", "18868", "18869", "18871", "18872", "18874", "18875", "18876", "18877", "18879", "18880", "18882", "18884", "18887", "18891", "18894", "18895", "18900", "18902", "18904", "18906", "18910", "18915", "18916", "18917", "18919", "18922", "18924", "18925", "18926", "18927", "18931", "18932", "18933", "18935", "18936", "18937", "18938", "18940", "18951", "18953", "18954", "18958", "18960", "18961", "18962", "18966", "18969", "18971", "18972", "18975", "18976", "18977", "18978", "18979", "18980", "18982", "18984", "18986", "18987", "18989", "18990", "18993", "18995", "18996", "18997", "18998", "18999", "19001", "19004", "19005", "19006", "19007", "19008", "19009", "19010", "19013", "19017", "19019", "19020", "19023", "19024", "19025", "19029", "19032", "19033", "19038", "19039", "19042", "19043", "19045", "19046", "19047", "19048", "19049", "19050", "19051", "19053", "19054", "19055", "19056", "19057", "19058", "19061", "19062", "19063", "19064", "19068", "19070", "19074", "19077", "19079", "19080", "19082", "19086", "19087", "19090", "19092", "19093", "19094", "19095", "19098", "19099", "19100", "19101", "19102", "19104", "19110", "19111", "19112", "19114", "19115", "19116", "19118", "19119", "19123", "19126", "19127", "19129", "19130", "19131", "19133", "19134", "19137", "19139", "19140", "19143", "19144", "19145", "19149", "19151", "19153", "19156", "19157", "19162", "19164", "19171", "19173", "19175", "19176", "19177", "19181", "19182", "19185", "19188", "19191", "19193", "19194", "19195", "19196", "19197", "19202", "19203", "19204", "19206", "19209", "19210", "19212", "19214", "19216", "19217", "19219", "19220", "19222", "19224", "19225", "19226", "19227", "19228", "19230", "19233", "19234", "19235", "19238", "19239", "19245", "19249", "19252", "19255", "19257", "19258", "19259", "19261", "19262", "19268", "19272", "19273", "19275", "19276", "19279", "19283", "19286", "19300", "19302", "19303", "19306", "19308", "19309", "19310", "19315", "19317", "19319", "19320", "19322", "19325", "19326", "19327", "19328", "19329", "19334", "19340", "19341", "19343", "19344", "19350", "19352", "19353", "19354", "19356", "19363", "19364", "19365", "19366", "19368", "19370", "19371", "19374", "19375", "19376", "19377", "19378", "19379", "19380", "19381", "19382", "19383", "19385", "19387", "19389", "19390", "19392", "19393", "19395", "19399", "19406", "19408", "19410", "19413", "19417", "19419", "19420", "19423", "19425", "19426", "19428", "19430", "19431", "19433", "19437", "19438", "19440", "19443", "19445", "19446", "19447", "19448", "19453", "19455", "19456", "19459", "19460", "19461", "19462", "19463", "19465", "19466", "19470", "19471", "19473", "19474", "19475", "19476", "19479", "19483", "19484", "19488", "19490", "19491", "19492", "19496", "19497", "19500", "19501", "19506", "19507", "19508", "19509", "19510", "19511", "19512", "19514", "19516", "19519", "19521", "19524", "19529", "19530", "19534", "19535", "19544", "19546", "19547", "19550", "19553", "19554", "19555", "19558", "19560", "19561", "19563", "19564", "19565", "19566", "19567", "19568", "19570", "19571", "19574", "19576", "19577", "19578", "19582", "19584", "19588", "19591", "19592", "19595", "19597", "19598", "19600", "19603", "19604", "19605", "19606", "19610", "19612", "19615", "19616", "19617", "19618", "19619", "19620", "19622", "19623", "19624", "19627", "19628", "19629", "19630", "19631", "19633", "19634", "19640", "19642", "19646", "19647", "19648", "19649", "19652", "19653", "19655", "19656", "19657", "19659", "19660", "19661", "19662", "19664", "19667", "19672", "19673", "19674", "19680", "19681", "19682", "19685", "19687", "19689", "19692", "19697", "19699", "19700", "19702", "19703", "19705", "19706", "19710", "19711", "19715", "19717", "19720", "19723", "19724", "19726", "19727", "19728", "19729", "19730", "19732", "19736", "19741", "19742", "19743", "19744", "19745", "19749", "19750", "19751", "19753", "19754", "19755", "19757", "19758", "19762", "19764", "19766", "19767", "19769", "19771", "19772", "19773", "19774", "19775", "19776", "19777", "19778", "19781", "19783", "19785", "19786", "19788", "19790", "19792", "19795", "19799", "19804", "19805", "19807", "19808", "19810", "19811", "19814", "19815", "19816", "19817", "19818", "19819", "19820", "19821", "19822", "19823", "19824", "19825", "19826", "19828", "19829", "19832", "19834", "19836", "19841", "19842", "19843", "19849", "19851", "19852", "19853", "19854", "19855", "19856", "19857", "19858", "19862", "19864", "19865", "19866", "19868", "19869", "19871", "19872", "19873", "19874", "19876", "19880", "19881", "19883", "19884", "19885", "19887", "19888", "19889", "19892", "19896", "19897", "19898", "19899", "19900", "19901", "19902", "19904", "19905", "19906", "19907", "19908", "19913", "19914", "19916", "19918", "19919", "19923", "19924", "19925", "19929", "19930", "19931", "19932", "19933", "19934", "19937", "19941", "19942", "19943", "19950", "19952", "19956", "19957", "19958", "19961", "19962", "19967", "19968", "19969", "19970", "19971", "19973", "19974", "19977", "19980", "19981", "19985", "19986", "19987", "19992", "19993", "19994", "19996", "19999", "20000", "20007", "20008", "20010", "20014", "20015", "20018", "20020", "20025", "20026", "20027", "20030", "20033", "20036", "20039", "20040", "20041", "20042", "20044", "20046", "20054", "20056", "20058", "20061", "20063", "20064", "20067", "20068", "20069", "20070", "20072", "20075", "20078", "20079", "20081", "20082", "20090", "20092", "20094", "20099", "20100", "20102", "20103", "20104", "20106", "20107", "20109", "20111", "20114", "20115", "20116", "20117", "20118", "20119", "20121", "20123", "20124", "20125", "20129", "20130", "20131", "20133", "20134", "20135", "20138", "20139", "20140", "20147", "20150", "20151", "20152", "20154", "20155", "20158", "20161", "20162", "20163", "20164", "20165", "20167", "20168", "20169", "20170", "20171", "20172", "20175", "20178", "20179", "20184", "20185", "20188", "20189", "20190", "20193", "20194", "20202", "20203", "20204", "20207", "20208", "20209", "20210", "20212", "20214", "20216", "20217", "20218", "20219", "20220", "20224", "20226", "20229", "20231", "20232", "20234", "20240", "20241", "20244", "20245", "20246", "20251", "20252", "20254", "20257", "20258", "20260", "20261", "20262", "20264", "20265", "20270", "20271", "20272", "20273", "20274", "20275", "20276", "20277", "20279", "20282", "20283", "20285", "20286", "20291", "20294", "20296", "20300", "20303", "20309", "20312", "20313", "20315", "20316", "20317", "20320", "20321", "20323", "20324", "20327", "20328", "20329", "20331", "20332", "20333", "20335", "20337", "20338", "20339", "20341", "20342", "20343", "20344", "20345", "20346", "20349", "20351", "20356", "20361", "20362", "20363", "20364", "20376", "20380", "20381", "20382", "20383", "20384", "20385", "20386", "20387", "20389", "20391", "20392", "20393", "20394", "20395", "20398", "20399", "20400", "20402", "20405", "20406", "20407", "20408", "20409", "20410", "20411", "20412", "20413", "20415", "20416", "20418", "20419", "20422", "20423", "20425", "20427", "20429", "20435", "20437", "20438", "20440", "20441", "20442", "20446", "20447", "20448", "20449", "20450", "20451", "20452", "20454", "20459", "20461", "20466", "20467", "20471", "20474", "20476", "20477", "20479", "20481", "20486", "20490", "20492", "20495", "20496", "20498", "20499", "20501", "20505", "20509", "20510", "20512", "20513", "20514", "20517", "20518", "20520", "20521", "20524", "20525", "20526", "20528", "20530", "20535", "20537", "20538", "20540", "20541", "20542", "20550", "20554", "20555", "20557", "20560", "20561", "20562", "20563", "20564", "20566", "20568", "20569", "20570", "20573", "20574", "20575", "20576", "20579", "20581", "20582", "20583", "20586", "20591", "20592", "20593", "20594", "20595", "20596", "20597", "20599", "20601", "20604", "20607", "20610", "20611", "20612", "20613", "20614", "20616", "20618", "20619", "20623", "20624", "20625", "20628", "20629", "20632", "20633", "20635", "20636", "20639", "20640", "20641", "20643", "20649", "20650", "20655", "20658", "20659", "20661", "20662", "20663", "20664", "20665", "20667", "20671", "20673", "20674", "20675", "20676", "20677", "20678", "20683", "20684", "20688", "20691", "20696", "20699", "20701", "20703", "20704", "20705", "20709", "20711", "20712", "20713", "20714", "20715", "20718", "20719", "20726", "20728", "20729", "20731", "20732", "20735", "20738", "20739", "20740", "20741", "20743", "20745", "20747", "20748", "20749", "20751", "20756", "20758", "20760", "20762", "20763", "20765", "20769", "20772", "20774", "20775", "20776", "20777", "20785", "20787", "20788", "20790", "20794", "20796", "20799", "20802", "20803", "20805", "20806", "20807", "20811", "20813", "20815", "20817", "20819", "20820", "20821", "20822", "20824", "20825", "20826", "20827", "20831", "20833", "20834", "20840", "20842", "20843", "20845", "20846", "20847", "20848", "20850", "20851", "20853", "20854", "20855", "20858", "20862", "20863", "20867", "20868", "20869", "20871", "20872", "20873", "20874", "20876", "20877", "20881", "20882", "20883", "20884", "20887", "20890", "20893", "20896", "20897", "20898", "20899", "20901", "20902", "20903", "20904", "20905", "20906", "20908", "20909", "20911", "20912", "20913", "20916", "20917", "20919", "20920", "20922", "20925", "20926", "20927", "20929", "20930", "20932", "20933", "20934", "20935", "20936", "20938", "20939", "20940", "20942", "20945", "20947", "20948", "20949", "20951", "20952", "20955", "20958", "20960", "20961", "20964", "20965", "20966", "20969", "20971", "20975", "20976", "20977", "20978", "20979", "20981", "20985", "20986", "20989", "20995", "20997", "20999", "21001", "21002", "21006", "21007", "21009", "21010", "21011", "21012", "21014", "21015", "21016", "21017", "21018", "21020", "21022", "21024", "21025", "21027", "21028", "21030", "21031", "21032", "21035", "21037", "21038", "21039", "21040", "21042", "21046", "21047", "21051", "21052", "21054", "21055", "21056", "21063", "21064", "21065", "21067", "21073", "21074", "21076", "21077", "21080", "21084", "21090", "21091", "21092", "21094", "21095", "21096", "21097", "21098", "21100", "21101", "21103", "21105", "21106", "21107", "21109", "21110", "21111", "21112", "21113", "21114", "21115", "21118", "21119", "21120", "21121", "21122", "21129", "21130", "21131", "21133", "21135", "21136", "21138", "21140", "21141", "21142", "21143", "21144", "21148", "21151", "21153", "21154", "21156", "21157", "21158", "21162", "21163", "21164", "21167", "21168", "21170", "21172", "21173", "21174", "21176", "21177", "21178", "21179", "21182", "21183", "21187", "21188", "21190", "21191", "21192", "21195", "21196", "21198", "21199", "21200", "21203", "21204", "21208", "21211", "21212", "21216", "21217", "21218", "21226", "21227", "21228", "21229", "21230", "21231", "21232", "21234", "21235", "21237", "21240", "21241", "21242", "21243", "21245", "21246", "21249", "21250", "21251", "21253", "21254", "21255", "21258", "21259", "21261", "21262", "21263", "21264", "21266", "21272", "21276", "21278", "21283", "21288", "21291", "21297", "21301", "21302", "21303", "21306", "21308", "21310", "21312", "21314", "21316", "21318", "21319", "21321", "21323", "21328", "21333", "21334", "21337", "21338", "21340", "21341", "21342", "21344", "21345", "21351", "21354", "21356", "21357", "21359", "21360", "21361", "21363", "21364", "21365", "21366", "21367", "21369", "21370", "21371", "21375", "21376", "21377", "21378", "21380", "21384", "21386", "21387", "21390", "21391", "21392", "21393", "21394", "21395", "21396", "21400", "21403", "21405", "21411", "21416", "21418", "21420", "21422", "21424", "21425", "21426", "21430", "21431", "21437", "21438", "21439", "21442", "21444", "21450", "21452", "21453", "21457", "21458", "21461", "21470", "21471", "21472", "21475", "21477", "21480", "21483", "21484", "21485", "21486", "21487", "21488", "21493", "21495", "21497", "21500", "21502", "21504", "21506", "21507", "21510", "21512", "21513", "21515", "21516", "21518", "21520", "21521", "21522", "21523", "21525", "21526", "21527", "21534", "21536", "21537", "21539", "21542", "21543", "21545", "21547", "21550", "21551", "21552", "21555", "21558", "21560", "21561", "21563", "21569", "21570", "21572", "21573", "21576", "21577", "21579", "21580", "21581", "21585", "21586", "21589", "21595", "21596", "21597", "21599", "21600", "21602", "21603", "21604", "21608", "21609", "21611", "21612", "21613", "21615", "21616", "21618", "21619", "21622", "21623", "21626", "21628", "21630", "21633", "21636", "21637", "21638", "21640", "21641", "21643", "21645", "21650", "21653", "21655", "21657", "21659", "21660", "21661", "21662", "21663", "21665", "21671", "21672", "21674", "21675", "21676", "21677", "21679", "21684", "21685", "21687", "21689", "21690", "21691", "21694", "21696", "21698", "21700", "21701", "21702", "21704", "21707", "21709", "21711", "21714", "21716", "21722", "21723", "21724", "21726", "21728", "21732", "21736", "21739", "21740", "21744", "21745", "21746", "21748", "21749", "21751", "21753", "21754", "21755", "21756", "21757", "21758", "21759", "21765", "21768", "21769", "21770", "21771", "21775", "21776", "21777", "21779", "21780", "21782", "21783", "21785", "21787", "21792", "21793", "21794", "21795", "21798", "21799", "21800", "21801", "21802", "21804", "21807", "21808", "21811", "21814", "21816", "21817", "21820", "21822", "21823", "21824", "21825", "21826", "21828", "21829", "21830", "21835", "21837", "21838", "21841", "21842", "21843", "21845", "21846", "21849", "21851", "21855", "21857", "21858", "21859", "21861", "21863", "21864", "21866", "21867", "21868", "21871", "21873", "21875", "21876", "21878", "21883", "21884", "21888", "21889", "21890", "21893", "21894", "21895", "21897", "21898", "21899", "21900", "21903", "21906", "21909", "21910", "21912", "21913", "21914", "21915", "21916", "21918", "21919", "21920", "21924", "21928", "21929", "21930", "21931", "21932", "21933", "21937", "21938", "21939", "21942", "21943", "21944", "21945", "21946", "21947", "21948", "21949", "21951", "21953", "21954", "21956", "21957", "21961", "21962", "21963", "21964", "21970", "21974", "21976", "21978", "21982", "21983", "21984", "21985", "21986", "21989", "21991", "21993", "21996", "21997", "21999", "22000", "22002", "22007", "22008", "22009", "22010", "22016", "22018", "22019", "22020", "22021", "22023", "22024", "22027", "22028", "22030", "22031", "22035", "22036", "22037", "22038", "22040", "22041", "22043", "22047", "22053", "22054", "22056", "22058", "22060", "22061", "22063", "22066", "22068", "22069", "22070", "22071", "22072", "22073", "22074", "22076", "22078", "22079", "22081", "22084", "22085", "22086", "22087", "22088", "22089", "22091", "22092", "22094", "22095", "22097", "22098", "22100", "22102", "22104", "22106", "22107", "22108", "22109", "22111", "22114", "22115", "22116", "22117", "22118", "22119", "22120", "22121", "22122", "22124", "22125", "22126", "22127", "22129", "22132", "22134", "22137", "22138", "22141", "22149", "22150", "22151", "22152", "22157", "22159", "22162", "22166", "22169", "22171", "22173", "22176", "22177", "22180", "22181", "22182", "22184", "22186", "22187", "22188", "22189", "22191", "22192", "22194", "22195", "22196", "22198", "22199", "22204", "22206", "22211", "22212", "22214", "22219", "22221", "22222", "22224", "22228", "22233", "22236", "22237", "22239", "22240", "22242", "22243", "22244", "22245", "22247", "22250", "22254", "22255", "22258", "22259", "22260", "22262", "22268", "22270", "22271", "22274", "22277", "22279", "22280", "22281", "22284", "22285", "22286", "22289", "22293", "22294", "22296", "22297", "22299", "22301", "22303", "22304", "22307", "22311", "22314", "22316", "22319", "22322", "22323", "22324", "22326", "22327", "22328", "22329", "22331", "22332", "22333", "22334", "22335", "22337", "22339", "22345", "22346", "22348", "22350", "22353", "22355", "22357", "22359", "22360", "22361", "22364", "22367", "22369", "22372", "22375", "22376", "22377", "22378", "22379", "22380", "22383", "22384", "22385", "22386", "22392", "22393", "22395", "22398", "22403", "22404", "22406", "22407", "22409", "22410", "22411", "22413", "22414", "22415", "22419", "22421", "22422", "22425", "22427", "22428", "22433", "22435", "22438", "22439", "22441", "22442", "22444", "22446", "22447", "22448", "22449", "22451", "22453", "22455", "22456", "22457", "22458", "22461", "22464", "22467", "22469", "22476", "22477", "22480", "22481", "22483", "22486", "22488", "22493", "22494", "22498", "22500", "22503", "22504", "22505", "22506", "22508", "22509", "22510", "22511", "22512", "22514", "22519", "22520", "22521", "22523", "22525", "22526", "22529", "22530", "22531", "22532", "22534", "22536", "22538", "22539", "22541", "22544", "22545", "22546", "22547", "22554", "22555", "22556", "22558", "22562", "22563", "22564", "22566", "22568", "22572", "22574", "22575", "22576", "22580", "22582", "22583", "22585", "22586", "22590", "22591", "22592", "22593", "22596", "22599", "22600", "22601", "22603", "22606", "22607", "22608", "22609", "22613", "22616", "22618", "22622", "22623", "22624", "22628", "22629", "22630", "22631", "22633", "22634", "22636", "22638", "22641", "22642", "22645", "22646", "22650", "22653", "22655", "22660", "22661", "22662", "22663", "22664", "22668", "22669", "22670", "22673", "22676", "22679", "22683", "22684", "22685", "22690", "22691", "22692", "22693", "22696", "22697", "22698", "22700", "22701", "22703", "22704", "22705", "22706", "22707", "22709", "22711", "22712", "22713", "22714", "22723", "22725", "22727", "22728", "22729", "22732", "22733", "22734", "22736", "22741", "22742", "22743", "22744", "22746", "22755", "22757", "22759", "22761", "22762", "22763", "22767", "22769", "22770", "22772", "22775", "22776", "22780", "22781", "22784", "22786", "22788", "22797", "22798", "22799", "22800", "22801", "22802", "22803", "22804", "22805", "22806", "22808", "22809", "22810", "22812", "22813", "22814", "22815", "22817", "22818", "22819", "22821", "22822", "22824", "22825", "22827", "22828", "22829", "22830", "22831", "22837", "22838", "22841", "22842", "22843", "22844", "22845", "22846", "22848", "22850", "22853", "22854", "22856", "22858", "22859", "22860", "22862", "22865", "22866", "22867", "22869", "22872", "22873", "22874", "22876", "22877", "22878", "22879", "22880", "22881", "22884", "22885", "22886", "22887", "22890", "22892", "22893", "22895", "22896", "22897", "22902", "22907", "22910", "22918", "22919", "22920", "22923", "22924", "22925", "22928", "22930", "22931", "22933", "22934", "22938", "22940", "22942", "22943", "22945", "22947", "22949", "22953", "22954", "22957", "22961", "22962", "22964", "22967", "22968", "22969", "22971", "22972", "22973", "22977", "22980", "22981", "22987", "22988", "22989", "22990", "22993", "22996", "22999", "23001", "23003", "23006", "23012", "23014", "23015", "23016", "23019", "23022", "23028", "23029", "23030", "23031", "23034", "23036", "23038", "23040", "23043", "23044", "23045", "23046", "23047", "23048", "23051", "23054", "23055", "23056", "23057", "23059", "23061", "23062", "23064", "23065", "23067", "23070", "23071", "23072", "23073", "23074", "23077", "23078", "23079", "23080", "23081", "23084", "23085", "23093", "23094", "23101", "23102", "23107", "23108", "23110", "23112", "23113", "23115", "23121", "23124", "23125", "23127", "23130", "23131", "23133", "23134", "23135", "23136", "23137", "23141", "23145", "23146", "23151", "23152", "23153", "23154", "23155", "23156", "23158", "23159", "23160", "23161", "23163", "23164", "23166", "23167", "23170", "23171", "23172", "23174", "23175", "23176", "23177", "23178", "23183", "23184", "23185", "23187", "23189", "23190", "23194", "23195", "23202", "23203", "23204", "23207", "23209", "23211", "23212", "23214", "23217", "23219", "23220", "23221", "23224", "23225", "23227", "23229", "23231", "23233", "23235", "23237", "23240", "23242", "23243", "23244", "23245", "23246", "23248", "23249", "23250", "23251", "23252", "23254", "23255", "23259", "23261", "23264", "23265", "23273", "23274", "23276", "23277", "23278", "23280", "23281", "23282", "23283", "23287", "23288", "23291", "23294", "23296", "23299", "23303", "23304", "23305", "23306", "23308", "23309", "23310", "23311", "23313", "23314", "23315", "23317", "23318", "23323", "23324", "23326", "23327", "23331", "23337", "23339", "23340", "23343", "23344", "23345", "23347", "23351", "23354", "23355", "23356", "23357", "23358", "23359", "23360", "23361", "23368", "23369", "23370", "23372", "23374", "23377", "23378", "23379", "23381", "23382", "23383", "23384", "23386", "23388", "23391", "23392", "23395", "23396", "23404", "23407", "23408", "23411", "23412", "23415", "23417", "23421", "23425", "23426", "23427", "23428", "23430", "23431", "23435", "23437", "23438", "23442", "23444", "23445", "23446", "23449", "23453", "23456", "23459", "23470", "23476", "23478", "23479", "23480", "23481", "23483", "23484", "23486", "23487", "23489", "23490", "23491", "23493", "23495", "23496", "23499", "23502", "23503", "23504", "23505", "23514", "23516", "23524", "23526", "23527", "23528", "23529", "23530", "23532", "23535", "23536", "23539", "23541", "23542", "23543", "23544", "23545", "23548", "23549", "23550", "23551", "23559", "23562", "23564", "23571", "23572", "23573", "23575", "23576", "23577", "23580", "23581", "23583", "23585", "23587", "23590", "23591", "23593", "23594", "23595", "23597", "23598", "23600", "23606", "23607", "23611", "23612", "23613", "23615", "23616", "23619", "23620", "23622", "23623", "23625", "23628", "23634", "23635", "23638", "23639", "23641", "23642", "23646", "23649", "23654", "23655", "23656", "23661", "23662", "23663", "23664", "23666", "23674", "23676", "23677", "23679", "23680", "23681", "23684", "23692", "23693", "23695", "23701", "23702", "23703", "23705", "23706", "23708", "23712", "23714", "23715", "23719", "23723", "23726", "23727", "23730", "23738", "23746", "23749", "23752", "23753", "23763", "23766", "23768", "23769", "23770", "23771", "23772", "23776", "23777", "23782", "23783", "23785", "23790", "23792", "23795", "23796", "23798", "23799", "23803", "23804", "23805", "23806", "23810", "23812", "23815", "23816", "23817", "23819", "23821", "23822", "23825", "23826", "23827", "23829", "23830", "23831", "23833", "23835", "23839", "23842", "23843", "23844", "23845", "23846", "23849", "23855", "23856", "23857", "23859", "23860", "23862", "23863", "23865", "23867", "23868", "23869", "23870", "23871", "23872", "23873", "23875", "23876", "23877", "23878", "23880", "23881", "23882", "23883", "23884", "23888", "23889", "23890", "23892", "23894", "23899", "23905", "23906", "23907", "23909", "23915", "23916", "23917", "23921", "23922", "23923", "23924", "23925", "23930", "23932", "23933", "23934", "23937", "23938", "23940", "23941", "23945", "23947", "23948", "23951", "23952", "23955", "23957", "23958", "23959", "23960", "23966", "23967", "23968", "23970", "23971", "23974", "23975", "23977", "23978", "23979", "23980", "23981", "23982", "23984", "23989", "23991", "23992", "23993", "23994", "23995", "23996", "24002", "24003", "24004", "24006", "24008", "24014", "24015", "24019", "24020", "24022", "24023", "24024", "24025", "24029", "24036", "24037", "24038", "24041", "24047", "24049", "24050", "24051", "24052", "24053", "24054", "24056", "24057", "24058", "24060", "24061", "24062", "24065", "24067", "24069", "24070", "24071", "24073", "24077", "24078", "24079", "24084", "24088", "24090", "24091", "24093", "24094", "24096", "24097", "24098", "24102", "24104", "24106", "24110", "24113", "24114", "24116", "24118", "24119", "24120", "24121", "24122", "24123", "24124", "24126", "24129", "24131", "24133", "24134", "24136", "24141", "24142", "24146", "24147", "24148", "24150", "24151", "24152", "24153", "24155", "24157", "24161", "24162", "24166", "24167", "24169", "24170", "24171", "24174", "24175", "24176", "24177", "24179", "24181", "24187", "24188", "24189", "24190", "24191", "24192", "24195", "24196", "24198", "24199", "24200", "24201", "24202", "24203", "24204", "24205", "24208", "24210", "24211", "24215", "24216", "24219", "24220", "24221", "24222", "24223", "24224", "24230", "24233", "24235", "24238", "24239", "24240", "24243", "24244", "24245", "24247", "24249", "24251", "24252", "24253", "24254", "24256", "24258", "24259", "24260", "24261", "24262", "24264", "24266", "24267", "24273", "24277", "24278", "24280", "24282", "24285", "24286", "24287", "24288", "24291", "24292", "24295", "24296", "24297", "24298", "24299", "24301", "24303", "24304", "24306", "24308", "24312", "24313", "24314", "24316", "24317", "24318", "24319", "24320", "24323", "24324", "24325", "24326", "24327", "24330", "24331", "24333", "24334", "24335", "24336", "24337", "24342", "24346", "24347", "24348", "24349", "24351", "24352", "24354", "24356", "24359", "24361", "24363", "24366", "24367", "24368", "24371", "24372", "24374", "24382", "24383", "24385", "24387", "24388", "24391", "24394", "24395", "24396", "24397", "24399", "24402", "24403", "24407", "24409", "24410", "24411", "24413", "24415", "24416", "24418", "24421", "24425", "24427", "24428", "24429", "24430", "24432", "24434", "24438", "24439", "24441", "24442", "24447", "24448", "24449", "24451", "24452", "24454", "24458", "24463", "24468", "24471", "24473", "24474", "24475", "24476", "24477", "24480", "24482", "24483", "24484", "24486", "24489", "24490", "24491", "24495", "24497", "24499", "24502", "24504", "24506", "24510", "24514", "24517", "24520", "24521", "24523", "24524", "24525", "24526", "24527", "24528", "24529", "24532", "24534", "24536", "24539", "24540", "24541", "24542", "24544", "24547", "24550", "24551", "24555", "24560", "24561", "24564", "24565", "24566", "24567", "24568", "24569", "24571", "24573", "24575", "24576", "24578", "24579", "24580", "24582", "24583", "24584", "24585", "24590", "24594", "24595", "24599", "24602", "24603", "24604", "24605", "24606", "24607", "24610", "24613", "24614", "24616", "24618", "24619", "24620", "24625", "24626", "24627", "24629", "24630", "24634", "24635", "24639", "24640", "24643", "24644", "24646", "24647", "24648", "24649", "24650", "24651", "24653", "24654", "24655", "24656", "24658", "24660", "24669", "24670", "24671", "24672", "24673", "24675", "24682", "24685", "24687", "24688", "24689", "24690", "24692", "24695", "24698", "24706", "24707", "24708", "24709", "24710", "24711", "24712", "24713", "24715", "24716", "24719", "24720", "24721", "24722", "24725", "24726", "24727", "24729", "24731", "24736", "24737", "24738", "24741", "24742", "24743", "24745", "24748", "24749", "24750", "24751", "24753", "24755", "24756", "24760", "24761", "24765", "24767", "24768", "24769", "24770", "24771", "24773", "24775", "24776", "24777", "24781", "24782", "24788", "24789", "24791", "24792", "24793", "24795", "24796", "24797", "24798", "24801", "24803", "24806", "24807", "24808", "24811", "24815", "24816", "24818", "24820", "24821", "24822", "24823", "24826", "24829", "24831", "24836", "24837", "24840", "24841", "24843", "24844", "24845", "24846", "24848", "24850", "24851", "24853", "24854", "24856", "24857", "24858", "24860", "24863", "24869", "24870", "24871", "24872", "24873", "24874", "24875", "24877", "24879", "24883", "24885", "24886", "24891", "24892", "24894", "24895", "24896", "24900", "24901", "24903", "24904", "24909", "24911", "24915", "24916", "24917", "24919", "24926", "24928", "24932", "24933", "24937", "24938", "24941", "24943", "24944", "24945", "24946", "24950", "24951", "24953", "24954", "24957", "24958", "24961", "24963", "24965", "24967", "24972", "24974", "24975", "24976", "24977", "24978", "24979", "24981", "24982", "24985", "24986", "24990", "24991", "24992", "24993", "24994", "24995", "24997", "25001", "25002", "25005", "25006", "25007", "25008", "25009", "25013", "25016", "25019", "25021", "25025", "25027", "25028", "25030", "25033", "25034", "25035", "25037", "25038", "25044", "25045", "25047", "25048", "25049", "25054", "25058", "25059", "25060", "25063", "25064", "25066", "25067", "25068", "25069", "25070", "25071", "25072", "25074", "25075", "25078", "25083", "25084", "25086", "25091", "25094", "25097", "25099", "25101", "25102", "25104", "25106", "25108", "25112", "25113", "25117", "25118", "25119", "25122", "25123", "25124", "25125", "25129", "25131", "25132", "25133", "25136", "25139", "25142", "25146", "25151", "25152", "25153", "25155", "25156", "25157", "25159", "25160", "25162", "25164", "25165", "25168", "25172", "25173", "25176", "25177", "25179", "25181", "25183", "25185", "25186", "25190", "25191", "25192", "25193", "25197", "25200", "25202", "25203", "25204", "25206", "25207", "25208", "25209", "25210", "25211", "25212", "25214", "25215", "25218", "25219", "25220", "25221", "25223", "25224", "25225", "25232", "25236", "25239", "25240", "25243", "25244", "25246", "25248", "25249", "25250", "25253", "25259", "25260", "25262", "25264", "25266", "25269", "25270", "25271", "25272", "25273", "25278", "25279", "25284", "25285", "25288", "25289", "25292", "25293", "25294", "25296", "25299", "25301", "25302", "25306", "25308", "25311", "25313", "25314", "25315", "25316", "25321", "25323", "25324", "25326", "25328", "25329", "25330", "25331", "25333", "25334", "25336", "25337", "25338", "25339", "25340", "25341", "25343", "25344", "25345", "25346", "25348", "25349", "25352", "25355", "25356", "25357", "25360", "25361", "25362", "25365", "25366", "25368", "25369", "25370", "25373", "25376", "25380", "25381", "25384", "25387", "25391", "25392", "25399", "25401", "25402", "25404", "25405", "25407", "25410", "25411", "25412", "25415", "25416", "25419", "25421", "25422", "25425", "25427", "25428", "25430", "25431", "25432", "25435", "25436", "25439", "25440", "25443", "25447", "25448", "25449", "25450", "25451", "25452", "25454", "25456", "25459", "25460", "25461", "25462", "25463", "25464", "25469", "25472", "25473", "25475", "25476", "25477", "25478", "25479", "25480", "25481", "25482", "25484", "25485", "25488", "25491", "25492", "25493", "25494", "25495", "25498", "25500", "25502", "25504", "25506", "25507", "25508", "25509", "25511", "25514", "25515", "25520", "25526", "25527", "25528", "25531", "25532", "25533", "25534", "25536", "25537", "25538", "25539", "25540", "25541", "25542", "25545", "25549", "25550", "25551", "25553", "25554", "25556", "25562", "25564", "25565", "25568", "25571", "25572", "25576", "25577", "25578", "25579", "25584", "25586", "25587", "25588", "25590", "25591", "25593", "25595", "25598", "25600", "25601", "25603", "25606", "25609", "25610", "25611", "25612", "25613", "25619", "25621", "25623", "25629", "25630", "25631", "25633", "25634", "25636", "25637", "25639", "25641", "25642", "25643", "25644", "25646", "25648", "25649", "25651", "25652", "25654", "25655", "25658", "25661", "25662", "25664", "25665", "25668", "25671", "25672", "25673", "25674", "25675", "25676", "25679", "25682", "25683", "25685", "25686", "25687", "25689", "25691", "25693", "25694", "25695", "25696", "25697", "25698", "25700", "25701", "25702", "25706", "25707", "25708", "25710", "25712", "25713", "25714", "25716", "25720", "25722", "25723", "25728", "25729", "25732", "25734", "25735", "25738", "25741", "25742", "25744", "25745", "25746", "25747", "25748", "25752", "25758", "25759", "25761", "25764", "25765", "25768", "25771", "25772", "25773", "25774", "25783", "25787", "25788", "25789", "25790", "25791", "25792", "25793", "25794", "25795", "25797", "25798", "25799", "25801", "25802", "25803", "25805", "25807", "25808", "25810", "25814", "25818", "25820", "25821", "25822", "25823", "25824", "25825", "25827", "25831", "25833", "25835", "25838", "25840", "25841", "25842", "25847", "25849", "25853", "25856", "25857", "25858", "25859", "25860", "25861", "25862", "25863", "25870", "25872", "25874", "25875", "25879", "25883", "25885", "25887", "25888", "25889", "25890", "25896", "25898", "25901", "25904", "25905", "25907", "25911", "25912", "25913", "25914", "25915", "25917", "25918", "25923", "25924", "25925", "25926", "25928", "25930", "25931", "25933", "25934", "25936", "25937", "25941", "25942", "25943", "25945", "25947", "25949", "25950", "25952", "25954", "25960", "25962", "25968", "25972", "25973", "25975", "25976", "25979", "25980", "25982", "25983", "25987", "25988", "25989", "25990", "25993", "25994", "25995", "25999", "26000", "26001", "26003", "26004", "26005", "26011", "26013", "26014", "26016", "26019", "26022", "26023", "26024", "26025", "26039", "26040", "26041", "26043", "26044", "26045", "26046", "26049", "26050", "26052", "26053", "26054", "26055", "26056", "26063", "26066", "26067", "26068", "26070", "26071", "26074", "26078", "26079", "26080", "26081", "26082", "26084", "26086", "26087", "26088", "26090", "26092", "26093", "26094", "26095", "26097", "26098", "26100", "26103", "26104", "26105", "26111", "26113", "26114", "26115", "26116", "26117", "26119", "26120", "26121", "26122", "26125", "26126", "26128", "26129", "26131", "26132", "26133", "26136", "26137", "26138", "26139", "26142", "26144", "26145", "26146", "26149", "26152", "26158", "26161", "26164", "26165", "26167", "26169", "26170", "26172", "26176", "26178", "26180", "26182", "26183", "26188", "26189", "26190", "26193", "26194", "26197", "26200", "26202", "26206", "26208", "26209", "26210", "26212", "26216", "26217", "26218", "26219", "26220", "26222", "26223", "26229", "26232", "26235", "26237", "26238", "26239", "26240", "26242", "26243", "26245", "26247", "26248", "26249", "26250", "26253", "26254", "26258", "26260", "26263", "26264", "26265", "26269", "26270", "26272", "26273", "26275", "26277", "26278", "26290", "26291", "26292", "26293", "26294", "26295", "26299", "26305", "26307", "26308", "26309", "26310", "26314", "26316", "26319", "26320", "26322", "26323", "26324", "26325", "26326", "26327", "26328", "26329", "26330", "26333", "26337", "26338", "26339", "26340", "26343", "26344", "26345", "26349", "26351", "26353", "26356", "26359", "26362", "26363", "26365", "26366", "26369", "26370", "26371", "26372", "26375", "26379", "26383", "26384", "26385", "26386", "26388", "26389", "26391", "26394", "26396", "26397", "26398", "26402", "26403", "26410", "26411", "26415", "26416", "26417", "26423", "26425", "26426", "26427", "26429", "26431", "26433", "26434", "26436", "26437", "26440", "26441", "26446", "26448", "26449", "26450", "26452", "26453", "26455", "26456", "26457", "26458", "26459", "26463", "26466", "26467", "26468", "26469", "26471", "26472", "26473", "26477", "26482", "26484", "26487", "26489", "26490", "26492", "26495", "26498", "26499", "26501", "26507", "26508", "26510", "26514", "26519", "26522", "26523", "26524", "26526", "26528", "26531", "26532", "26533", "26535", "26536", "26539", "26540", "26541", "26547", "26549", "26551", "26552", "26560", "26561", "26562", "26565", "26572", "26574", "26575", "26577", "26579", "26582", "26584", "26586", "26589", "26592", "26597", "26599", "26600", "26602", "26604", "26606", "26608", "26611", "26615", "26616", "26617", "26620", "26621", "26625", "26626", "26628", "26629", "26630", "26631", "26632", "26634", "26635", "26637", "26638", "26639", "26642", "26643", "26644", "26645", "26647", "26649", "26654", "26656", "26658", "26659", "26661", "26662", "26663", "26667", "26668", "26669", "26671", "26675", "26677", "26685", "26688", "26689", "26690", "26692", "26694", "26695", "26697", "26698", "26699", "26702", "26703", "26705", "26706", "26707", "26708", "26709", "26710", "26711", "26713", "26715", "26719", "26728", "26729", "26730", "26734", "26735", "26738", "26741", "26743", "26744", "26747", "26749", "26751", "26752", "26754", "26761", "26765", "26766", "26771", "26773", "26775", "26779", "26781", "26783", "26786", "26787", "26790", "26791", "26792", "26796", "26797", "26798", "26799", "26802", "26804", "26809", "26812", "26813", "26816", "26817", "26820", "26821", "26826", "26827", "26830", "26832", "26833", "26834", "26835", "26836", "26840", "26841", "26845", "26847", "26848", "26851", "26855", "26856", "26858", "26859", "26860", "26862", "26869", "26871", "26872", "26874", "26876", "26879", "26881", "26882", "26883", "26885", "26886", "26887", "26889", "26890", "26893", "26894", "26898", "26900", "26902", "26903", "26904", "26905", "26911", "26913", "26914", "26915", "26916", "26921", "26922", "26924", "26925", "26926", "26928", "26931", "26932", "26933", "26935", "26936", "26938", "26940", "26942", "26943", "26946", "26948", "26949", "26951", "26953", "26954", "26955", "26957", "26962", "26964", "26965", "26967", "26968", "26972", "26973", "26974", "26977", "26979", "26980", "26982", "26983", "26984", "26986", "26987", "26993", "27000", "27003", "27008", "27009", "27010", "27011", "27013", "27014", "27015", "27017", "27018", "27020", "27021", "27024", "27025", "27026", "27027", "27029", "27034", "27038", "27039", "27040", "27042", "27045", "27046", "27050", "27055", "27056", "27057", "27061", "27062", "27064", "27065", "27067", "27068", "27070", "27071", "27072", "27074", "27077", "27079", "27083", "27084", "27086", "27087", "27088", "27090", "27092", "27096", "27097", "27099", "27102", "27103", "27104", "27105", "27109", "27110", "27112", "27113", "27115", "27117", "27118", "27119", "27127", "27129", "27130", "27131", "27132", "27135", "27143", "27144", "27145", "27147", "27152", "27156", "27158", "27159", "27160", "27161", "27162", "27165", "27166", "27167", "27168", "27173", "27175", "27178", "27179", "27180", "27181", "27183", "27189", "27191", "27193", "27194", "27196", "27197", "27199", "27201", "27202", "27203", "27205", "27206", "27207", "27208", "27212", "27214", "27216", "27222", "27223", "27224", "27225", "27226", "27229", "27231", "27232", "27234", "27236", "27238", "27239", "27241", "27243", "27245", "27246", "27247", "27249", "27250", "27251", "27254", "27255", "27257", "27261", "27264", "27267", "27268", "27269", "27270", "27271", "27273", "27274", "27276", "27278", "27281", "27283", "27284", "27285", "27289", "27290", "27292", "27293", "27294", "27295", "27296", "27297", "27299", "27301", "27305", "27309", "27312", "27313", "27314", "27315", "27316", "27317", "27318", "27319", "27322", "27323", "27324", "27327", "27329", "27330", "27331", "27332", "27333", "27335", "27337", "27338", "27339", "27340", "27341", "27342", "27343", "27344", "27345", "27347", "27349", "27351", "27354", "27355", "27356", "27357", "27359", "27362", "27364", "27365", "27367", "27368", "27369", "27370", "27372", "27374", "27376", "27378", "27380", "27381", "27382", "27383", "27385", "27386", "27387", "27393", "27394", "27396", "27397", "27399", "27400", "27401", "27406", "27407", "27408", "27409", "27410", "27412", "27414", "27416", "27417", "27418", "27419", "27421", "27423", "27424", "27425", "27426", "27427", "27428", "27429", "27432", "27434", "27436", "27438", "27439", "27440", "27443", "27445", "27446", "27447", "27448", "27449", "27451", "27452", "27453", "27455", "27457", "27458", "27459", "27460", "27461", "27462", "27464", "27465", "27466", "27468", "27469", "27470", "27471", "27472", "27473", "27476", "27481", "27482", "27486", "27487", "27496", "27498", "27500", "27501", "27503", "27505", "27506", "27508", "27509", "27510", "27511", "27512", "27513", "27518", "27519", "27520", "27522", "27524", "27526", "27530", "27532", "27534", "27538", "27541", "27544", "27545", "27546", "27548", "27550", "27551", "27552", "27553", "27554", "27555", "27559", "27560", "27561", "27563", "27564", "27565", "27566", "27567", "27568", "27571", "27572", "27575", "27577", "27578", "27579", "27581", "27583", "27585", "27586", "27587", "27594", "27595", "27596", "27597", "27599", "27600", "27602", "27604", "27605", "27607", "27609", "27611", "27614", "27615", "27616", "27617", "27619", "27621", "27622", "27623", "27627", "27628", "27631", "27635", "27638", "27639", "27640", "27641", "27642", "27644", "27645", "27648", "27649", "27650", "27651", "27653", "27654", "27656", "27658", "27660", "27662", "27663", "27664", "27666", "27670", "27672", "27674", "27677", "27678", "27679", "27682", "27685", "27688", "27689", "27694", "27696", "27697", "27698", "27700", "27702", "27703", "27704", "27706", "27712", "27714", "27715", "27718", "27719", "27720", "27721", "27722", "27723", "27726", "27727", "27734", "27735", "27736", "27737", "27738", "27740", "27741", "27742", "27744", "27748", "27749", "27750", "27752", "27754", "27756", "27757", "27758", "27762", "27768", "27775", "27776", "27780", "27781", "27782", "27785", "27786", "27787", "27789", "27790", "27797", "27801", "27802", "27803", "27806", "27807", "27808", "27809", "27813", "27816", "27817", "27818", "27820", "27822", "27826", "27828", "27829", "27830", "27832", "27835", "27837", "27838", "27839", "27843", "27846", "27847", "27851", "27852", "27854", "27857", "27863", "27864", "27865", "27866", "27867", "27868", "27869", "27872", "27873", "27876", "27878", "27879", "27882", "27883", "27887", "27888", "27891", "27892", "27893", "27895", "27897", "27898", "27899", "27903", "27905", "27906", "27908", "27909", "27911", "27913", "27914", "27915", "27916", "27917", "27922", "27923", "27924", "27925", "27927", "27929", "27930", "27932", "27933", "27934", "27935", "27936", "27938", "27942", "27943", "27944", "27945", "27952", "27953", "27954", "27955", "27956", "27957", "27964", "27965", "27973", "27975", "27976", "27977", "27979", "27980", "27982", "27988", "27993", "27994", "27995", "27996", "27998", "27999", "28000", "28001", "28003", "28004", "28005", "28006", "28007", "28008", "28009", "28010", "28011", "28013", "28015", "28017", "28019", "28021", "28022", "28023", "28029", "28030", "28035", "28036", "28038", "28040", "28044", "28046", "28047", "28048", "28049", "28050", "28052", "28053", "28055", "28057", "28058", "28061", "28063", "28065", "28066", "28067", "28068", "28069", "28072", "28073", "28076", "28078", "28079", "28083", "28086", "28088", "28090", "28091", "28094", "28095", "28099", "28103", "28104", "28105", "28106", "28107", "28108", "28110", "28111", "28112", "28113", "28119", "28120", "28121", "28125", "28126", "28128", "28129", "28130", "28131", "28132", "28133", "28134", "28136", "28137", "28142", "28143", "28144", "28145", "28147", "28149", "28150", "28154", "28156", "28159", "28160", "28168", "28169", "28171", "28173", "28174", "28175", "28176", "28178", "28180", "28181", "28183", "28184", "28186", "28187", "28192", "28193", "28195", "28197", "28198", "28199", "28201", "28204", "28205", "28208", "28212", "28213", "28214", "28218", "28219", "28222", "28226", "28227", "28229", "28231", "28232", "28234", "28235", "28238", "28239", "28240", "28241", "28243", "28244", "28245", "28246", "28248", "28250", "28252", "28253", "28254", "28255", "28258", "28259", "28260", "28261", "28262", "28263", "28264", "28266", "28268", "28270", "28272", "28273", "28274", "28276", "28278", "28279", "28280", "28281", "28282", "28283", "28284", "28285", "28287", "28288", "28289", "28290", "28291", "28294", "28296", "28297", "28299", "28300", "28302", "28303", "28304", "28305", "28307", "28308", "28309", "28316", "28317", "28318", "28319", "28320", "28323", "28324", "28326", "28327", "28336", "28337", "28339", "28343", "28345", "28348", "28351", "28357", "28359", "28360", "28362", "28364", "28365", "28368", "28369", "28373", "28374", "28376", "28379", "28382", "28383", "28385", "28387", "28392", "28393", "28395", "28396", "28399", "28400", "28402", "28403", "28407", "28408", "28411", "28412", "28413", "28415", "28416", "28417", "28418", "28421", "28425", "28431", "28432", "28433", "28434", "28436", "28437", "28438", "28439", "28440", "28443", "28445", "28446", "28447", "28448", "28458", "28459", "28461", "28462", "28464", "28469", "28470", "28473", "28474", "28479", "28484", "28485", "28486", "28491", "28492", "28493", "28496", "28498", "28499", "28502", "28504", "28505", "28506", "28507", "28510", "28513", "28517", "28519", "28520", "28521", "28523", "28524", "28526", "28527", "28528", "28529", "28531", "28533", "28535", "28537", "28539", "28540", "28545", "28547", "28552", "28553", "28554", "28556", "28558", "28560", "28562", "28564", "28566", "28568", "28571", "28572", "28576", "28577", "28580", "28581", "28583", "28584", "28589", "28592", "28593", "28598", "28600", "28601", "28602", "28604", "28605", "28606", "28607", "28608", "28609", "28617", "28619", "28621", "28625", "28627", "28628", "28629", "28630", "28631", "28636", "28637", "28640", "28642", "28646", "28647", "28649", "28650", "28652", "28653", "28654", "28655", "28656", "28658", "28660", "28664", "28665", "28668", "28670", "28672", "28673", "28675", "28676", "28678", "28679", "28682", "28684", "28686", "28687", "28690", "28691", "28693", "28695", "28696", "28697", "28698", "28699", "28700", "28707", "28708", "28712", "28713", "28714", "28715", "28718", "28719", "28720", "28722", "28723", "28725", "28730", "28734", "28736", "28739", "28745", "28746", "28747", "28748", "28751", "28753", "28756", "28759", "28763", "28766", "28767", "28769", "28775", "28776", "28777", "28782", "28783", "28785", "28786", "28789", "28791", "28793", "28794", "28795", "28796", "28798", "28799", "28800", "28802", "28806", "28808", "28810", "28811", "28813", "28814", "28816", "28817", "28818", "28820", "28822", "28825", "28830", "28831", "28832", "28835", "28836", "28837", "28838", "28841", "28843", "28847", "28850", "28851", "28853", "28854", "28857", "28859", "28861", "28862", "28864", "28866", "28867", "28868", "28870", "28872", "28873", "28876", "28877", "28879", "28882", "28883", "28885", "28886", "28888", "28889", "28891", "28893", "28894", "28895", "28897", "28898", "28902", "28903", "28904", "28906", "28909", "28910", "28911", "28912", "28914", "28916", "28917", "28918", "28919", "28920", "28922", "28923", "28926", "28929", "28932", "28933", "28934", "28935", "28936", "28938", "28939", "28940", "28941", "28942", "28943", "28946", "28948", "28949", "28950", "28951", "28956", "28957", "28960", "28962", "28966", "28968", "28971", "28975", "28976", "28977", "28979", "28980", "28986", "28987", "28988", "28989", "28990", "28996", "28998", "28999", "29000", "29002", "29007", "29009", "29010", "29013", "29014", "29015", "29016", "29018", "29019", "29020", "29024", "29026", "29029", "29030", "29031", "29034", "29036", "29037", "29038", "29045", "29048", "29050", "29052", "29053", "29056", "29057", "29058", "29059", "29060", "29061", "29062", "29066", "29067", "29068", "29069", "29070", "29071", "29075", "29077", "29078", "29080", "29082", "29084", "29086", "29088", "29090", "29094", "29095", "29097", "29098", "29099", "29103", "29105", "29106", "29107", "29108", "29109", "29113", "29114", "29118", "29119", "29121", "29124", "29130", "29131", "29132", "29134", "29136", "29138", "29139", "29140", "29146", "29148", "29149", "29150", "29152", "29155", "29158", "29162", "29163", "29164", "29166", "29167", "29168", "29173", "29175", "29176", "29177", "29179", "29181", "29182", "29183", "29184", "29189", "29190", "29192", "29198", "29199", "29201", "29203", "29207", "29208", "29210", "29211", "29212", "29213", "29214", "29219", "29220", "29222", "29224", "29227", "29229", "29230", "29231", "29232", "29234", "29236", "29237", "29239", "29240", "29241", "29242", "29243", "29244", "29245", "29246", "29248", "29250", "29252", "29253", "29254", "29256", "29257", "29259", "29264", "29266", "29267", "29268", "29270", "29271", "29274", "29275", "29278", "29279", "29280", "29283", "29285", "29288", "29289", "29290", "29294", "29295", "29297", "29298", "29299", "29302", "29303", "29305", "29307", "29308", "29310", "29312", "29315", "29316", "29317", "29319", "29322", "29323", "29325", "29326", "29330", "29331", "29336", "29337", "29338", "29339", "29340", "29341", "29342", "29345", "29348", "29349", "29353", "29354", "29357", "29359", "29361", "29362", "29365", "29367", "29370", "29376", "29378", "29380", "29381", "29383", "29384", "29385", "29389", "29391", "29392", "29393", "29395", "29396", "29397", "29398", "29403", "29404", "29407", "29408", "29409", "29411", "29412", "29414", "29417", "29422", "29426", "29429", "29430", "29431", "29433", "29434", "29437", "29438", "29441", "29443", "29444", "29446", "29447", "29452", "29455", "29457", "29458", "29460", "29461", "29462", "29463", "29464", "29465", "29466", "29469", "29471", "29474", "29475", "29478", "29484", "29486", "29489", "29494", "29495", "29498", "29500", "29501", "29502", "29505", "29506", "29515", "29516", "29523", "29526", "29529", "29530", "29531", "29535", "29536", "29537", "29538", "29539", "29540", "29543", "29544", "29549", "29551", "29552", "29554", "29555", "29558", "29559", "29560", "29563", "29565", "29566", "29567", "29568", "29569", "29571", "29574", "29575", "29581", "29586", "29587", "29588", "29589", "29590", "29592", "29593", "29594", "29596", "29597", "29599", "29603", "29604", "29605", "29606", "29608", "29611", "29612", "29613", "29614", "29615", "29619", "29620", "29622", "29625", "29626", "29627", "29628", "29629", "29630", "29632", "29636", "29638", "29640", "29641", "29642", "29643", "29644", "29645", "29646", "29647", "29651", "29652", "29653", "29654", "29655", "29658", "29659", "29660", "29662", "29664", "29666", "29667", "29668", "29670", "29671", "29672", "29673", "29675", "29676", "29677", "29679", "29681", "29683", "29685", "29686", "29687", "29689", "29690", "29692", "29695", "29696", "29697", "29699", "29700", "29703", "29704", "29705", "29708", "29711", "29716", "29717", "29719", "29720", "29724", "29725", "29729", "29732", "29734", "29735", "29739", "29740", "29743", "29744", "29747", "29749", "29753", "29755", "29759", "29762", "29764", "29767", "29772", "29773", "29774", "29776", "29777", "29779", "29782", "29783", "29787", "29789", "29790", "29791", "29793", "29794", "29795", "29798", "29799", "29800", "29801", "29803", "29804", "29805", "29809", "29810", "29811", "29812", "29813", "29815", "29816", "29817", "29819", "29822", "29823", "29824", "29828", "29830", "29831", "29832", "29834", "29837", "29838", "29841", "29842", "29843", "29844", "29845", "29846", "29847", "29848", "29849", "29851", "29852", "29854", "29858", "29859", "29867", "29869", "29870", "29871", "29874", "29877", "29878", "29881", "29882", "29884", "29887", "29888", "29891", "29893", "29894", "29895", "29896", "29897", "29898", "29899", "29900", "29902", "29903", "29904", "29905", "29907", "29908", "29911", "29914", "29916", "29919", "29920", "29921", "29924", "29925", "29926", "29928", "29931", "29932", "29933", "29934", "29936", "29940", "29941", "29942", "29944", "29953", "29957", "29958", "29959", "29960", "29962", "29965", "29966", "29967", "29968", "29969", "29971", "29973", "29976", "29977", "29978", "29979", "29984", "29987", "29990", "29991", "29992", "29993", "29994", "29997", "29998", "30000", "30001", "30003", "30005", "30006", "30011", "30012", "30013", "30014", "30016", "30017", "30018", "30019", "30020", "30021", "30024", "30026", "30027", "30029", "30030", "30031", "30033", "30034", "30035", "30039", "30040", "30042", "30044", "30045", "30048", "30050", "30051", "30052", "30053", "30054", "30055", "30058", "30061", "30062", "30064", "30065", "30067", "30068", "30072", "30074", "30075", "30077", "30078", "30079", "30081", "30084", "30085", "30086", "30088", "30090", "30091", "30095", "30096", "30099", "30100", "30101", "30102", "30107", "30111", "30112", "30114", "30115", "30116", "30117", "30120", "30121", "30124", "30135", "30136", "30138", "30143", "30145", "30146", "30147", "30149", "30150", "30151", "30152", "30153", "30155", "30159", "30160", "30161", "30162", "30163", "30164", "30165", "30166", "30167", "30168", "30171", "30172", "30179", "30180", "30181", "30182", "30185", "30186", "30198", "30199", "30202", "30203", "30209", "30211", "30214", "30216", "30217", "30220", "30227", "30230", "30232", "30235", "30236", "30237", "30242", "30244", "30245", "30251", "30252", "30254", "30256", "30257", "30258", "30260", "30261", "30262", "30263", "30271", "30274", "30275", "30278", "30279", "30280", "30281", "30284", "30285", "30286", "30289", "30290", "30294", "30295", "30296", "30297", "30298", "30300", "30303", "30304", "30306", "30309", "30310", "30314", "30315", "30316", "30317", "30318", "30321", "30326", "30327", "30328", "30331", "30332", "30335", "30336", "30337", "30339", "30340", "30342", "30343", "30346", "30347", "30348", "30349", "30352", "30353", "30356", "30364", "30365", "30366", "30367", "30370", "30372", "30374", "30375", "30376", "30377", "30378", "30379", "30380", "30381", "30382", "30383", "30385", "30388", "30389", "30392", "30396", "30397", "30399", "30401", "30403", "30404", "30405", "30406", "30408", "30410", "30411", "30412", "30413", "30414", "30417", "30418", "30422", "30423", "30424", "30425", "30430", "30434", "30436", "30438", "30439", "30441", "30444", "30447", "30449", "30452", "30456", "30457", "30464", "30466", "30468", "30472", "30473", "30478", "30479", "30481", "30482", "30484", "30486", "30487", "30488", "30489", "30490", "30491", "30492", "30495", "30496", "30499", "30501", "30502", "30504", "30505", "30506", "30507", "30508", "30510", "30511", "30514", "30515", "30518", "30519", "30521", "30523", "30524", "30526", "30530", "30532", "30533", "30534", "30537", "30538", "30545", "30546", "30547", "30548", "30550", "30551", "30552", "30553", "30554", "30555", "30556", "30557", "30558", "30559", "30561", "30562", "30564", "30565", "30568", "30570", "30572", "30573", "30574", "30577", "30581", "30582", "30584", "30585", "30586", "30587", "30589", "30590", "30591", "30596", "30598", "30603", "30605", "30606", "30607", "30608", "30610", "30612", "30613", "30615", "30617", "30621", "30622", "30623", "30628", "30629", "30630", "30634", "30637", "30638", "30640", "30644", "30645", "30647", "30650", "30651", "30654", "30655", "30656", "30658", "30662", "30664", "30666", "30668", "30669", "30671", "30674", "30677", "30678", "30679", "30680", "30684", "30687", "30689", "30690", "30691", "30692", "30693", "30697", "30699", "30701", "30702", "30703", "30704", "30705", "30706", "30707", "30714", "30715", "30717", "30718", "30720", "30729", "30730", "30733", "30734", "30735", "30736", "30737", "30738", "30739", "30740", "30741", "30742", "30745", "30746", "30747", "30750", "30751", "30756", "30757", "30758", "30760", "30763", "30764", "30769", "30771", "30775", "30776", "30779", "30781", "30783", "30785", "30786", "30789", "30794", "30795", "30796", "30799", "30801", "30804", "30806", "30808", "30809", "30810", "30814", "30815", "30816", "30817", "30820", "30821", "30822", "30823", "30827", "30828", "30830", "30832", "30834", "30835", "30838", "30840", "30842", "30845", "30846", "30851", "30854", "30855", "30856", "30860", "30862", "30863", "30864", "30865", "30866", "30867", "30868", "30870", "30873", "30874", "30875", "30877", "30879", "30880", "30882", "30883", "30885", "30888", "30889", "30890", "30891", "30893", "30894", "30897", "30898", "30899", "30900", "30902", "30903", "30905", "30910", "30912", "30913", "30914", "30917", "30921", "30925", "30926", "30928", "30930", "30932", "30936", "30938", "30939", "30940", "30942", "30943", "30944", "30945", "30947", "30949", "30951", "30952", "30955", "30957", "30958", "30960", "30963", "30964", "30967", "30968", "30969", "30970", "30972", "30974", "30975", "30976", "30978", "30980", "30981", "30983", "30985", "30988", "30989", "30990", "30992", "30993", "30994", "30995", "30996", "30998", "30999", "31001", "31002", "31005", "31006", "31007", "31009", "31014", "31022", "31024", "31026", "31027", "31029", "31032", "31034", "31036", "31037", "31040", "31042", "31043", "31047", "31048", "31053", "31056", "31059", "31061", "31062", "31063", "31064", "31065", "31066", "31067", "31068", "31075", "31078", "31080", "31082", "31083", "31085", "31086", "31089", "31090", "31092", "31094", "31096", "31097", "31099", "31103", "31106", "31107", "31113", "31116", "31117", "31123", "31125", "31126", "31132", "31133", "31136", "31137", "31138", "31141", "31142", "31145", "31148", "31156", "31157", "31159", "31160", "31161", "31162", "31163", "31164", "31167", "31168", "31169", "31172", "31174", "31175", "31178", "31179", "31182", "31183", "31184", "31185", "31186", "31187", "31188", "31190", "31196", "31201", "31202", "31204", "31205", "31206", "31207", "31208", "31209", "31212", "31213", "31214", "31216", "31218", "31219", "31224", "31226", "31227", "31230", "31232", "31233", "31234", "31235", "31236", "31238", "31239", "31241", "31243", "31249", "31250", "31257", "31258", "31259", "31261", "31264", "31267", "31269", "31272", "31276", "31278", "31284", "31285", "31286", "31287", "31289", "31290", "31293", "31295", "31296", "31298", "31300", "31303", "31304", "31305", "31306", "31308", "31310", "31314", "31317", "31318", "31320", "31322", "31325", "31329", "31332", "31333", "31336", "31338", "31341", "31342", "31343", "31344", "31346", "31347", "31350", "31352", "31358", "31360", "31362", "31366", "31367", "31368", "31373", "31380", "31381", "31382", "31384", "31387", "31388", "31389", "31390", "31394", "31397", "31398", "31402", "31404", "31406", "31409", "31414", "31416", "31418", "31420", "31421", "31424", "31426", "31427", "31431", "31433", "31434", "31437", "31441", "31443", "31444", "31445", "31446", "31447", "31448", "31449", "31451", "31453", "31454", "31456", "31458", "31459", "31460", "31462", "31466", "31469", "31471", "31473", "31474", "31477", "31478", "31480", "31482", "31484", "31485", "31487", "31488", "31489", "31490", "31493", "31494", "31495", "31497", "31499", "31502", "31505", "31508", "31511", "31512", "31514", "31515", "31516", "31518", "31520", "31522", "31523", "31525", "31527", "31528", "31530", "31531", "31532", "31534", "31535", "31536", "31537", "31541", "31542", "31543", "31545", "31547", "31549", "31550", "31551", "31555", "31556", "31557", "31558", "31559", "31561", "31562", "31564", "31565", "31570", "31571", "31572", "31574", "31580", "31591", "31593", "31595", "31598", "31600", "31601", "31603", "31605", "31606", "31608", "31610", "31613", "31614", "31621", "31627", "31628", "31629", "31630", "31634", "31635", "31636", "31637", "31638", "31639", "31640", "31641", "31642", "31644", "31646", "31647", "31648", "31649", "31653", "31655", "31658", "31659", "31661", "31662", "31663", "31664", "31668", "31675", "31677", "31678", "31681", "31683", "31684", "31686", "31687", "31690", "31691", "31693", "31694", "31696", "31698", "31702", "31703", "31707", "31709", "31710", "31712", "31715", "31717", "31718", "31719", "31722", "31726", "31730", "31732", "31735", "31737", "31738", "31740", "31741", "31742", "31743", "31745", "31753", "31754", "31755", "31757", "31758", "31760", "31766", "31767", "31768", "31769", "31772", "31774", "31775", "31776", "31778", "31784", "31785", "31787", "31788", "31789", "31793", "31796", "31797", "31798", "31799", "31802", "31803", "31804", "31806", "31807", "31808", "31809", "31811", "31813", "31815", "31816", "31818", "31819", "31821", "31824", "31826", "31828", "31830", "31831", "31837", "31838", "31840", "31842", "31843", "31846", "31847", "31851", "31858", "31859", "31861", "31862", "31865", "31866", "31869", "31870", "31879", "31881", "31884", "31889", "31890", "31891", "31892", "31893", "31896", "31897", "31904", "31908", "31912", "31913", "31916", "31920", "31922", "31929", "31930", "31931", "31932", "31935", "31938", "31939", "31940", "31942", "31943", "31946", "31947", "31948", "31949", "31951", "31954", "31955", "31957", "31958", "31959", "31960", "31961", "31964", "31967", "31968", "31969", "31971", "31973", "31978", "31980", "31982", "31983", "31985", "31986", "31989", "31990", "31991", "31995", "31996", "31999", "32001", "32002", "32003", "32004", "32005", "32009", "32010", "32011", "32013", "32018", "32019", "32021", "32026", "32028", "32029", "32030", "32031", "32035", "32038", "32041", "32043", "32045", "32046", "32047", "32048", "32049", "32050", "32051", "32052", "32053", "32058", "32062", "32064", "32067", "32068", "32070", "32072", "32074", "32078", "32079", "32080", "32081", "32082", "32083", "32085", "32087", "32090", "32092", "32096", "32099", "32101", "32103", "32107", "32112", "32117", "32119", "32120", "32123", "32127", "32128", "32129", "32130", "32132", "32136", "32137", "32139", "32140", "32141", "32142", "32145", "32148", "32149", "32152", "32153", "32154", "32155", "32156", "32157", "32159", "32162", "32163", "32166", "32168", "32169", "32170", "32172", "32173", "32176", "32179", "32180", "32183", "32184", "32186", "32187", "32190", "32191", "32194", "32195", "32197", "32198", "32204", "32207", "32210", "32211", "32213", "32214", "32215", "32217", "32219", "32220", "32221", "32224", "32226", "32227", "32228", "32230", "32231", "32239", "32240", "32243", "32246", "32247", "32249", "32251", "32252", "32253", "32255", "32256", "32257", "32258", "32261", "32262", "32264", "32270", "32271", "32272", "32273", "32275", "32280", "32282", "32284", "32287", "32289", "32290", "32294", "32295", "32296", "32298", "32300", "32305", "32307", "32313", "32319", "32320", "32321", "32324", "32327", "32329", "32331", "32332", "32334", "32336", "32337", "32339", "32341", "32346", "32347", "32351", "32353", "32358", "32360", "32364", "32367", "32369", "32372", "32373", "32374", "32375", "32376", "32379", "32381", "32385", "32390", "32391", "32392", "32393", "32396", "32397", "32399", "32401", "32404", "32405", "32406", "32410", "32412", "32416", "32417", "32419", "32420", "32424", "32428", "32431", "32432", "32434", "32435", "32437", "32438", "32440", "32441", "32442", "32443", "32446", "32450", "32456", "32459", "32461", "32464", "32466", "32467", "32471", "32476", "32478", "32481", "32482", "32483", "32484", "32485", "32487", "32488", "32489", "32492", "32493", "32495", "32496", "32498", "32499", "32500", "32504", "32506", "32513", "32514", "32520", "32523", "32524", "32525", "32526", "32528", "32529", "32531", "32532", "32536", "32538", "32539", "32541", "32542", "32550", "32551", "32552", "32553", "32555", "32559", "32561", "32566", "32567", "32569", "32570", "32571", "32572", "32573", "32575", "32576", "32578", "32580", "32581", "32584", "32587", "32588", "32589", "32590", "32594", "32597", "32598", "32600", "32601", "32603", "32605", "32609", "32614", "32616", "32617", "32618", "32619", "32620", "32628", "32632", "32633", "32634", "32636", "32639", "32641", "32643", "32647", "32648", "32649", "32650", "32652", "32653", "32655", "32656", "32657", "32658", "32660", "32661", "32665", "32666", "32670", "32672", "32674", "32675", "32676", "32678", "32679", "32681", "32683", "32685", "32686", "32687", "32688", "32689", "32690", "32691", "32694", "32695", "32696", "32699", "32704", "32706", "32710", "32711", "32714", "32715", "32717", "32718", "32721", "32722", "32725", "32727", "32728", "32730", "32731", "32733", "32734", "32736", "32738", "32740", "32745", "32749", "32750", "32752", "32753", "32754", "32756", "32758", "32759", "32761", "32762", "32763", "32764", "32772", "32777", "32780", "32781", "32782", "32783", "32787", "32790", "32791", "32792", "32793", "32798", "32800", "32804", "32805", "32806", "32807", "32809", "32810", "32813", "32815", "32816", "32817", "32818", "32819", "32822", "32825", "32828", "32829", "32830", "32831", "32833", "32834", "32836", "32837", "32840", "32841", "32848", "32849", "32850", "32852", "32853", "32854", "32856", "32859", "32862", "32865", "32866", "32867", "32868", "32871", "32872", "32873", "32874", "32875", "32876", "32881", "32882", "32883", "32885", "32886", "32887", "32888", "32889", "32893", "32895", "32897", "32900", "32901", "32902", "32903", "32904", "32908", "32909", "32911", "32915", "32920", "32921", "32923", "32927", "32929", "32932", "32933", "32936", "32937", "32939", "32947", "32951", "32956", "32960", "32961", "32962", "32964", "32965", "32966", "32967", "32968", "32971", "32973", "32974", "32984", "32987", "32988", "32989", "32992", "32993", "32994", "32996", "32997", "32998", "33001", "33005", "33008", "33009", "33011", "33018", "33019", "33020", "33023", "33024", "33028", "33030", "33032", "33033", "33034", "33037", "33038", "33039", "33042", "33044", "33046", "33049", "33052", "33053", "33054", "33055", "33058", "33059", "33060", "33062", "33065", "33066", "33067", "33068", "33071", "33072", "33073", "33074", "33075", "33076", "33078", "33081", "33083", "33084", "33086", "33088", "33089", "33091", "33092", "33093", "33096", "33104", "33106", "33107", "33109", "33110", "33113", "33114", "33115", "33117", "33118", "33119", "33120", "33121", "33122", "33123", "33125", "33126", "33129", "33134", "33135", "33137", "33138", "33139", "33142", "33143", "33146", "33148", "33151", "33153", "33154", "33156", "33158", "33159", "33160", "33162", "33164", "33165", "33167", "33168", "33169", "33171", "33172", "33174", "33175", "33177", "33181", "33182", "33183", "33184", "33185", "33186", "33187", "33189", "33190", "33194", "33198", "33199", "33201", "33203", "33204", "33206", "33207", "33208", "33210", "33211", "33212", "33218", "33219", "33220", "33222", "33223", "33224", "33225", "33227", "33228", "33229", "33230", "33231", "33233", "33236", "33237", "33238", "33239", "33240", "33241", "33243", "33244", "33246", "33247", "33249", "33250", "33253", "33255", "33256", "33259", "33261", "33262", "33264", "33267", "33268", "33269", "33272", "33274", "33276", "33278", "33279", "33280", "33283", "33285", "33286", "33287", "33288", "33289", "33290", "33292", "33294", "33297", "33298", "33300", "33301", "33302", "33303", "33304", "33309", "33310", "33314", "33316", "33317", "33318", "33319", "33322", "33323", "33324", "33325", "33328", "33329", "33332", "33333", "33335", "33338", "33339", "33341", "33342", "33344", "33346", "33348", "33349", "33350", "33351", "33356", "33357", "33358", "33359", "33360", "33363", "33364", "33365", "33366", "33368", "33370", "33371", "33372", "33373", "33375", "33376", "33377", "33378", "33381", "33384", "33386", "33387", "33391", "33393", "33397", "33400", "33402", "33405", "33407", "33410", "33412", "33413", "33416", "33417", "33420", "33421", "33422", "33424", "33425", "33426", "33427", "33429", "33430", "33431", "33434", "33435", "33437", "33440", "33441", "33443", "33446", "33448", "33451", "33453", "33455", "33457", "33458", "33460", "33462", "33463", "33467", "33468", "33469", "33474", "33475", "33476", "33478", "33479", "33480", "33482", "33484", "33485", "33486", "33489", "33493", "33495", "33497", "33498", "33499", "33501", "33503", "33504", "33505", "33508", "33509", "33510", "33511", "33512", "33513", "33515", "33517", "33521", "33522", "33528", "33529", "33530", "33531", "33536", "33537", "33540", "33542", "33543", "33544", "33549", "33550", "33551", "33552", "33553", "33554", "33555", "33556", "33558", "33559", "33560", "33561", "33562", "33564", "33566", "33567", "33573", "33574", "33575", "33576", "33578", "33580", "33582", "33583", "33584", "33589", "33590", "33591", "33592", "33594", "33595", "33598", "33599", "33602", "33606", "33607", "33612", "33619", "33620", "33624", "33625", "33626", "33629", "33633", "33637", "33640", "33643", "33647", "33650", "33651", "33652", "33654", "33660", "33663", "33664", "33665", "33666", "33668", "33672", "33673", "33676", "33678", "33679", "33680", "33681", "33682", "33683", "33685", "33686", "33688", "33690", "33691", "33692", "33695", "33698", "33701", "33703", "33704", "33708", "33709", "33710", "33712", "33713", "33715", "33719", "33720", "33723", "33724", "33725", "33726", "33727", "33730", "33732", "33733", "33739", "33742", "33743", "33744", "33746", "33747", "33750", "33751", "33752", "33753", "33754", "33756", "33757", "33764", "33765", "33768", "33772", "33773", "33777", "33778", "33779", "33782", "33783", "33784", "33788", "33792", "33794", "33795", "33796", "33798", "33799", "33800", "33801", "33804", "33812", "33815", "33816", "33824", "33825", "33826", "33827", "33828", "33829", "33832", "33833", "33834", "33836", "33839", "33840", "33842", "33844", "33845", "33848", "33851", "33854", "33856", "33857", "33858", "33861", "33866", "33867", "33868", "33871", "33873", "33874", "33876", "33880", "33881", "33882", "33886", "33887", "33888", "33897", "33898", "33899", "33900", "33902", "33906", "33909", "33910", "33912", "33913", "33914", "33915", "33917", "33918", "33920", "33922", "33924", "33925", "33927", "33928", "33929", "33930", "33931", "33932", "33936", "33938", "33939", "33941", "33942", "33946", "33947", "33948", "33954", "33955", "33956", "33957", "33958", "33959", "33960", "33967", "33971", "33972", "33974", "33977", "33978", "33980", "33983", "33984", "33985", "33987", "33988", "33990", "33993", "33994", "33999", "34001", "34003", "34004", "34010", "34012", "34013", "34017", "34023", "34026", "34027", "34029", "34032", "34033", "34036", "34037", "34041", "34042", "34044", "34045", "34047", "34049", "34050", "34051", "34052", "34053", "34054", "34057", "34058", "34063", "34065", "34066", "34070", "34072", "34074", "34075", "34076", "34078", "34079", "34080", "34081", "34083", "34085", "34086", "34089", "34090", "34091", "34092", "34095", "34097", "34101", "34102", "34103", "34104", "34105", "34106", "34107", "34108", "34109", "34110", "34111", "34113", "34114", "34116", "34119", "34120", "34121", "34123", "34125", "34126", "34127", "34130", "34131", "34132", "34133", "34135", "34141", "34143", "34147", "34150", "34151", "34152", "34155", "34157", "34158", "34160", "34161", "34162", "34165", "34166", "34170", "34172", "34173", "34180", "34182", "34183", "34184", "34187", "34194", "34197", "34198", "34199", "34202", "34203", "34205", "34207", "34208", "34209", "34210", "34211", "34213", "34215", "34219", "34221", "34222", "34223", "34225", "34228", "34232", "34233", "34235", "34236", "34237", "34239", "34240", "34242", "34244", "34246", "34247", "34248", "34251", "34252", "34254", "34261", "34262", "34264", "34265", "34266", "34267", "34268", "34271", "34273", "34274", "34275", "34276", "34277", "34279", "34282", "34284", "34286", "34287", "34290", "34291", "34293", "34296", "34297", "34299", "34300", "34302", "34303", "34304", "34308", "34310", "34311", "34312", "34313", "34314", "34316", "34317", "34321", "34322", "34323", "34324", "34326", "34327", "34329", "34330", "34331", "34332", "34333", "34335", "34337", "34339", "34341", "34343", "34345", "34346", "34347", "34348", "34349", "34351", "34353", "34356", "34360", "34363", "34364", "34366", "34370", "34372", "34373", "34375", "34377", "34378", "34379", "34380", "34382", "34383", "34384", "34385", "34387", "34391", "34393", "34395", "34396", "34397", "34398", "34400", "34401", "34402", "34403", "34404", "34406", "34407", "34408", "34410", "34411", "34416", "34417", "34419", "34421", "34423", "34424", "34427", "34428", "34430", "34431", "34432", "34433", "34434", "34435", "34438", "34441", "34442", "34446", "34447", "34448", "34452", "34453", "34456", "34457", "34458", "34460", "34461", "34462", "34463", "34464", "34465", "34469", "34470", "34472", "34473", "34474", "34475", "34477", "34480", "34481", "34482", "34483", "34484", "34487", "34488", "34490", "34492", "34493", "34495", "34497", "34501", "34503", "34505", "34507", "34508", "34509", "34511", "34515", "34522", "34524", "34525", "34526", "34527", "34528", "34529", "34530", "34531", "34532", "34536", "34537", "34538", "34540", "34541", "34542", "34545", "34549", "34550", "34551", "34552", "34553", "34559", "34560", "34562", "34563", "34570", "34572", "34573", "34577", "34580", "34581", "34584", "34585", "34588", "34593", "34599", "34600", "34604", "34607", "34609", "34611", "34612", "34613", "34615", "34618", "34620", "34622", "34624", "34625", "34629", "34630", "34631", "34635", "34637", "34638", "34639", "34641", "34642", "34647", "34649", "34651", "34652", "34653", "34656", "34661", "34662", "34663", "34664", "34666", "34671", "34675", "34679", "34684", "34685", "34688", "34691", "34695", "34697", "34700", "34702", "34703", "34706", "34707", "34713", "34714", "34715", "34718", "34723", "34724", "34726", "34731", "34736", "34741", "34746", "34747", "34751", "34752", "34754", "34756", "34758", "34760", "34763", "34764", "34765", "34766", "34767", "34772", "34773", "34777", "34778", "34779", "34782", "34785", "34786", "34789", "34790", "34792", "34793", "34795", "34798", "34802", "34804", "34807", "34811", "34813", "34814", "34817", "34818", "34819", "34820", "34821", "34823", "34827", "34828", "34829", "34832", "34833", "34834", "34835", "34836", "34839", "34841", "34846", "34848", "34851", "34853", "34857", "34858", "34860", "34861", "34863", "34865", "34866", "34870", "34873", "34874", "34875", "34876", "34882", "34884", "34885", "34886", "34892", "34893", "34896", "34897", "34898", "34900", "34901", "34906", "34908", "34912", "34913", "34914", "34916", "34917", "34918", "34921", "34922", "34925", "34928", "34930", "34932", "34936", "34941", "34942", "34947", "34948", "34950", "34953", "34958", "34960", "34961", "34962", "34964", "34966", "34968", "34969", "34971", "34972", "34973", "34974", "34976", "34977", "34979", "34981", "34984", "34988", "34994", "34996", "34998", "34999", "35000", "35001", "35002", "35003", "35004", "35005", "35007", "35012", "35013", "35015", "35021", "35022", "35024", "35029", "35034", "35039", "35040", "35041", "35042", "35043", "35045", "35047", "35049", "35050", "35051", "35053", "35055", "35056", "35057", "35058", "35059", "35060", "35063", "35064", "35065", "35069", "35072", "35074", "35075", "35079", "35084", "35086", "35087", "35088", "35092", "35095", "35096", "35097", "35099", "35100", "35101", "35102", "35104", "35105", "35108", "35110", "35112", "35113", "35114", "35115", "35116", "35117", "35121", "35122", "35123", "35126", "35128", "35129", "35131", "35132", "35134", "35138", "35140", "35141", "35142", "35143", "35145", "35147", "35149", "35152", "35153", "35154", "35155", "35156", "35157", "35160", "35165", "35167", "35169", "35170", "35172", "35174", "35176", "35179", "35183", "35184", "35186", "35189", "35190", "35194", "35197", "35198", "35200", "35202", "35207", "35209", "35210", "35212", "35213", "35215", "35216", "35220", "35223", "35225", "35226", "35229", "35230", "35235", "35236", "35239", "35243", "35244", "35245", "35248", "35253", "35254", "35255", "35256", "35258", "35259", "35261", "35262", "35263", "35265", "35266", "35267", "35269", "35270", "35275", "35281", "35283", "35285", "35288", "35290", "35291", "35292", "35294", "35295", "35297", "35298", "35302", "35303", "35305", "35307", "35308", "35309", "35310", "35313", "35315", "35318", "35320", "35321", "35325", "35326", "35327", "35328", "35333", "35338", "35341", "35348", "35350", "35352", "35353", "35358", "35360", "35361", "35363", "35364", "35368", "35369", "35370", "35371", "35372", "35374", "35375", "35376", "35377", "35378", "35379", "35381", "35383", "35385", "35387", "35389", "35390", "35394", "35395", "35396", "35398", "35399", "35401", "35403", "35409", "35410", "35412", "35413", "35418", "35419", "35420", "35421", "35425", "35426", "35427", "35428", "35429", "35431", "35435", "35437", "35439", "35440", "35441", "35445", "35448", "35449", "35451", "35452", "35453", "35455", "35456", "35462", "35463", "35464", "35465", "35468", "35473", "35474", "35476", "35477", "35478", "35479", "35482", "35483", "35485", "35491", "35492", "35493", "35494", "35495", "35502", "35503", "35510", "35511", "35513", "35515", "35516", "35517", "35519", "35520", "35522", "35523", "35524", "35526", "35527", "35532", "35534", "35536", "35538", "35539", "35540", "35543", "35544", "35546", "35549", "35552", "35554", "35560", "35563", "35564", "35565", "35566", "35567", "35570", "35571", "35574", "35578", "35579", "35580", "35581", "35583", "35584", "35585", "35589", "35590", "35591", "35592", "35593", "35594", "35595", "35596", "35599", "35602", "35603", "35604", "35606", "35608", "35611", "35614", "35617", "35618", "35624", "35625", "35626", "35627", "35628", "35629", "35630", "35631", "35633", "35634", "35635", "35638", "35639", "35641", "35643", "35644", "35645", "35646", "35647", "35649", "35652", "35653", "35657", "35658", "35659", "35664", "35666", "35667", "35668", "35670", "35672", "35675", "35681", "35686", "35687", "35688", "35691", "35693", "35696", "35698", "35699", "35700", "35703", "35705", "35706", "35708", "35709", "35710", "35711", "35712", "35717", "35719", "35723", "35725", "35727", "35728", "35733", "35734", "35735", "35736", "35737", "35738", "35740", "35741", "35744", "35745", "35748", "35749", "35751", "35752", "35753", "35756", "35759", "35762", "35764", "35770", "35771", "35772", "35774", "35777", "35778", "35783", "35785", "35786", "35787", "35788", "35789", "35790", "35792", "35794", "35797", "35801", "35802", "35804", "35805", "35807", "35808", "35809", "35811", "35812", "35815", "35817", "35820", "35823", "35825", "35826", "35828", "35831", "35834", "35837", "35839", "35841", "35842", "35846", "35848", "35851", "35852", "35854", "35856", "35860", "35861", "35862", "35864", "35866", "35867", "35869", "35871", "35874", "35876", "35877", "35878", "35879", "35881", "35883", "35886", "35887", "35888", "35890", "35894", "35895", "35897", "35898", "35901", "35902", "35903", "35904", "35907", "35908", "35910", "35911", "35913", "35915", "35916", "35917", "35918", "35919", "35921", "35925", "35926", "35931", "35932", "35933", "35934", "35935", "35937", "35939", "35942", "35944", "35947", "35949", "35950", "35951", "35953", "35954", "35955", "35956", "35958", "35961", "35962", "35965", "35971", "35974", "35980", "35983", "35987", "35988", "35989", "35990", "35991", "35992", "35994", "35997", "35999", "36000", "36001", "36002", "36003", "36004", "36005", "36006", "36014", "36015", "36017", "36019", "36020", "36022", "36028", "36030", "36031", "36032", "36033", "36034", "36035", "36036", "36040", "36041", "36044", "36045", "36047", "36048", "36049", "36051", "36054", "36058", "36059", "36061", "36062", "36063", "36066", "36068", "36069", "36070", "36072", "36074", "36075", "36077", "36080", "36081", "36082", "36083", "36086", "36087", "36088", "36089", "36090", "36091", "36099", "36101", "36103", "36108", "36109", "36110", "36111", "36113", "36115", "36119", "36121", "36124", "36126", "36130", "36132", "36134", "36135", "36136", "36137", "36141", "36142", "36143", "36149", "36151", "36152", "36155", "36158", "36163", "36166", "36167", "36170", "36171", "36172", "36173", "36174", "36176", "36180", "36183", "36188", "36189", "36190", "36191", "36192", "36195", "36197", "36198", "36200", "36201", "36202", "36203", "36204", "36205", "36207", "36208", "36209", "36212", "36213", "36215", "36217", "36223", "36224", "36227", "36229", "36230", "36234", "36235", "36236", "36237", "36240", "36242", "36243", "36246", "36253", "36262", "36264", "36267", "36269", "36270", "36271", "36272", "36274", "36277", "36280", "36282", "36283", "36284", "36288", "36289", "36291", "36297", "36300", "36301", "36302", "36303", "36304", "36305", "36307", "36308", "36309", "36310", "36313", "36314", "36316", "36318", "36319", "36321", "36322", "36324", "36325", "36327", "36329", "36332", "36336", "36338", "36340", "36341", "36343", "36346", "36347", "36350", "36351", "36352", "36354", "36355", "36359", "36361", "36363", "36364", "36365", "36370", "36372", "36373", "36374", "36376", "36377", "36378", "36379", "36380", "36381", "36384", "36385", "36386", "36390", "36391", "36392", "36393", "36394", "36395", "36396", "36397", "36400", "36401", "36402", "36403", "36404", "36408", "36410", "36411", "36413", "36415", "36417", "36421", "36423", "36424", "36426", "36428", "36430", "36431", "36432", "36434", "36435", "36439", "36441", "36443", "36445", "36446", "36447", "36448", "36449", "36451", "36452", "36457", "36458", "36459", "36461", "36463", "36466", "36467", "36470", "36471", "36472", "36473", "36474", "36477", "36482", "36483", "36486", "36489", "36490", "36493", "36495", "36496", "36497", "36498", "36499", "36500", "36501", "36502", "36503", "36504", "36505", "36510", "36511", "36512", "36513", "36515", "36517", "36518", "36519", "36524", "36526", "36530", "36533", "36534", "36535", "36536", "36539", "36541", "36543", "36545", "36546", "36548", "36550", "36552", "36553", "36554", "36555", "36556", "36557", "36558", "36559", "36560", "36563", "36565", "36566", "36567", "36568", "36569", "36570", "36573", "36574", "36576", "36577", "36578", "36581", "36583", "36584", "36594", "36595", "36597", "36600", "36603", "36605", "36607", "36608", "36609", "36610", "36613", "36615", "36617", "36621", "36622", "36623", "36625", "36627", "36629", "36630", "36633", "36635", "36636", "36637", "36639", "36640", "36643", "36646", "36647", "36653", "36654", "36655", "36656", "36657", "36658", "36659", "36660", "36661", "36667", "36668", "36670", "36672", "36675", "36678", "36681", "36683", "36685", "36686", "36688", "36690", "36693", "36694", "36696", "36698", "36699", "36703", "36704", "36705", "36706", "36708", "36710", "36711", "36712", "36714", "36715", "36718", "36720", "36721", "36726", "36729", "36730", "36733", "36734", "36735", "36736", "36737", "36739", "36741", "36742", "36743", "36744", "36746", "36751", "36752", "36757", "36758", "36759", "36760", "36761", "36763", "36765", "36768", "36770", "36771", "36773", "36776", "36778", "36781", "36784", "36787", "36788", "36789", "36790", "36791", "36793", "36794", "36795", "36796", "36797", "36801", "36802", "36811", "36813", "36815", "36816", "36820", "36821", "36823", "36825", "36827", "36829", "36830", "36832", "36833", "36836", "36839", "36841", "36843", "36845", "36846", "36850", "36851", "36854", "36855", "36856", "36857", "36858", "36860", "36862", "36863", "36864", "36866", "36867", "36870", "36871", "36872", "36873", "36875", "36876", "36877", "36878", "36881", "36887", "36888", "36894", "36895", "36897", "36898", "36899", "36900", "36902", "36903", "36907", "36908", "36909", "36910", "36911", "36912", "36913", "36914", "36915", "36917", "36920", "36921", "36922", "36923", "36924", "36925", "36927", "36928", "36933", "36935", "36937", "36938", "36939", "36942", "36944", "36946", "36947", "36951", "36952", "36954", "36955", "36957", "36960", "36961", "36964", "36966", "36970", "36975", "36978", "36979", "36982", "36985", "36987", "36988", "36989", "36991", "36992", "36994", "36997", "36998", "36999", "37000", "37001", "37005", "37006", "37009", "37010", "37012", "37013", "37014", "37015", "37017", "37018", "37019", "37021", "37023", "37026", "37027", "37029", "37033", "37034", "37035", "37036", "37038", "37039", "37040", "37041", "37042", "37043", "37044", "37046", "37048", "37051", "37052", "37054", "37057", "37059", "37061", "37064", "37066", "37067", "37070", "37074", "37076", "37077", "37081", "37083", "37084", "37086", "37087", "37089", "37090", "37091", "37092", "37094", "37100", "37101", "37106", "37107", "37108", "37110", "37112", "37113", "37114", "37116", "37121", "37122", "37125", "37127", "37128", "37129", "37130", "37131", "37133", "37134", "37136", "37138", "37139", "37140", "37143", "37144", "37147", "37148", "37151", "37153", "37154", "37157", "37158", "37161", "37163", "37164", "37166", "37167", "37169", "37171", "37172", "37174", "37177", "37178", "37179", "37182", "37184", "37185", "37187", "37188", "37190", "37191", "37192", "37193", "37194", "37195", "37197", "37199", "37201", "37203", "37205", "37207", "37210", "37211", "37213", "37214", "37217", "37219", "37220", "37222", "37224", "37226", "37228", "37229", "37230", "37231", "37234", "37239", "37240", "37241", "37242", "37245", "37246", "37247", "37249", "37250", "37253", "37255", "37261", "37263", "37265", "37269", "37270", "37271", "37272", "37273", "37276", "37277", "37278", "37279", "37280", "37283", "37287", "37288", "37289", "37290", "37292", "37296", "37297", "37298", "37299", "37300", "37302", "37303", "37305", "37307", "37310", "37311", "37313", "37314", "37318", "37319", "37323", "37325", "37329", "37331", "37332", "37334", "37337", "37343", "37344", "37347", "37349", "37350", "37351", "37352", "37358", "37363", "37364", "37365", "37368", "37369", "37370", "37371", "37372", "37373", "37375", "37376", "37379", "37382", "37385", "37386", "37387", "37390", "37392", "37402", "37403", "37404", "37406", "37408", "37410", "37411", "37412", "37413", "37416", "37418", "37419", "37421", "37424", "37426", "37427", "37434", "37437", "37438", "37439", "37441", "37443", "37445", "37447", "37451", "37452", "37455", "37457", "37458", "37459", "37461", "37462", "37463", "37464", "37470", "37471", "37472", "37474", "37478", "37481", "37488", "37490", "37492", "37493", "37495", "37496", "37498", "37500", "37501", "37502", "37506", "37507", "37508", "37509", "37510", "37511", "37515", "37517", "37518", "37520", "37522", "37525", "37526", "37527", "37529", "37531", "37533", "37534", "37535", "37536", "37537", "37540", "37541", "37542", "37544", "37545", "37547", "37551", "37553", "37554", "37555", "37558", "37561", "37563", "37564", "37573", "37578", "37579", "37580", "37581", "37584", "37585", "37586", "37589", "37590", "37594", "37596", "37600", "37602", "37605", "37606", "37608", "37609", "37610", "37612", "37613", "37616", "37617", "37619", "37620", "37621", "37627", "37628", "37629", "37630", "37633", "37637", "37638", "37639", "37640", "37643", "37646", "37648", "37655", "37658", "37662", "37664", "37667", "37668", "37669", "37670", "37673", "37680", "37681", "37682", "37684", "37686", "37687", "37690", "37695", "37696", "37697", "37698", "37700", "37702", "37703", "37704", "37708", "37709", "37710", "37712", "37713", "37714", "37716", "37717", "37720", "37721", "37723", "37724", "37725", "37726", "37729", "37730", "37731", "37732", "37738", "37740", "37742", "37743", "37749", "37753", "37755", "37757", "37759", "37760", "37765", "37766", "37767", "37769", "37770", "37771", "37773", "37775", "37776", "37777", "37778", "37780", "37782", "37783", "37785", "37786", "37788", "37789", "37791", "37792", "37793", "37795", "37800", "37801", "37805", "37808", "37812", "37814", "37815", "37816", "37817", "37818", "37819", "37820", "37821", "37826", "37828", "37829", "37833", "37835", "37836", "37839", "37840", "37843", "37847", "37848", "37850", "37851", "37852", "37854", "37856", "37858", "37860", "37862", "37864", "37865", "37866", "37867", "37870", "37872", "37875", "37879", "37882", "37883", "37887", "37892", "37893", "37895", "37896", "37897", "37900", "37905", "37907", "37912", "37913", "37914", "37916", "37918", "37919", "37920", "37923", "37924", "37932", "37933", "37936", "37939", "37941", "37942", "37944", "37945", "37948", "37950", "37953", "37955", "37956", "37958", "37962", "37963", "37965", "37967", "37971", "37972", "37979", "37980", "37981", "37982", "37983", "37984", "37985", "37986", "37988", "37989", "37990", "37993", "37997", "37998", "37999", "38001", "38003", "38004", "38005", "38008", "38011", "38012", "38014", "38016", "38017", "38018", "38019", "38023", "38024", "38027", "38028", "38029", "38031", "38036", "38038", "38039", "38040", "38041", "38042", "38043", "38049", "38050", "38051", "38052", "38054", "38056", "38058", "38061", "38063", "38064", "38068", "38071", "38076", "38078", "38082", "38083", "38085", "38087", "38088", "38091", "38092", "38093", "38096", "38097", "38098", "38099", "38100", "38105", "38106", "38107", "38114", "38115", "38116", "38117", "38118", "38119", "38121", "38123", "38126", "38128", "38136", "38137", "38138", "38140", "38141", "38143", "38144", "38147", "38148", "38149", "38150", "38152", "38153", "38156", "38158", "38160", "38162", "38164", "38165", "38167", "38173", "38180", "38182", "38183", "38185", "38186", "38187", "38190", "38192", "38196", "38197", "38200", "38203", "38204", "38208", "38209", "38211", "38212", "38215", "38216", "38220", "38222", "38226", "38227", "38229", "38231", "38232", "38234", "38235", "38237", "38239", "38242", "38243", "38245", "38246", "38247", "38251", "38252", "38263", "38266", "38271", "38273", "38275", "38276", "38277", "38278", "38279", "38280", "38282", "38289", "38290", "38291", "38292", "38293", "38294", "38295", "38296", "38298", "38301", "38302", "38303", "38305", "38307", "38310", "38312", "38314", "38315", "38316", "38318", "38319", "38321", "38323", "38324", "38326", "38328", "38335", "38336", "38340", "38341", "38342", "38344", "38345", "38346", "38347", "38348", "38350", "38351", "38352", "38353", "38354", "38355", "38356", "38357", "38359", "38361", "38362", "38363", "38366", "38368", "38370", "38373", "38374", "38375", "38376", "38378", "38379", "38380", "38381", "38382", "38383", "38388", "38393", "38394", "38395", "38396", "38401", "38403", "38404", "38405", "38406", "38409", "38410", "38411", "38412", "38413", "38415", "38416", "38418", "38420", "38421", "38422", "38423", "38425", "38426", "38427", "38428", "38430", "38431", "38432", "38433", "38435", "38437", "38438", "38439", "38441", "38443", "38446", "38447", "38451", "38454", "38458", "38459", "38460", "38462", "38463", "38465", "38467", "38468", "38470", "38471", "38475", "38476", "38478", "38484", "38486", "38489", "38492", "38496", "38497", "38498", "38500", "38501", "38502", "38506", "38507", "38509", "38514", "38517", "38519", "38520", "38523", "38524", "38525", "38526", "38527", "38528", "38530", "38531", "38538", "38540", "38542", "38544", "38545", "38547", "38548", "38550", "38556", "38559", "38560", "38562", "38563", "38566", "38568", "38570", "38574", "38575", "38578", "38579", "38584", "38585", "38586", "38589", "38593", "38594", "38596", "38597", "38600", "38601", "38606", "38608", "38609", "38611", "38612", "38614", "38618", "38619", "38620", "38621", "38622", "38627", "38628", "38631", "38632", "38634", "38635", "38636", "38638", "38639", "38640", "38643", "38644", "38645", "38646", "38647", "38651", "38655", "38657", "38658", "38659", "38661", "38663", "38665", "38669", "38670", "38671", "38673", "38678", "38679", "38681", "38682", "38683", "38685", "38686", "38690", "38695", "38697", "38699", "38700", "38705", "38706", "38707", "38712", "38714", "38717", "38722", "38723", "38724", "38727", "38730", "38731", "38733", "38734", "38735", "38737", "38738", "38743", "38744", "38745", "38746", "38748", "38749", "38753", "38756", "38757", "38758", "38761", "38762", "38763", "38765", "38766", "38768", "38770", "38771", "38772", "38774", "38775", "38777", "38780", "38783", "38785", "38787", "38788", "38790", "38792", "38794", "38795", "38796", "38800", "38801", "38802", "38805", "38806", "38811", "38815", "38817", "38819", "38820", "38821", "38825", "38826", "38831", "38832", "38833", "38836", "38837", "38841", "38842", "38847", "38848", "38849", "38850", "38851", "38853", "38854", "38855", "38856", "38857", "38858", "38859", "38860", "38861", "38866", "38870", "38872", "38875", "38879", "38880", "38885", "38886", "38888", "38889", "38891", "38892", "38897", "38899", "38902", "38903", "38911", "38912", "38913", "38914", "38917", "38921", "38923", "38924", "38929", "38930", "38931", "38933", "38935", "38936", "38937", "38938", "38939", "38940", "38942", "38943", "38944", "38945", "38949", "38950", "38952", "38955", "38957", "38960", "38962", "38963", "38964", "38965", "38971", "38973", "38974", "38976", "38978", "38980", "38981", "38982", "38983", "38986", "38989", "38991", "38993", "38994", "38996", "38997", "38998", "39005", "39006", "39008", "39009", "39010", "39013", "39014", "39015", "39016", "39020", "39021", "39023", "39025", "39026", "39028", "39033", "39035", "39036", "39039", "39040", "39041", "39047", "39048", "39049", "39051", "39054", "39056", "39057", "39058", "39060", "39062", "39065", "39066", "39067", "39069", "39071", "39072", "39073", "39075", "39077", "39079", "39081", "39083", "39084", "39087", "39089", "39090", "39093", "39094", "39097", "39098", "39101", "39104", "39107", "39108", "39109", "39110", "39112", "39113", "39114", "39115", "39116", "39117", "39118", "39119", "39122", "39125", "39128", "39129", "39130", "39131", "39133", "39140", "39141", "39142", "39143", "39144", "39147", "39148", "39149", "39152", "39153", "39154", "39155", "39158", "39159", "39160", "39163", "39164", "39165", "39166", "39167", "39169", "39170", "39171", "39172", "39175", "39176", "39177", "39178", "39180", "39181", "39182", "39183", "39186", "39188", "39190", "39191", "39193", "39198", "39202", "39203", "39204", "39205", "39207", "39208", "39210", "39213", "39214", "39215", "39217", "39220", "39222", "39225", "39228", "39229", "39230", "39232", "39233", "39235", "39237", "39241", "39243", "39246", "39249", "39250", "39251", "39254", "39255", "39256", "39259", "39260", "39261", "39263", "39264", "39269", "39270", "39271", "39272", "39274", "39276", "39279", "39281", "39283", "39284", "39285", "39288", "39289", "39290", "39291", "39292", "39294", "39297", "39298", "39300", "39302", "39303", "39307", "39311", "39313", "39315", "39316", "39321", "39322", "39324", "39325", "39326", "39327", "39332", "39334", "39336", "39337", "39338", "39344", "39346", "39350", "39351", "39353", "39354", "39355", "39357", "39361", "39366", "39367", "39370", "39373", "39375", "39377", "39379", "39380", "39382", "39385", "39386", "39387", "39388", "39392", "39396", "39397", "39398", "39405", "39406", "39407", "39408", "39409", "39413", "39414", "39415", "39416", "39419", "39421", "39423", "39424", "39425", "39428", "39430", "39431", "39436", "39437", "39438", "39440", "39443", "39444", "39448", "39449", "39450", "39451", "39452", "39453", "39455", "39456", "39458", "39459", "39464", "39466", "39468", "39469", "39471", "39472", "39473", "39476", "39478", "39481", "39484", "39485", "39488", "39489", "39490", "39492", "39493", "39495", "39496", "39497", "39504", "39505", "39506", "39507", "39510", "39511", "39516", "39517", "39518", "39519", "39525", "39528", "39529", "39530", "39531", "39535", "39537", "39538", "39539", "39540", "39541", "39542", "39546", "39547", "39548", "39549", "39550", "39551", "39552", "39555", "39556", "39559", "39560", "39562", "39564", "39565", "39568", "39570", "39571", "39572", "39575", "39577", "39579", "39581", "39583", "39584", "39586", "39590", "39591", "39592", "39594", "39595", "39596", "39600", "39601", "39603", "39606", "39608", "39609", "39611", "39614", "39615", "39618", "39619", "39622", "39624", "39629", "39630", "39631", "39632", "39633", "39635", "39636", "39637", "39638", "39639", "39640", "39641", "39642", "39643", "39644", "39646", "39653", "39654", "39655", "39657", "39659", "39663", "39665", "39666", "39667", "39669", "39670", "39673", "39678", "39679", "39681", "39683", "39686", "39689", "39690", "39693", "39694", "39699", "39702", "39703", "39707", "39710", "39712", "39713", "39714", "39715", "39718", "39720", "39722", "39724", "39725", "39726", "39728", "39732", "39734", "39736", "39737", "39739", "39741", "39742", "39743", "39746", "39747", "39748", "39750", "39752", "39756", "39759", "39760", "39761", "39764", "39765", "39766", "39767", "39771", "39772", "39773", "39774", "39775", "39777", "39779", "39782", "39783", "39784", "39786", "39788", "39790", "39793", "39798", "39799", "39800", "39802", "39807", "39809", "39811", "39813", "39814", "39815", "39818", "39819", "39821", "39823", "39827", "39830", "39836", "39837", "39838", "39839", "39840", "39843", "39845", "39847", "39850", "39853", "39855", "39856", "39859", "39861", "39866", "39867", "39868", "39870", "39872", "39876", "39877", "39880", "39881", "39882", "39883", "39884", "39885", "39891", "39893", "39894", "39896", "39897", "39901", "39902", "39903", "39906", "39908", "39911", "39912", "39921", "39922", "39925", "39929", "39931", "39932", "39936", "39937", "39940", "39942", "39944", "39947", "39950", "39952", "39957", "39958", "39960", "39962", "39964", "39965", "39966", "39970", "39973", "39977", "39978", "39979", "39982", "39983", "39986", "39987", "39993", "39998", "39999", "40005", "40006", "40010", "40013", "40015", "40017", "40020", "40021", "40025", "40027", "40028", "40029", "40030", "40031", "40032", "40033", "40035", "40038", "40040", "40041", "40042", "40043", "40044", "40045", "40048", "40050", "40051", "40054", "40058", "40059", "40061", "40062", "40070", "40071", "40072", "40073", "40076", "40078", "40080", "40081", "40086", "40087", "40089", "40091", "40093", "40095", "40096", "40101", "40103", "40104", "40109", "40117", "40120", "40121", "40122", "40123", "40125", "40127", "40128", "40131", "40133", "40137", "40139", "40142", "40143", "40144", "40145", "40146", "40150", "40151", "40152", "40153", "40154", "40155", "40160", "40162", "40163", "40166", "40167", "40170", "40171", "40173", "40174", "40175", "40176", "40178", "40180", "40181", "40182", "40183", "40184", "40186", "40187", "40189", "40190", "40192", "40198", "40200", "40201", "40202", "40205", "40208", "40210", "40214", "40216", "40217", "40219", "40222", "40230", "40231", "40234", "40235", "40237", "40240", "40241", "40243", "40244", "40246", "40250", "40251", "40253", "40254", "40255", "40256", "40257", "40258", "40259", "40260", "40261", "40262", "40264", "40266", "40268", "40269", "40272", "40274", "40284", "40285", "40286", "40287", "40288", "40289", "40290", "40292", "40293", "40295", "40296", "40297", "40298", "40301", "40302", "40306", "40308", "40310", "40311", "40313", "40315", "40316", "40317", "40319", "40321", "40322", "40324", "40325", "40326", "40327", "40328", "40331", "40332", "40337", "40339", "40341", "40344", "40345", "40346", "40349", "40350", "40353", "40354", "40355", "40356", "40357", "40358", "40360", "40361", "40366", "40368", "40372", "40373", "40376", "40377", "40378", "40379", "40382", "40390", "40394", "40398", "40402", "40403", "40404", "40405", "40406", "40407", "40408", "40410", "40413", "40416", "40417", "40418", "40420", "40421", "40422", "40425", "40426", "40427", "40428", "40429", "40430", "40431", "40433", "40434", "40436", "40437", "40438", "40441", "40442", "40443", "40444", "40446", "40447", "40448", "40449", "40451", "40452", "40454", "40457", "40459", "40460", "40461", "40464", "40465", "40466", "40469", "40471", "40472", "40473", "40476", "40477", "40478", "40481", "40482", "40483", "40485", "40488", "40491", "40492", "40494", "40495", "40497", "40498", "40503", "40504", "40509", "40510", "40514", "40515", "40516", "40517", "40518", "40521", "40523", "40524", "40527", "40529", "40530", "40531", "40535", "40537", "40540", "40541", "40542", "40543", "40546", "40551", "40552", "40553", "40555", "40558", "40561", "40562", "40563", "40565", "40570", "40573", "40574", "40575", "40576", "40578", "40579", "40580", "40581", "40582", "40585", "40588", "40589", "40590", "40591", "40595", "40597", "40598", "40601", "40605", "40606", "40607", "40608", "40609", "40610", "40614", "40617", "40618", "40620", "40621", "40623", "40624", "40628", "40630", "40631", "40632", "40633", "40634", "40636", "40637", "40640", "40641", "40645", "40646", "40647", "40648", "40649", "40653", "40655", "40657", "40658", "40659", "40663", "40664", "40665", "40666", "40667", "40669", "40670", "40671", "40672", "40673", "40674", "40675", "40676", "40678", "40679", "40680", "40681", "40682", "40685", "40686", "40688", "40689", "40692", "40694", "40695", "40696", "40698", "40699", "40700", "40701", "40703", "40704", "40708", "40709", "40710", "40712", "40714", "40715", "40718", "40720", "40723", "40724", "40726", "40727", "40728", "40730", "40732", "40735", "40736", "40737", "40739", "40742", "40745", "40746", "40747", "40748", "40750", "40751", "40754", "40756", "40760", "40761", "40767", "40768", "40769", "40770", "40771", "40772", "40775", "40776", "40777", "40778", "40780", "40781", "40783", "40785", "40786", "40787", "40788", "40793", "40794", "40795", "40796", "40799", "40800", "40802", "40803", "40804", "40805", "40809", "40811", "40815", "40818", "40819", "40822", "40824", "40825", "40826", "40827", "40828", "40831", "40833", "40837", "40838", "40839", "40840", "40841", "40843", "40846", "40850", "40852", "40854", "40855", "40856", "40857", "40859", "40860", "40862", "40863", "40864", "40865", "40869", "40872", "40873", "40877", "40880", "40884", "40885", "40886", "40887", "40888", "40889", "40890", "40891", "40892", "40894", "40897", "40899", "40901", "40902", "40903", "40906", "40907", "40912", "40913", "40914", "40915", "40917", "40919", "40920", "40922", "40923", "40924", "40925", "40927", "40928", "40929", "40932", "40933", "40938", "40944", "40945", "40946", "40949", "40950", "40951", "40952", "40956", "40960", "40962", "40963", "40964", "40966", "40967", "40969", "40972", "40973", "40976", "40979", "40980", "40982", "40983", "40984", "40988", "40991", "40992", "40994", "40996", "40997", "41000", "41004", "41008", "41012", "41013", "41015", "41016", "41018", "41019", "41021", "41022", "41024", "41025", "41026", "41029", "41030", "41031", "41035", "41036", "41039", "41041", "41044", "41046", "41048", "41049", "41050", "41051", "41052", "41054", "41055", "41056", "41057", "41058", "41061", "41064", "41065", "41068", "41071", "41072", "41073", "41075", "41077", "41078", "41079", "41081", "41082", "41084", "41085", "41089", "41090", "41091", "41094", "41096", "41097", "41098", "41099", "41100", "41106", "41107", "41108", "41110", "41112", "41114", "41115", "41116", "41118", "41120", "41122", "41125", "41126", "41127", "41128", "41129", "41131", "41132", "41136", "41138", "41139", "41141", "41143", "41147", "41148", "41149", "41152", "41154", "41155", "41156", "41158", "41161", "41163", "41164", "41167", "41168", "41169", "41170", "41171", "41172", "41173", "41174", "41177", "41178", "41180", "41181", "41184", "41186", "41190", "41191", "41196", "41197", "41198", "41200", "41201", "41202", "41203", "41204", "41206", "41208", "41211", "41214", "41216", "41217", "41218", "41220", "41223", "41225", "41226", "41227", "41228", "41229", "41230", "41232", "41233", "41235", "41236", "41237", "41238", "41240", "41242", "41246", "41250", "41251", "41253", "41254", "41255", "41259", "41260", "41261", "41264", "41265", "41266", "41268", "41270", "41271", "41273", "41276", "41277", "41279", "41281", "41284", "41290", "41291", "41295", "41301", "41302", "41306", "41309", "41311", "41313", "41314", "41316", "41317", "41318", "41319", "41320", "41325", "41329", "41332", "41333", "41334", "41336", "41338", "41339", "41341", "41342", "41344", "41345", "41346", "41347", "41348", "41351", "41352", "41354", "41360", "41362", "41364", "41366", "41368", "41369", "41370", "41372", "41377", "41378", "41383", "41385", "41389", "41391", "41393", "41394", "41396", "41399", "41400", "41402", "41405", "41406", "41408", "41411", "41413", "41415", "41416", "41417", "41418", "41421", "41422", "41423", "41425", "41427", "41430", "41431", "41436", "41437", "41439", "41442", "41443", "41446", "41447", "41449", "41450", "41451", "41453", "41455", "41456", "41461", "41469", "41471", "41472", "41475", "41477", "41478", "41481", "41482", "41484", "41487", "41490", "41492", "41493", "41496", "41499", "41500", "41501", "41502", "41504", "41505", "41507", "41508", "41514", "41515", "41516", "41517", "41518", "41520", "41524", "41525", "41532", "41536", "41537", "41538", "41539", "41540", "41542", "41543", "41544", "41550", "41551", "41552", "41553", "41554", "41556", "41557", "41558", "41559", "41561", "41563", "41565", "41566", "41568", "41569", "41572", "41574", "41577", "41578", "41579", "41586", "41587", "41588", "41590", "41594", "41595", "41598", "41599", "41600", "41601", "41603", "41604", "41605", "41608", "41610", "41611", "41612", "41613", "41614", "41623", "41624", "41626", "41628", "41629", "41632", "41636", "41637", "41640", "41641", "41642", "41643", "41647", "41649", "41650", "41654", "41655", "41658", "41659", "41660", "41661", "41663", "41666", "41669", "41670", "41671", "41675", "41678", "41679", "41680", "41684", "41686", "41688", "41689", "41694", "41697", "41698", "41702", "41703", "41705", "41706", "41711", "41714", "41720", "41721", "41723", "41727", "41728", "41729", "41731", "41732", "41734", "41737", "41738", "41740", "41741", "41744", "41746", "41747", "41749", "41751", "41752", "41754", "41757", "41758", "41759", "41760", "41765", "41769", "41770", "41771", "41772", "41773", "41777", "41779", "41783", "41784", "41786", "41788", "41791", "41792", "41793", "41794", "41796", "41800", "41801", "41802", "41804", "41808", "41809", "41812", "41816", "41821", "41822", "41828", "41829", "41834", "41836", "41844", "41845", "41850", "41851", "41854", "41855", "41858", "41861", "41862", "41863", "41870", "41872", "41873", "41875", "41880", "41886", "41888", "41889", "41891", "41893", "41894", "41897", "41900", "41901", "41902", "41903", "41905", "41907", "41909", "41914", "41915", "41916", "41917", "41918", "41925", "41927", "41928", "41930", "41932", "41934", "41938", "41942", "41943", "41944", "41946", "41947", "41949", "41952", "41954", "41958", "41960", "41965", "41966", "41967", "41969", "41971", "41975", "41977", "41978", "41979", "41981", "41982", "41990", "41993", "41998", "41999", "42003", "42004", "42007", "42009", "42010", "42011", "42016", "42020", "42021", "42022", "42023", "42028", "42031", "42033", "42034", "42035", "42036", "42037", "42042", "42046", "42047", "42048", "42049", "42050", "42054", "42055", "42056", "42060", "42063", "42065", "42068", "42069", "42073", "42074", "42075", "42078", "42081", "42082", "42083", "42087", "42088", "42089", "42090", "42094", "42095", "42096", "42098", "42099", "42100", "42101", "42102", "42105", "42109", "42113", "42114", "42115", "42117", "42118", "42119", "42120", "42122", "42124", "42129", "42130", "42139", "42142", "42144", "42146", "42148", "42152", "42153", "42156", "42157", "42158", "42159", "42160", "42161", "42162", "42163", "42165", "42167", "42169", "42172", "42173", "42177", "42179", "42183", "42187", "42189", "42191", "42194", "42195", "42196", "42197", "42199", "42203", "42204", "42209", "42210", "42211", "42212", "42214", "42215", "42217", "42219", "42221", "42223", "42224", "42225", "42227", "42228", "42231", "42233", "42234", "42236", "42239", "42245", "42246", "42247", "42249", "42250", "42251", "42252", "42257", "42258", "42265", "42266", "42268", "42269", "42271", "42272", "42273", "42276", "42277", "42278", "42279", "42282", "42286", "42289", "42293", "42295", "42297", "42298", "42300", "42301", "42303", "42309", "42310", "42311", "42313", "42315", "42321", "42323", "42324", "42326", "42327", "42330", "42331", "42333", "42334", "42336", "42339", "42342", "42344", "42345", "42346", "42347", "42350", "42352", "42354", "42355", "42356", "42359", "42362", "42363", "42365", "42368", "42374", "42375", "42378", "42379", "42380", "42381", "42382", "42385", "42386", "42388", "42389", "42393", "42394", "42396", "42397", "42398", "42399", "42404", "42405", "42407", "42410", "42413", "42418", "42422", "42423", "42425", "42428", "42432", "42437", "42438", "42439", "42441", "42442", "42445", "42447", "42448", "42449", "42451", "42454", "42456", "42458", "42459", "42462", "42463", "42465", "42470", "42471", "42474", "42475", "42477", "42478", "42480", "42483", "42485", "42486", "42489", "42490", "42491", "42492", "42493", "42496", "42497", "42498", "42499", "42500", "42504", "42507", "42509", "42511", "42513", "42514", "42515", "42518", "42519", "42523", "42525", "42526", "42527", "42528", "42534", "42536", "42539", "42541", "42544", "42546", "42547", "42550", "42551", "42554", "42555", "42557", "42558", "42560", "42561", "42563", "42564", "42568", "42569", "42571", "42572", "42574", "42575", "42576", "42577", "42578", "42579", "42581", "42582", "42584", "42586", "42587", "42591", "42592", "42593", "42596", "42597", "42602", "42604", "42605", "42606", "42607", "42608", "42609", "42612", "42613", "42615", "42616", "42617", "42618", "42619", "42625", "42631", "42634", "42635", "42638", "42641", "42644", "42645", "42646", "42647", "42650", "42654", "42655", "42656", "42658", "42659", "42660", "42663", "42664", "42665", "42666", "42668", "42669", "42670", "42671", "42673", "42674", "42677", "42680", "42684", "42687", "42689", "42691", "42692", "42693", "42694", "42695", "42697", "42698", "42699", "42700", "42701", "42705", "42706", "42709", "42710", "42712", "42714", "42717", "42719", "42720", "42721", "42724", "42727", "42729", "42730", "42731", "42733", "42735", "42738", "42739", "42740", "42741", "42742", "42743", "42746", "42747", "42748", "42749", "42750", "42753", "42754", "42756", "42757", "42758", "42761", "42762", "42763", "42764", "42765", "42766", "42769", "42771", "42775", "42776", "42778", "42782", "42784", "42787", "42791", "42793", "42794", "42795", "42796", "42798", "42800", "42803", "42804", "42810", "42812", "42813", "42814", "42818", "42820", "42822", "42825", "42827", "42828", "42829", "42832", "42834", "42835", "42836", "42838", "42839", "42842", "42843", "42845", "42847", "42850", "42852", "42854", "42855", "42857", "42859", "42860", "42861", "42862", "42863", "42864", "42865", "42866", "42875", "42877", "42878", "42879", "42881", "42886", "42892", "42893", "42894", "42896", "42897", "42899", "42901", "42902", "42903", "42904", "42906", "42911", "42913", "42914", "42916", "42918", "42924", "42928", "42932", "42934", "42935", "42937", "42940", "42941", "42943", "42944", "42947", "42950", "42951", "42962", "42963", "42966", "42972", "42973", "42974", "42975", "42976", "42977", "42978", "42981", "42983", "42984", "42985", "42986", "42989", "42991", "42993", "43000", "43001", "43002", "43004", "43005", "43006", "43007", "43010", "43011", "43013", "43014", "43015", "43016", "43020", "43021", "43022", "43023", "43024", "43027", "43028", "43029", "43030", "43031", "43036", "43037", "43038", "43039", "43041", "43042", "43043", "43044", "43045", "43046", "43047", "43051", "43054", "43055", "43056", "43058", "43062", "43065", "43066", "43068", "43071", "43073", "43077", "43080", "43082", "43084", "43088", "43090", "43091", "43097", "43099", "43101", "43102", "43106", "43107", "43109", "43117", "43118", "43119", "43121", "43123", "43124", "43125", "43129", "43130", "43131", "43134", "43135", "43136", "43137", "43138", "43140", "43141", "43143", "43146", "43152", "43153", "43155", "43157", "43158", "43159", "43160", "43165", "43167", "43168", "43171", "43172", "43173", "43174", "43180", "43186", "43193", "43194", "43196", "43197", "43198", "43199", "43202", "43210", "43211", "43212", "43214", "43216", "43220", "43224", "43227", "43228", "43231", "43232", "43235", "43237", "43241", "43245", "43247", "43248", "43250", "43251", "43253", "43254", "43261", "43262", "43270", "43271", "43272", "43273", "43274", "43276", "43277", "43278", "43282", "43284", "43285", "43287", "43289", "43290", "43291", "43294", "43295", "43298", "43299", "43301", "43302", "43303", "43305", "43306", "43307", "43309", "43311", "43312", "43314", "43317", "43318", "43320", "43322", "43323", "43328", "43336", "43338", "43339", "43340", "43341", "43344", "43345", "43346", "43347", "43348", "43350", "43351", "43352", "43355", "43356", "43360", "43363", "43364", "43369", "43370", "43373", "43374", "43375", "43376", "43377", "43380", "43381", "43383", "43385", "43390", "43391", "43396", "43397", "43400", "43403", "43405", "43406", "43407", "43408", "43410", "43411", "43413", "43418", "43420", "43426", "43428", "43429", "43432", "43433", "43434", "43440", "43443", "43444", "43445", "43447", "43449", "43450", "43451", "43453", "43455", "43457", "43460", "43461", "43462", "43464", "43467", "43468", "43469", "43473", "43474", "43475", "43476", "43477", "43479", "43484", "43486", "43487", "43489", "43490", "43493", "43495", "43500", "43503", "43505", "43506", "43507", "43508", "43509", "43511", "43514", "43515", "43516", "43520", "43521", "43522", "43523", "43524", "43526", "43527", "43528", "43529", "43530", "43533", "43534", "43538", "43539", "43540", "43542", "43543", "43548", "43550", "43551", "43555", "43557", "43560", "43561", "43563", "43564", "43565", "43567", "43568", "43569", "43570", "43571", "43572", "43574", "43577", "43580", "43582", "43583", "43584", "43585", "43586", "43588", "43589", "43590", "43592", "43594", "43595", "43598", "43599", "43600", "43601", "43602", "43604", "43606", "43607", "43612", "43613", "43615", "43616", "43619", "43620", "43621", "43624", "43626", "43628", "43631", "43632", "43633", "43635", "43638", "43641", "43642", "43645", "43648", "43650", "43651", "43654", "43660", "43661", "43662", "43664", "43667", "43672", "43675", "43676", "43678", "43679", "43680", "43681", "43683", "43684", "43685", "43686", "43689", "43691", "43696", "43700", "43705", "43707", "43713", "43714", "43716", "43717", "43719", "43720", "43724", "43726", "43730", "43733", "43738", "43739", "43740", "43741", "43746", "43748", "43751", "43752", "43753", "43754", "43755", "43757", "43758", "43767", "43768", "43769", "43770", "43771", "43772", "43773", "43775", "43777", "43778", "43780", "43783", "43785", "43788", "43793", "43794", "43795", "43798", "43803", "43805", "43811", "43812", "43813", "43816", "43819", "43820", "43825", "43829", "43831", "43833", "43834", "43835", "43838", "43841", "43842", "43843", "43844", "43846", "43847", "43849", "43851", "43852", "43858", "43860", "43862", "43863", "43864", "43865", "43869", "43870", "43873", "43874", "43876", "43878", "43880", "43881", "43882", "43884", "43886", "43887", "43890", "43892", "43894", "43895", "43900", "43901", "43904", "43906", "43907", "43910", "43912", "43915", "43916", "43917", "43919", "43923", "43926", "43928", "43930", "43931", "43932", "43933", "43934", "43935", "43936", "43937", "43938", "43942", "43943", "43945", "43946", "43949", "43956", "43957", "43958", "43960", "43961", "43962", "43967", "43969", "43973", "43976", "43977", "43978", "43982", "43986", "43992", "43995", "43997", "43998", "43999", "44000", "44002", "44003", "44004", "44008", "44009", "44010", "44011", "44012", "44013", "44017", "44021", "44022", "44026", "44027", "44028", "44032", "44036", "44039", "44040", "44041", "44043", "44046", "44048", "44049", "44050", "44055", "44058", "44064", "44065", "44066", "44067", "44069", "44070", "44071", "44072", "44073", "44074", "44080", "44083", "44085", "44086", "44088", "44089", "44090", "44095", "44097", "44099", "44100", "44101", "44102", "44103", "44104", "44105", "44106", "44107", "44109", "44110", "44113", "44116", "44119", "44120", "44123", "44125", "44126", "44128", "44129", "44130", "44132", "44134", "44136", "44137", "44140", "44141", "44142", "44143", "44144", "44145", "44150", "44151", "44154", "44155", "44156", "44157", "44160", "44161", "44162", "44163", "44165", "44168", "44171", "44172", "44173", "44174", "44175", "44178", "44183", "44184", "44185", "44187", "44188", "44193", "44195", "44198", "44203", "44205", "44206", "44208", "44209", "44210", "44211", "44212", "44213", "44215", "44216", "44222", "44223", "44224", "44225", "44229", "44232", "44233", "44237", "44239", "44241", "44242", "44246", "44252", "44254", "44259", "44261", "44263", "44264", "44267", "44270", "44271", "44274", "44275", "44276", "44280", "44281", "44282", "44283", "44284", "44285", "44286", "44287", "44291", "44292", "44293", "44295", "44297", "44298", "44299", "44301", "44302", "44303", "44306", "44307", "44308", "44309", "44310", "44311", "44313", "44315", "44319", "44320", "44321", "44325", "44326", "44328", "44334", "44336", "44338", "44340", "44341", "44342", "44343", "44346", "44347", "44353", "44355", "44359", "44360", "44361", "44362", "44364", "44367", "44368", "44369", "44371", "44372", "44373", "44377", "44379", "44380", "44383", "44386", "44387", "44389", "44391", "44393", "44394", "44398", "44401", "44402", "44403", "44404", "44406", "44407", "44409", "44411", "44414", "44416", "44417", "44419", "44421", "44425", "44426", "44433", "44436", "44437", "44440", "44442", "44445", "44447", "44448", "44451", "44452", "44457", "44461", "44462", "44463", "44464", "44466", "44469", "44471", "44472", "44474", "44479", "44480", "44482", "44483", "44484", "44486", "44491", "44492", "44496", "44497", "44498", "44500", "44502", "44506", "44508", "44509", "44510", "44511", "44514", "44516", "44520", "44522", "44523", "44524", "44529", "44531", "44535", "44537", "44538", "44539", "44540", "44542", "44543", "44552", "44553", "44554", "44555", "44556", "44559", "44561", "44563", "44565", "44566", "44567", "44569", "44571", "44572", "44576", "44577", "44580", "44582", "44585", "44586", "44587", "44588", "44591", "44594", "44596", "44597", "44598", "44599", "44600", "44601", "44604", "44605", "44608", "44609", "44610", "44612", "44615", "44616", "44622", "44624", "44626", "44627", "44633", "44635", "44638", "44639", "44642", "44646", "44649", "44650", "44651", "44652", "44654", "44655", "44656", "44657", "44660", "44661", "44663", "44666", "44668", "44669", "44671", "44675", "44678", "44680", "44681", "44682", "44684", "44685", "44686", "44687", "44688", "44689", "44691", "44692", "44693", "44695", "44696", "44697", "44698", "44702", "44703", "44705", "44706", "44707", "44710", "44713", "44714", "44717", "44719", "44720", "44721", "44726", "44727", "44728", "44729", "44733", "44735", "44739", "44741", "44745", "44746", "44748", "44750", "44752", "44753", "44754", "44755", "44757", "44759", "44760", "44763", "44766", "44767", "44768", "44769", "44770", "44772", "44773", "44776", "44777", "44778", "44779", "44783", "44784", "44785", "44787", "44788", "44789", "44790", "44792", "44793", "44794", "44795", "44796", "44797", "44801", "44805", "44809", "44810", "44811", "44812", "44813", "44814", "44818", "44819", "44820", "44823", "44825", "44826", "44827", "44830", "44832", "44835", "44836", "44838", "44839", "44842", "44843", "44844", "44846", "44851", "44854", "44856", "44857", "44858", "44861", "44866", "44867", "44868", "44870", "44872", "44873", "44878", "44880", "44881", "44882", "44885", "44888", "44889", "44890", "44891", "44892", "44894", "44895", "44898", "44900", "44903", "44904", "44905", "44907", "44909", "44910", "44914", "44915", "44916", "44918", "44919", "44920", "44922", "44923", "44924", "44925", "44926", "44930", "44931", "44935", "44939", "44942", "44945", "44946", "44947", "44948", "44951", "44952", "44953", "44954", "44955", "44956", "44957", "44958", "44959", "44960", "44963", "44964", "44968", "44969", "44974", "44975", "44976", "44977", "44978", "44979", "44980", "44981", "44984", "44985", "44987", "44988", "44991", "44996", "44998", "44999", "45002", "45005", "45006", "45008", "45010", "45012", "45013", "45014", "45016", "45017", "45018", "45023", "45024", "45026", "45028", "45029", "45036", "45038", "45042", "45043", "45046", "45047", "45048", "45050", "45053", "45054", "45056", "45058", "45059", "45060", "45061", "45064", "45066", "45070", "45071", "45074", "45075", "45076", "45077", "45078", "45079", "45080", "45082", "45083", "45087", "45088", "45089", "45090", "45091", "45092", "45093", "45095", "45096", "45098", "45099", "45101", "45103", "45110", "45111", "45112", "45114", "45116", "45120", "45121", "45123", "45128", "45130", "45131", "45132", "45134", "45137", "45138", "45139", "45142", "45144", "45145", "45146", "45147", "45150", "45151", "45152", "45153", "45154", "45155", "45157", "45158", "45163", "45164", "45167", "45177", "45180", "45183", "45188", "45190", "45192", "45196", "45197", "45199", "45200", "45202", "45204", "45205", "45212", "45214", "45217", "45219", "45227", "45230", "45231", "45232", "45233", "45234", "45236", "45238", "45239", "45241", "45242", "45244", "45245", "45246", "45247", "45249", "45250", "45252", "45253", "45254", "45255", "45256", "45257", "45258", "45259", "45269", "45270", "45271", "45274", "45276", "45277", "45279", "45280", "45285", "45286", "45290", "45292", "45293", "45295", "45298", "45299", "45301", "45302", "45303", "45304", "45305", "45307", "45309", "45310", "45314", "45315", "45326", "45327", "45329", "45330", "45337", "45339", "45340", "45341", "45348", "45349", "45351", "45354", "45355", "45358", "45360", "45363", "45364", "45367", "45368", "45371", "45372", "45375", "45377", "45379", "45381", "45382", "45386", "45387", "45391", "45392", "45393", "45396", "45398", "45400", "45403", "45404", "45405", "45409", "45413", "45418", "45419", "45420", "45421", "45424", "45426", "45429", "45431", "45433", "45439", "45441", "45447", "45448", "45450", "45452", "45454", "45455", "45456", "45458", "45460", "45461", "45462", "45464", "45465", "45466", "45469", "45470", "45471", "45474", "45476", "45477", "45479", "45484", "45485", "45487", "45488", "45489", "45492", "45493", "45495", "45497", "45501", "45504", "45507", "45508", "45510", "45511", "45512", "45516", "45517", "45520", "45523", "45526", "45527", "45529", "45530", "45532", "45533", "45534", "45536", "45537", "45538", "45540", "45543", "45544", "45547", "45549", "45550", "45553", "45554", "45555", "45557", "45560", "45561", "45562", "45563", "45565", "45566", "45567", "45571", "45572", "45574", "45576", "45577", "45578", "45580", "45582", "45585", "45586", "45587", "45589", "45590", "45592", "45594", "45597", "45599", "45601", "45602", "45603", "45606", "45607", "45608", "45611", "45612", "45614", "45615", "45620", "45621", "45622", "45623", "45626", "45627", "45628", "45630", "45632", "45633", "45637", "45638", "45641", "45643", "45644", "45645", "45647", "45648", "45650", "45651", "45654", "45655", "45656", "45658", "45659", "45662", "45663", "45664", "45666", "45668", "45672", "45673", "45676", "45678", "45680", "45683", "45686", "45687", "45689", "45690", "45693", "45694", "45695", "45699", "45700", "45703", "45705", "45706", "45709", "45712", "45715", "45716", "45718", "45722", "45724", "45727", "45728", "45729", "45730", "45731", "45741", "45742", "45746", "45747", "45749", "45750", "45751", "45752", "45755", "45759", "45763", "45768", "45769", "45770", "45772", "45774", "45775", "45777", "45778", "45779", "45781", "45785", "45786", "45789", "45790", "45791", "45792", "45794", "45795", "45796", "45797", "45802", "45804", "45805", "45807", "45809", "45810", "45811", "45812", "45815", "45816", "45818", "45819", "45821", "45824", "45826", "45827", "45828", "45829", "45831", "45832", "45833", "45835", "45838", "45839", "45840", "45842", "45843", "45844", "45845", "45846", "45847", "45850", "45857", "45859", "45863", "45865", "45866", "45867", "45869", "45870", "45871", "45874", "45876", "45877", "45879", "45882", "45883", "45884", "45889", "45891", "45896", "45897", "45898", "45900", "45902", "45903", "45905", "45908", "45910", "45915", "45916", "45921", "45923", "45924", "45926", "45927", "45931", "45932", "45933", "45934", "45937", "45938", "45939", "45945", "45946", "45947", "45948", "45952", "45956", "45957", "45958", "45960", "45963", "45967", "45968", "45970", "45972", "45974", "45976", "45978", "45979", "45986", "45989", "45991", "45992", "45994", "45997", "45998", "46000", "46001", "46002", "46003", "46004", "46005", "46006", "46008", "46009", "46010", "46012", "46013", "46014", "46020", "46023", "46024", "46026", "46027", "46028", "46033", "46034", "46036", "46037", "46038", "46039", "46042", "46043", "46044", "46045", "46047", "46048", "46050", "46051", "46052", "46055", "46056", "46058", "46060", "46064", "46066", "46069", "46070", "46072", "46073", "46074", "46075", "46076", "46077", "46078", "46082", "46085", "46089", "46091", "46092", "46094", "46095", "46097", "46098", "46099", "46100", "46101", "46106", "46112", "46114", "46115", "46118", "46120", "46121", "46122", "46124", "46127", "46128", "46129", "46131", "46133", "46134", "46136", "46139", "46140", "46145", "46146", "46147", "46149", "46150", "46153", "46155", "46156", "46157", "46158", "46159", "46161", "46162", "46164", "46165", "46167", "46168", "46169", "46177", "46178", "46180", "46181", "46182", "46185", "46186", "46187", "46188", "46191", "46193", "46196", "46199", "46200", "46202", "46203", "46204", "46205", "46212", "46216", "46217", "46219", "46220", "46221", "46223", "46224", "46225", "46227", "46228", "46230", "46233", "46234", "46235", "46236", "46238", "46243", "46246", "46247", "46248", "46249", "46253", "46254", "46255", "46259", "46260", "46263", "46265", "46270", "46272", "46274", "46275", "46277", "46279", "46286", "46289", "46290", "46292", "46293", "46295", "46302", "46305", "46306", "46307", "46308", "46311", "46312", "46313", "46314", "46315", "46316", "46317", "46318", "46319", "46320", "46326", "46327", "46329", "46331", "46333", "46335", "46336", "46338", "46339", "46340", "46341", "46343", "46348", "46349", "46352", "46353", "46355", "46356", "46358", "46359", "46360", "46361", "46364", "46365", "46368", "46370", "46371", "46372", "46373", "46375", "46380", "46381", "46384", "46385", "46393", "46395", "46397", "46398", "46401", "46402", "46403", "46404", "46407", "46409", "46411", "46416", "46417", "46418", "46420", "46422", "46424", "46426", "46427", "46430", "46431", "46432", "46436", "46437", "46438", "46441", "46443", "46446", "46447", "46449", "46450", "46451", "46452", "46453", "46454", "46456", "46457", "46458", "46461", "46462", "46465", "46470", "46472", "46474", "46476", "46477", "46480", "46481", "46482", "46483", "46489", "46494", "46496", "46498", "46500", "46503", "46504", "46506", "46507", "46508", "46509", "46510", "46515", "46516", "46521", "46522", "46523", "46524", "46525", "46528", "46530", "46531", "46532", "46533", "46534", "46535", "46537", "46539", "46540", "46541", "46542", "46543", "46547", "46548", "46549", "46551", "46552", "46553", "46555", "46557", "46559", "46562", "46563", "46565", "46566", "46567", "46569", "46574", "46575", "46577", "46585", "46586", "46587", "46589", "46590", "46593", "46594", "46598", "46601", "46602", "46606", "46608", "46610", "46612", "46613", "46615", "46616", "46617", "46618", "46619", "46620", "46621", "46622", "46623", "46624", "46631", "46632", "46638", "46641", "46643", "46645", "46650", "46651", "46653", "46654", "46655", "46658", "46661", "46663", "46669", "46671", "46674", "46675", "46676", "46678", "46679", "46681", "46683", "46684", "46685", "46686", "46694", "46695", "46699", "46700", "46703", "46705", "46707", "46710", "46712", "46713", "46720", "46723", "46728", "46731", "46734", "46739", "46742", "46747", "46748", "46750", "46751", "46753", "46755", "46756", "46757", "46758", "46761", "46763", "46764", "46767", "46768", "46769", "46772", "46775", "46778", "46780", "46783", "46784", "46785", "46786", "46789", "46790", "46792", "46794", "46795", "46798", "46800", "46801", "46804", "46807", "46810", "46813", "46814", "46819", "46820", "46821", "46822", "46824", "46826", "46827", "46828", "46830", "46831", "46832", "46835", "46836", "46838", "46839", "46840", "46841", "46842", "46843", "46844", "46847", "46848", "46849", "46854", "46855", "46856", "46858", "46863", "46864", "46868", "46869", "46870", "46872", "46873", "46876", "46880", "46881", "46882", "46884", "46886", "46887", "46888", "46889", "46890", "46891", "46893", "46896", "46899", "46902", "46903", "46906", "46907", "46908", "46912", "46913", "46915", "46917", "46919", "46920", "46921", "46922", "46923", "46924", "46926", "46927", "46930", "46931", "46932", "46933", "46935", "46937", "46938", "46941", "46942", "46944", "46947", "46950", "46951", "46954", "46955", "46956", "46957", "46960", "46963", "46966", "46967", "46968", "46971", "46972", "46975", "46978", "46979", "46983", "46988", "46989", "46991", "46996", "46997", "47001", "47002", "47004", "47007", "47008", "47009", "47011", "47012", "47014", "47015", "47016", "47017", "47019", "47021", "47027", "47029", "47030", "47034", "47035", "47037", "47040", "47042", "47043", "47044", "47047", "47051", "47052", "47053", "47055", "47063", "47064", "47066", "47068", "47069", "47070", "47071", "47075", "47076", "47078", "47079", "47081", "47084", "47085", "47086", "47088", "47092", "47093", "47095", "47096", "47099", "47100", "47102", "47105", "47107", "47108", "47109", "47113", "47119", "47120", "47121", "47124", "47125", "47127", "47128", "47130", "47131", "47133", "47135", "47138", "47139", "47140", "47144", "47145", "47147", "47149", "47150", "47152", "47155", "47156", "47157", "47158", "47163", "47164", "47165", "47166", "47168", "47169", "47170", "47171", "47172", "47173", "47177", "47178", "47179", "47184", "47185", "47186", "47188", "47190", "47193", "47196", "47198", "47199", "47200", "47201", "47205", "47213", "47214", "47219", "47221", "47222", "47226", "47227", "47230", "47231", "47233", "47234", "47238", "47239", "47240", "47242", "47243", "47244", "47245", "47246", "47247", "47250", "47257", "47258", "47261", "47269", "47271", "47272", "47273", "47279", "47282", "47285", "47287", "47288", "47290", "47291", "47293", "47297", "47298", "47299", "47300", "47305", "47306", "47309", "47311", "47312", "47314", "47315", "47317", "47320", "47321", "47325", "47329", "47330", "47331", "47333", "47334", "47336", "47338", "47340", "47341", "47342", "47343", "47344", "47345", "47346", "47348", "47349", "47353", "47354", "47355", "47356", "47359", "47360", "47362", "47363", "47364", "47368", "47369", "47370", "47371", "47372", "47373", "47375", "47378", "47379", "47380", "47384", "47385", "47386", "47388", "47390", "47391", "47392", "47395", "47396", "47397", "47401", "47402", "47403", "47404", "47407", "47408", "47410", "47411", "47418", "47419", "47420", "47422", "47425", "47426", "47427", "47433", "47436", "47437", "47438", "47440", "47442", "47443", "47446", "47447", "47449", "47450", "47451", "47456", "47457", "47458", "47460", "47467", "47470", "47473", "47476", "47477", "47478", "47484", "47488", "47489", "47491", "47495", "47496", "47502", "47503", "47507", "47509", "47510", "47511", "47514", "47515", "47516", "47519", "47520", "47523", "47524", "47525", "47526", "47528", "47531", "47535", "47536", "47537", "47539", "47540", "47541", "47543", "47544", "47545", "47546", "47548", "47549", "47550", "47551", "47554", "47555", "47558", "47559", "47560", "47562", "47563", "47564", "47566", "47567", "47568", "47569", "47572", "47573", "47579", "47581", "47582", "47583", "47587", "47589", "47593", "47595", "47597", "47598", "47599", "47604", "47605", "47606", "47608", "47609", "47610", "47611", "47614", "47615", "47618", "47620", "47624", "47625", "47626", "47627", "47632", "47634", "47635", "47637", "47639", "47645", "47646", "47647", "47649", "47651", "47654", "47657", "47658", "47659", "47660", "47662", "47664", "47665", "47666", "47669", "47674", "47678", "47680", "47682", "47687", "47688", "47689", "47693", "47694", "47695", "47698", "47699", "47700", "47701", "47702", "47704", "47708", "47709", "47712", "47715", "47717", "47719", "47722", "47723", "47731", "47733", "47735", "47736", "47737", "47738", "47739", "47742", "47743", "47745", "47746", "47748", "47755", "47756", "47759", "47761", "47762", "47763", "47765", "47767", "47770", "47771", "47772", "47773", "47774", "47775", "47776", "47777", "47778", "47786", "47787", "47788", "47789", "47790", "47791", "47792", "47795", "47797", "47800", "47802", "47804", "47807", "47808", "47810", "47819", "47821", "47825", "47826", "47827", "47828", "47829", "47834", "47835", "47836", "47839", "47840", "47855", "47856", "47859", "47861", "47862", "47865", "47867", "47868", "47869", "47870", "47871", "47874", "47875", "47877", "47878", "47881", "47882", "47883", "47884", "47887", "47889", "47890", "47891", "47892", "47893", "47895", "47896", "47900", "47901", "47902", "47905", "47906", "47915", "47916", "47919", "47920", "47921", "47923", "47924", "47925", "47928", "47929", "47933", "47934", "47935", "47938", "47941", "47943", "47944", "47945", "47948", "47950", "47951", "47952", "47954", "47955", "47956", "47957", "47958", "47959", "47962", "47970", "47971", "47973", "47975", "47976", "47979", "47980", "47982", "47984", "47985", "47986", "47987", "47988", "47989", "47996", "47998", "47999", "48000", "48003", "48006", "48007", "48011", "48014", "48015", "48016", "48017", "48018", "48020", "48021", "48022", "48024", "48025", "48026", "48027", "48029", "48031", "48032", "48033", "48035", "48036", "48041", "48042", "48043", "48045", "48046", "48048", "48050", "48051", "48058", "48063", "48064", "48065", "48066", "48067", "48071", "48073", "48074", "48076", "48077", "48080", "48081", "48082", "48085", "48089", "48090", "48096", "48097", "48098", "48099", "48102", "48104", "48106", "48107", "48108", "48109", "48111", "48117", "48118", "48119", "48121", "48123", "48125", "48127", "48131", "48134", "48137", "48139", "48142", "48143", "48145", "48147", "48149", "48150", "48152", "48155", "48159", "48160", "48168", "48169", "48171", "48172", "48173", "48174", "48176", "48180", "48182", "48184", "48185", "48186", "48188", "48189", "48190", "48191", "48192", "48193", "48196", "48198", "48199", "48204", "48208", "48211", "48212", "48213", "48215", "48217", "48218", "48220", "48221", "48222", "48224", "48229", "48232", "48234", "48235", "48236", "48238", "48239", "48240", "48242", "48247", "48248", "48249", "48250", "48254", "48256", "48257", "48260", "48263", "48265", "48267", "48268", "48270", "48275", "48278", "48279", "48281", "48283", "48284", "48286", "48287", "48290", "48293", "48294", "48297", "48301", "48303", "48304", "48307", "48309", "48310", "48312", "48316", "48318", "48321", "48322", "48323", "48324", "48327", "48329", "48334", "48336", "48338", "48341", "48343", "48344", "48345", "48347", "48360", "48362", "48363", "48364", "48365", "48366", "48367", "48375", "48376", "48377", "48379", "48381", "48384", "48385", "48386", "48387", "48390", "48391", "48392", "48393", "48394", "48397", "48398", "48399", "48402", "48403", "48405", "48407", "48410", "48411", "48414", "48415", "48417", "48418", "48422", "48423", "48424", "48425", "48426", "48427", "48428", "48433", "48434", "48435", "48438", "48440", "48443", "48445", "48446", "48447", "48449", "48455", "48457", "48460", "48461", "48463", "48465", "48467", "48468", "48469", "48471", "48473", "48474", "48478", "48483", "48485", "48487", "48488", "48490", "48491", "48492", "48493", "48494", "48497", "48498", "48503", "48505", "48507", "48510", "48512", "48514", "48517", "48520", "48521", "48525", "48527", "48530", "48544", "48545", "48547", "48548", "48549", "48550", "48552", "48554", "48555", "48557", "48558", "48560", "48561", "48562", "48563", "48564", "48565", "48569", "48571", "48579", "48580", "48583", "48586", "48587", "48588", "48589", "48592", "48594", "48597", "48599", "48600", "48603", "48604", "48607", "48615", "48617", "48618", "48620", "48621", "48624", "48625", "48626", "48627", "48630", "48631", "48633", "48635", "48636", "48638", "48639", "48642", "48644", "48646", "48648", "48649", "48650", "48651", "48653", "48656", "48659", "48660", "48662", "48664", "48665", "48668", "48669", "48670", "48671", "48673", "48674", "48675", "48676", "48677", "48679", "48681", "48682", "48683", "48684", "48685", "48686", "48688", "48690", "48694", "48696", "48697", "48698", "48699", "48700", "48701", "48702", "48703", "48705", "48706", "48708", "48709", "48710", "48711", "48712", "48714", "48718", "48720", "48724", "48730", "48732", "48733", "48735", "48736", "48737", "48738", "48739", "48741", "48743", "48746", "48750", "48753", "48754", "48756", "48757", "48758", "48759", "48764", "48765", "48772", "48773", "48774", "48775", "48776", "48778", "48779", "48785", "48788", "48790", "48791", "48792", "48794", "48797", "48798", "48800", "48801", "48802", "48803", "48804", "48814", "48817", "48818", "48820", "48821", "48823", "48824", "48826", "48828", "48835", "48837", "48840", "48841", "48842", "48843", "48844", "48847", "48851", "48853", "48854", "48855", "48857", "48859", "48860", "48861", "48862", "48863", "48867", "48871", "48872", "48873", "48875", "48877", "48878", "48879", "48880", "48881", "48883", "48884", "48886", "48887", "48888", "48890", "48891", "48893", "48895", "48897", "48898", "48900", "48901", "48904", "48905", "48906", "48907", "48909", "48911", "48913", "48915", "48919", "48921", "48925", "48927", "48929", "48931", "48934", "48936", "48941", "48942", "48944", "48946", "48947", "48949", "48950", "48953", "48955", "48957", "48959", "48961", "48962", "48964", "48967", "48969", "48970", "48972", "48973", "48974", "48976", "48979", "48980", "48983", "48984", "48985", "48989", "48990", "48992", "48994", "48995", "48996", "48997", "48998", "49000", "49001", "49004", "49005", "49006", "49008", "49009", "49010", "49011", "49013", "49014", "49019", "49020", "49022", "49023", "49024", "49025", "49026", "49027", "49029", "49030", "49034", "49035", "49036", "49037", "49038", "49039", "49042", "49043", "49044", "49045", "49047", "49049", "49050", "49051", "49052", "49054", "49056", "49059", "49060", "49061", "49065", "49067", "49068", "49069", "49070", "49074", "49075", "49076", "49077", "49078", "49080", "49081", "49082", "49089", "49091", "49092", "49093", "49095", "49096", "49098", "49099", "49101", "49102", "49103", "49104", "49106", "49108", "49109", "49114", "49115", "49118", "49119", "49120", "49122", "49123", "49125", "49126", "49127", "49128", "49129", "49130", "49132", "49133", "49137", "49139", "49141", "49143", "49145", "49146", "49148", "49149", "49150", "49151", "49152", "49154", "49155", "49158", "49159", "49161", "49163", "49164", "49166", "49167", "49168", "49169", "49172", "49176", "49179", "49180", "49181", "49182", "49184", "49185", "49186", "49190", "49196", "49197", "49199", "49202", "49203", "49206", "49208", "49209", "49210", "49211", "49212", "49213", "49214", "49215", "49218", "49220", "49221", "49223", "49226", "49229", "49231", "49235", "49237", "49239", "49246", "49247", "49249", "49251", "49253", "49255", "49257", "49259", "49260", "49270", "49276", "49277", "49278", "49279", "49281", "49287", "49288", "49290", "49292", "49294", "49296", "49297", "49300", "49302", "49307", "49308", "49310", "49313", "49316", "49320", "49327", "49328", "49329", "49332", "49334", "49336", "49337", "49340", "49341", "49342", "49346", "49347", "49348", "49350", "49352", "49354", "49356", "49357", "49358", "49359", "49360", "49362", "49364", "49365", "49366", "49368", "49370", "49372", "49375", "49377", "49379", "49382", "49384", "49385", "49386", "49387", "49388", "49390", "49391", "49395", "49396", "49397", "49399", "49401", "49403", "49404", "49405", "49406", "49407", "49408", "49412", "49415", "49418", "49419", "49420", "49421", "49424", "49425", "49426", "49428", "49429", "49430", "49431", "49432", "49435", "49438", "49444", "49446", "49450", "49451", "49453", "49454", "49457", "49458", "49459", "49460", "49461", "49463", "49464", "49466", "49467", "49469", "49470", "49473", "49474", "49475", "49476", "49480", "49481", "49482", "49483", "49485", "49487", "49488", "49489", "49490", "49491", "49493", "49498", "49499", "49501", "49502", "49505", "49507", "49508", "49510", "49511", "49512", "49513", "49514", "49517", "49519", "49521", "49522", "49523", "49525", "49530", "49531", "49533", "49534", "49535", "49537", "49540", "49541", "49542", "49549", "49550", "49553", "49554", "49555", "49562", "49563", "49566", "49567", "49569", "49570", "49572", "49573", "49574", "49575", "49576", "49578", "49579", "49580", "49582", "49583", "49585", "49587", "49591", "49594", "49595", "49599", "49601", "49602", "49603", "49607", "49610", "49612", "49613", "49617", "49619", "49623", "49626", "49631", "49634", "49635", "49638", "49639", "49640", "49648", "49649", "49650", "49651", "49652", "49653", "49655", "49656", "49658", "49659", "49660", "49661", "49663", "49664", "49665", "49668", "49675", "49676", "49678", "49681", "49682", "49684", "49685", "49688", "49693", "49698", "49701", "49704", "49705", "49706", "49707", "49709", "49710", "49711", "49713", "49717", "49718", "49720", "49721", "49722", "49723", "49725", "49726", "49728", "49729", "49730", "49731", "49733", "49734", "49735", "49737", "49740", "49742", "49745", "49747", "49748", "49750", "49751", "49752", "49759", "49760", "49761", "49762", "49763", "49766", "49767", "49768", "49770", "49771", "49772", "49773", "49774", "49776", "49777", "49779", "49780", "49782", "49785", "49786", "49789", "49790", "49791", "49792", "49793", "49794", "49797", "49798", "49801", "49802", "49803", "49805", "49806", "49808", "49817", "49819", "49820", "49822", "49823", "49824", "49826", "49827", "49829", "49830", "49833", "49834", "49836", "49837", "49838", "49844", "49847", "49848", "49851", "49852", "49854", "49855", "49856", "49858", "49859", "49862", "49863", "49865", "49867", "49869", "49871", "49873", "49874", "49877", "49880", "49883", "49884", "49886", "49888", "49892", "49894", "49895", "49896", "49899", "49900", "49902", "49903", "49904", "49909", "49910", "49911", "49913", "49914", "49917", "49920", "49922", "49926", "49927", "49930", "49931", "49932", "49934", "49937", "49938", "49940", "49942", "49943", "49945", "49946", "49950", "49951", "49952", "49955", "49959", "49960", "49961", "49965", "49970", "49971", "49973", "49974", "49976", "49977", "49978", "49981", "49982", "49983", "49984", "49990", "49992", "49996", "49997", "49999", "50001", "50003", "50004", "50006", "50009", "50010", "50012", "50013", "50014", "50016", "50017", "50019", "50020", "50021", "50023", "50024", "50025", "50026", "50027", "50028", "50030", "50031", "50035", "50036", "50043", "50044", "50046", "50047", "50049", "50055", "50058", "50059", "50060", "50062", "50063", "50064", "50065", "50066", "50068", "50072", "50073", "50074", "50075", "50076", "50078", "50079", "50080", "50081", "50090", "50091", "50094", "50096", "50101", "50104", "50114", "50119", "50120", "50123", "50125", "50130", "50132", "50134", "50140", "50141", "50142", "50144", "50146", "50147", "50151", "50152", "50153", "50155", "50156", "50158", "50159", "50161", "50162", "50164", "50165", "50166", "50167", "50169", "50171", "50175", "50177", "50178", "50179", "50180", "50181", "50184", "50185", "50188", "50189", "50192", "50194", "50196", "50198", "50199", "50200", "50201", "50203", "50204", "50205", "50208", "50209", "50210", "50212", "50214", "50215", "50216", "50219", "50220", "50221", "50223", "50225", "50227", "50228", "50233", "50235", "50238", "50239", "50240", "50241", "50242", "50244", "50245", "50246", "50248", "50249", "50250", "50251", "50252", "50255", "50256", "50257", "50259", "50264", "50265", "50266", "50269", "50271", "50272", "50273", "50275", "50276", "50281", "50283", "50284", "50285", "50287", "50292", "50294", "50295", "50296", "50297", "50299", "50300", "50301", "50302", "50304", "50305", "50306", "50308", "50309", "50310", "50313", "50314", "50315", "50318", "50319", "50321", "50322", "50324", "50326", "50327", "50328", "50331", "50332", "50334", "50336", "50339", "50343", "50345", "50346", "50347", "50349", "50350", "50351", "50353", "50355", "50357", "50358", "50362", "50363", "50364", "50366", "50373", "50374", "50375", "50376", "50377", "50379", "50381", "50383", "50386", "50388", "50390", "50392", "50394", "50396", "50401", "50405", "50410", "50412", "50413", "50414", "50416", "50417", "50418", "50420", "50421", "50422", "50423", "50425", "50427", "50429", "50430", "50432", "50436", "50440", "50441", "50442", "50444", "50445", "50447", "50448", "50449", "50450", "50451", "50452", "50453", "50455", "50457", "50458", "50460", "50462", "50463", "50464", "50466", "50467", "50468", "50470", "50472", "50473", "50474", "50476", "50479", "50481", "50484", "50486", "50488", "50489", "50490", "50493", "50495", "50496", "50497", "50498", "50500", "50505", "50508", "50512", "50518", "50519", "50520", "50521", "50522", "50523", "50531", "50532", "50534", "50536", "50537", "50539", "50544", "50548", "50555", "50559", "50568", "50569", "50573", "50574", "50576", "50579", "50580", "50581", "50582", "50583", "50585", "50586", "50588", "50589", "50593", "50594", "50595", "50600", "50601", "50603", "50604", "50606", "50611", "50612", "50613", "50614", "50616", "50622", "50623", "50627", "50628", "50629", "50631", "50633", "50634", "50635", "50637", "50638", "50639", "50640", "50641", "50645", "50649", "50652", "50653", "50656", "50657", "50658", "50659", "50660", "50662", "50663", "50665", "50666", "50668", "50670", "50672", "50673", "50674", "50676", "50677", "50678", "50681", "50684", "50685", "50686", "50687", "50690", "50696", "50698", "50699", "50701", "50702", "50703", "50704", "50705", "50707", "50711", "50717", "50718", "50720", "50722", "50723", "50724", "50725", "50727", "50729", "50730", "50735", "50736", "50737", "50738", "50740", "50742", "50743", "50744", "50747", "50749", "50750", "50751", "50752", "50753", "50755", "50756", "50759", "50760", "50762", "50764", "50765", "50769", "50770", "50771", "50772", "50776", "50777", "50778", "50779", "50780", "50783", "50785", "50786", "50788", "50792", "50794", "50797", "50800", "50801", "50803", "50805", "50809", "50811", "50816", "50818", "50819", "50820", "50821", "50824", "50825", "50827", "50829", "50831", "50832", "50834", "50835", "50836", "50837", "50838", "50839", "50843", "50844", "50846", "50847", "50848", "50849", "50851", "50856", "50857", "50858", "50859", "50860", "50862", "50864", "50866", "50870", "50873", "50875", "50876", "50877", "50879", "50883", "50884", "50887", "50889", "50890", "50891", "50894", "50896", "50898", "50900", "50903", "50904", "50908", "50909", "50912", "50913", "50915", "50919", "50922", "50929", "50930", "50933", "50935", "50937", "50938", "50940", "50943", "50944", "50945", "50946", "50947", "50948", "50949", "50951", "50954", "50956", "50957", "50958", "50959", "50962", "50963", "50966", "50967", "50972", "50973", "50974", "50977", "50978", "50980", "50982", "50983", "50985", "50989", "50990", "50995", "50998", "50999", "51001", "51002", "51005", "51006", "51007", "51008", "51012", "51015", "51016", "51017", "51018", "51019", "51020", "51022", "51025", "51026", "51027", "51028", "51029", "51030", "51033", "51034", "51036", "51041", "51043", "51044", "51046", "51050", "51052", "51054", "51056", "51059", "51061", "51062", "51064", "51066", "51067", "51068", "51069", "51071", "51072", "51077", "51080", "51081", "51085", "51088", "51091", "51093", "51095", "51098", "51099", "51100", "51101", "51102", "51103", "51105", "51108", "51109", "51111", "51112", "51113", "51116", "51117", "51118", "51120", "51121", "51122", "51126", "51129", "51130", "51133", "51134", "51135", "51136", "51137", "51138", "51140", "51141", "51143", "51144", "51148", "51151", "51153", "51158", "51160", "51161", "51164", "51165", "51169", "51170", "51173", "51174", "51176", "51177", "51179", "51182", "51183", "51184", "51187", "51189", "51190", "51192", "51195", "51196", "51197", "51198", "51200", "51201", "51202", "51203", "51204", "51206", "51208", "51211", "51212", "51213", "51214", "51216", "51217", "51219", "51220", "51222", "51224", "51228", "51229", "51231", "51233", "51234", "51236", "51238", "51241", "51242", "51243", "51247", "51248", "51249", "51252", "51253", "51254", "51256", "51258", "51260", "51262", "51263", "51265", "51266", "51267", "51269", "51272", "51273", "51274", "51275", "51276", "51281", "51282", "51283", "51284", "51287", "51288", "51293", "51297", "51301", "51302", "51303", "51304", "51306", "51308", "51309", "51319", "51324", "51325", "51326", "51327", "51329", "51331", "51334", "51337", "51338", "51339", "51341", "51342", "51346", "51348", "51349", "51355", "51356", "51358", "51363", "51364", "51367", "51369", "51370", "51371", "51372", "51374", "51375", "51376", "51377", "51379", "51380", "51381", "51382", "51383", "51384", "51385", "51386", "51387", "51390", "51391", "51392", "51396", "51408", "51409", "51412", "51415", "51417", "51419", "51421", "51422", "51423", "51424", "51426", "51427", "51428", "51429", "51431", "51432", "51437", "51439", "51441", "51443", "51445", "51446", "51448", "51449", "51451", "51452", "51454", "51456", "51457", "51458", "51459", "51460", "51461", "51462", "51463", "51466", "51470", "51474", "51475", "51477", "51480", "51481", "51483", "51485", "51486", "51488", "51490", "51491", "51493", "51494", "51500", "51501", "51502", "51504", "51509", "51510", "51512", "51514", "51515", "51519", "51520", "51527", "51528", "51530", "51533", "51535", "51536", "51537", "51540", "51542", "51543", "51544", "51545", "51548", "51550", "51551", "51552", "51553", "51554", "51555", "51558", "51559", "51561", "51562", "51563", "51566", "51567", "51568", "51570", "51572", "51573", "51575", "51576", "51578", "51579", "51580", "51581", "51584", "51588", "51590", "51591", "51594", "51595", "51597", "51601", "51603", "51604", "51607", "51611", "51613", "51614", "51615", "51621", "51625", "51627", "51629", "51632", "51633", "51634", "51638", "51640", "51648", "51649", "51650", "51651", "51653", "51655", "51657", "51659", "51662", "51665", "51666", "51667", "51668", "51671", "51674", "51676", "51677", "51678", "51681", "51682", "51683", "51686", "51687", "51688", "51689", "51691", "51693", "51694", "51696", "51697", "51699", "51700", "51701", "51703", "51707", "51711", "51713", "51715", "51718", "51719", "51720", "51722", "51725", "51726", "51731", "51736", "51743", "51745", "51746", "51747", "51749", "51750", "51751", "51752", "51753", "51754", "51757", "51758", "51759", "51764", "51765", "51766", "51767", "51768", "51773", "51775", "51776", "51777", "51778", "51781", "51782", "51783", "51784", "51789", "51791", "51793", "51794", "51797", "51798", "51800", "51803", "51804", "51807", "51811", "51812", "51814", "51815", "51816", "51818", "51819", "51821", "51824", "51825", "51826", "51828", "51829", "51831", "51833", "51835", "51836", "51837", "51839", "51840", "51842", "51846", "51849", "51853", "51855", "51856", "51857", "51860", "51861", "51866", "51868", "51869", "51870", "51871", "51872", "51875", "51876", "51877", "51878", "51881", "51882", "51884", "51885", "51887", "51888", "51891", "51894", "51895", "51898", "51901", "51902", "51903", "51904", "51908", "51909", "51910", "51915", "51919", "51921", "51922", "51926", "51928", "51929", "51930", "51931", "51933", "51936", "51937", "51938", "51939", "51940", "51941", "51943", "51946", "51951", "51952", "51957", "51958", "51961", "51963", "51965", "51976", "51978", "51979", "51980", "51981", "51988", "51989", "51991", "51992", "51993", "51994", "51995", "51997", "51998", "51999", "52000", "52007", "52012", "52013", "52014", "52015", "52018", "52019", "52028", "52029", "52031", "52034", "52035", "52036", "52037", "52038", "52039", "52041", "52042", "52043", "52044", "52047", "52048", "52050", "52051", "52052", "52053", "52056", "52062", "52063", "52069", "52070", "52072", "52076", "52079", "52080", "52081", "52082", "52084", "52085", "52086", "52087", "52090", "52091", "52092", "52093", "52094", "52095", "52097", "52098", "52101", "52102", "52106", "52107", "52108", "52109", "52110", "52111", "52115", "52118", "52120", "52122", "52125", "52128", "52129", "52130", "52134", "52135", "52136", "52137", "52139", "52140", "52142", "52144", "52145", "52146", "52150", "52153", "52154", "52157", "52164", "52165", "52167", "52169", "52174", "52176", "52181", "52185", "52186", "52189", "52190", "52193", "52194", "52195", "52196", "52197", "52198", "52200", "52201", "52204", "52205", "52206", "52208", "52209", "52211", "52214", "52215", "52217", "52218", "52219", "52222", "52224", "52228", "52230", "52232", "52234", "52235", "52236", "52242", "52243", "52244", "52247", "52255", "52257", "52258", "52259", "52260", "52261", "52263", "52265", "52266", "52268", "52269", "52270", "52272", "52275", "52277", "52279", "52284", "52285", "52288", "52290", "52293", "52294", "52296", "52297", "52298", "52299", "52301", "52302", "52304", "52305", "52306", "52309", "52312", "52316", "52317", "52318", "52319", "52321", "52323", "52324", "52325", "52327", "52329", "52330", "52331", "52333", "52335", "52336", "52338", "52339", "52341", "52344", "52347", "52348", "52352", "52353", "52354", "52356", "52357", "52358", "52359", "52360", "52362", "52364", "52365", "52367", "52369", "52372", "52374", "52375", "52376", "52378", "52380", "52384", "52388", "52389", "52390", "52391", "52393", "52396", "52397", "52402", "52404", "52405", "52406", "52407", "52409", "52411", "52414", "52419", "52420", "52423", "52425", "52427", "52428", "52430", "52432", "52433", "52434", "52436", "52438", "52448", "52449", "52450", "52453", "52455", "52456", "52459", "52460", "52461", "52462", "52463", "52464", "52465", "52466", "52468", "52470", "52471", "52474", "52476", "52478", "52479", "52481", "52484", "52487", "52489", "52495", "52496", "52497", "52498", "52500", "52501", "52506", "52508", "52511", "52513", "52514", "52516", "52517", "52519", "52523", "52525", "52527", "52529", "52531", "52533", "52535", "52536", "52539", "52542", "52545", "52546", "52549", "52550", "52551", "52552", "52554", "52555", "52556", "52557", "52558", "52560", "52561", "52562", "52564", "52566", "52568", "52569", "52570", "52571", "52572", "52574", "52575", "52577", "52578", "52580", "52581", "52582", "52584", "52586", "52587", "52588", "52591", "52593", "52595", "52596", "52597", "52598", "52599", "52600", "52604", "52605", "52607", "52608", "52610", "52613", "52614", "52619", "52620", "52621", "52624", "52628", "52630", "52632", "52633", "52634", "52639", "52640", "52643", "52645", "52649", "52651", "52654", "52660", "52661", "52664", "52667", "52668", "52673", "52674", "52675", "52678", "52679", "52682", "52685", "52686", "52691", "52692", "52693", "52694", "52695", "52696", "52697", "52698", "52701", "52702", "52704", "52706", "52707", "52709", "52710", "52712", "52714", "52715", "52716", "52719", "52721", "52724", "52726", "52728", "52732", "52733", "52738", "52739", "52741", "52746", "52747", "52751", "52752", "52753", "52756", "52760", "52762", "52764", "52765", "52766", "52767", "52770", "52771", "52773", "52774", "52776", "52778", "52781", "52782", "52786", "52788", "52792", "52794", "52795", "52796", "52797", "52798", "52799", "52800", "52802", "52803", "52808", "52810", "52811", "52813", "52814", "52815", "52817", "52818", "52819", "52823", "52824", "52825", "52826", "52827", "52828", "52829", "52830", "52831", "52832", "52839", "52842", "52844", "52846", "52848", "52851", "52854", "52858", "52861", "52862", "52863", "52866", "52867", "52869", "52870", "52871", "52872", "52875", "52876", "52877", "52880", "52882", "52883", "52884", "52886", "52888", "52890", "52891", "52892", "52893", "52895", "52897", "52899", "52900", "52901", "52902", "52903", "52905", "52906", "52910", "52912", "52913", "52914", "52917", "52918", "52920", "52924", "52925", "52926", "52928", "52929", "52930", "52931", "52933", "52934", "52935", "52941", "52942", "52945", "52946", "52947", "52950", "52951", "52952", "52953", "52955", "52957", "52958", "52962", "52963", "52964", "52965", "52970", "52973", "52975", "52976", "52980", "52981", "52982", "52984", "52985", "52986", "52988", "52992", "52993", "52994", "52995", "52998", "52999", "53000", "53003", "53008", "53010", "53013", "53014", "53015", "53016", "53019", "53020", "53022", "53023", "53024", "53025", "53027", "53030", "53031", "53033", "53035", "53037", "53041", "53042", "53044", "53046", "53048", "53049", "53050", "53054", "53056", "53057", "53059", "53061", "53063", "53064", "53065", "53075", "53076", "53077", "53078", "53082", "53083", "53086", "53088", "53089", "53093", "53094", "53095", "53096", "53098", "53099", "53101", "53102", "53103", "53108", "53109", "53113", "53117", "53118", "53124", "53127", "53131", "53133", "53135", "53138", "53140", "53141", "53147", "53148", "53149", "53150", "53169", "53170", "53171", "53172", "53173", "53174", "53175", "53176", "53178", "53184", "53185", "53186", "53187", "53188", "53189", "53191", "53193", "53195", "53197", "53201", "53205", "53210", "53211", "53213", "53214", "53216", "53217", "53218", "53221", "53222", "53224", "53225", "53226", "53228", "53231", "53232", "53234", "53235", "53236", "53237", "53245", "53247", "53248", "53249", "53251", "53252", "53258", "53261", "53262", "53264", "53265", "53267", "53270", "53271", "53272", "53273", "53276", "53277", "53280", "53281", "53282", "53283", "53284", "53285", "53286", "53289", "53290", "53292", "53294", "53300", "53303", "53304", "53305", "53307", "53309", "53310", "53315", "53316", "53318", "53319", "53320", "53321", "53325", "53327", "53329", "53331", "53332", "53334", "53335", "53337", "53338", "53340", "53341", "53343", "53345", "53346", "53350", "53353", "53354", "53356", "53360", "53362", "53363", "53366", "53367", "53368", "53369", "53371", "53373", "53374", "53376", "53377", "53380", "53381", "53384", "53386", "53387", "53389", "53390", "53392", "53393", "53394", "53395", "53396", "53399", "53400", "53402", "53407", "53408", "53409", "53411", "53413", "53416", "53419", "53420", "53424", "53427", "53429", "53433", "53434", "53436", "53438", "53439", "53442", "53444", "53446", "53447", "53448", "53449", "53451", "53452", "53453", "53458", "53459", "53460", "53463", "53464", "53466", "53467", "53473", "53476", "53477", "53482", "53483", "53484", "53485", "53486", "53487", "53488", "53489", "53490", "53491", "53492", "53493", "53494", "53495", "53496", "53497", "53499", "53500", "53503", "53507", "53510", "53511", "53512", "53513", "53515", "53516", "53519", "53520", "53521", "53524", "53526", "53527", "53530", "53531", "53533", "53537", "53538", "53539", "53541", "53543", "53544", "53547", "53551", "53552", "53553", "53554", "53555", "53556", "53558", "53559", "53560", "53563", "53564", "53566", "53567", "53570", "53572", "53574", "53579", "53582", "53583", "53585", "53591", "53592", "53593", "53595", "53599", "53600", "53601", "53602", "53603", "53605", "53606", "53607", "53608", "53609", "53610", "53611", "53613", "53619", "53620", "53621", "53623", "53625", "53627", "53628", "53630", "53634", "53638", "53639", "53640", "53641", "53642", "53645", "53648", "53649", "53651", "53652", "53656", "53658", "53659", "53660", "53661", "53663", "53665", "53666", "53667", "53669", "53670", "53672", "53673", "53676", "53682", "53683", "53684", "53688", "53689", "53690", "53691", "53692", "53696", "53699", "53700", "53701", "53702", "53703", "53706", "53707", "53709", "53711", "53713", "53718", "53719", "53720", "53721", "53725", "53729", "53730", "53732", "53733", "53734", "53735", "53736", "53739", "53741", "53742", "53743", "53744", "53745", "53747", "53749", "53751", "53752", "53756", "53761", "53763", "53765", "53766", "53767", "53769", "53770", "53772", "53775", "53776", "53778", "53779", "53783", "53784", "53787", "53788", "53791", "53793", "53799", "53800", "53802", "53803", "53804", "53805", "53806", "53811", "53812", "53813", "53815", "53816", "53817", "53821", "53824", "53826", "53827", "53828", "53829", "53831", "53832", "53833", "53838", "53843", "53844", "53845", "53850", "53851", "53852", "53861", "53862", "53863", "53864", "53866", "53875", "53876", "53880", "53881", "53883", "53885", "53886", "53887", "53888", "53889", "53891", "53892", "53893", "53894", "53895", "53898", "53899", "53901", "53906", "53908", "53909", "53910", "53912", "53914", "53915", "53918", "53920", "53921", "53926", "53928", "53930", "53933", "53935", "53937", "53938", "53939", "53940", "53941", "53942", "53943", "53944", "53945", "53949", "53950", "53952", "53953", "53954", "53957", "53958", "53959", "53960", "53963", "53967", "53969", "53970", "53972", "53973", "53974", "53976", "53978", "53979", "53980", "53981", "53987", "53990", "53993", "53994", "53997", "53998", "53999", "54000", "54002", "54004", "54005", "54006", "54007", "54008", "54010", "54012", "54013", "54015", "54016", "54017", "54018", "54019", "54020", "54022", "54023", "54025", "54026", "54031", "54033", "54038", "54041", "54044", "54046", "54047", "54048", "54049", "54051", "54053", "54054", "54057", "54061", "54062", "54064", "54067", "54068", "54070", "54071", "54072", "54074", "54076", "54080", "54081", "54082", "54083", "54088", "54089", "54092", "54093", "54094", "54095", "54096", "54097", "54098", "54101", "54102", "54103", "54104", "54105", "54110", "54112", "54113", "54114", "54115", "54116", "54117", "54118", "54120", "54121", "54122", "54123", "54124", "54125", "54128", "54129", "54130", "54131", "54132", "54135", "54136", "54138", "54140", "54143", "54146", "54148", "54149", "54152", "54154", "54155", "54156", "54158", "54161", "54163", "54166", "54168", "54171", "54172", "54173", "54174", "54175", "54176", "54177", "54178", "54180", "54181", "54185", "54186", "54187", "54194", "54196", "54199", "54201", "54203", "54204", "54206", "54208", "54210", "54211", "54212", "54214", "54215", "54216", "54222", "54224", "54226", "54227", "54229", "54230", "54232", "54233", "54235", "54238", "54240", "54241", "54243", "54247", "54250", "54252", "54253", "54254", "54256", "54257", "54259", "54260", "54261", "54263", "54266", "54268", "54278", "54279", "54280", "54282", "54283", "54284", "54285", "54288", "54290", "54291", "54292", "54293", "54296", "54298", "54299", "54301", "54309", "54310", "54313", "54314", "54316", "54320", "54322", "54324", "54327", "54328", "54329", "54330", "54332", "54337", "54338", "54339", "54346", "54348", "54353", "54354", "54355", "54357", "54359", "54362", "54364", "54365", "54366", "54367", "54368", "54370", "54371", "54372", "54374", "54375", "54376", "54377", "54378", "54380", "54381", "54383", "54384", "54387", "54388", "54390", "54391", "54394", "54395", "54396", "54398", "54405", "54409", "54411", "54413", "54414", "54417", "54418", "54419", "54420", "54424", "54427", "54429", "54431", "54432", "54434", "54435", "54436", "54437", "54438", "54439", "54444", "54446", "54447", "54448", "54451", "54452", "54453", "54458", "54459", "54465", "54466", "54467", "54470", "54471", "54475", "54477", "54479", "54480", "54481", "54482", "54483", "54484", "54485", "54487", "54489", "54490", "54492", "54495", "54500", "54503", "54507", "54508", "54510", "54511", "54515", "54516", "54518", "54520", "54521", "54522", "54523", "54524", "54525", "54526", "54528", "54529", "54532", "54536", "54540", "54542", "54544", "54546", "54547", "54548", "54549", "54550", "54551", "54556", "54560", "54564", "54567", "54569", "54572", "54576", "54577", "54579", "54580", "54581", "54585", "54586", "54587", "54591", "54594", "54596", "54597", "54598", "54599", "54602", "54603", "54604", "54606", "54607", "54608", "54609", "54610", "54612", "54614", "54616", "54617", "54619", "54620", "54621", "54622", "54625", "54626", "54628", "54633", "54638", "54642", "54643", "54644", "54648", "54650", "54653", "54656", "54657", "54659", "54660", "54661", "54663", "54664", "54666", "54668", "54669", "54671", "54672", "54675", "54679", "54680", "54681", "54685", "54686", "54688", "54694", "54695", "54696", "54701", "54702", "54703", "54706", "54707", "54709", "54713", "54714", "54715", "54716", "54718", "54720", "54721", "54723", "54726", "54729", "54730", "54733", "54734", "54735", "54736", "54740", "54742", "54747", "54748", "54749", "54750", "54752", "54754", "54756", "54757", "54759", "54761", "54763", "54764", "54765", "54767", "54768", "54771", "54772", "54774", "54776", "54779", "54780", "54782", "54783", "54785", "54787", "54791", "54792", "54797", "54798", "54799", "54800", "54802", "54804", "54808", "54811", "54816", "54820", "54825", "54828", "54830", "54831", "54834", "54839", "54843", "54844", "54845", "54846", "54851", "54852", "54853", "54854", "54856", "54860", "54861", "54862", "54863", "54869", "54873", "54874", "54875", "54876", "54878", "54879", "54880", "54882", "54883", "54884", "54885", "54886", "54887", "54890", "54891", "54892", "54897", "54899", "54900", "54901", "54904", "54908", "54912", "54915", "54916", "54918", "54919", "54920", "54922", "54923", "54924", "54925", "54928", "54931", "54932", "54933", "54934", "54935", "54937", "54941", "54942", "54943", "54946", "54953", "54954", "54956", "54957", "54958", "54962", "54963", "54964", "54968", "54970", "54971", "54972", "54974", "54975", "54977", "54978", "54979", "54980", "54981", "54982", "54984", "54988", "54989", "54990", "54991", "54993", "54996", "54999", "55001", "55002", "55003", "55005", "55008", "55011", "55013", "55014", "55015", "55016", "55017", "55018", "55024", "55026", "55027", "55030", "55031", "55033", "55034", "55037", "55039", "55041", "55042", "55043", "55045", "55047", "55049", "55050", "55058", "55062", "55063", "55064", "55068", "55069", "55070", "55072", "55073", "55074", "55079", "55080", "55081", "55082", "55083", "55085", "55088", "55091", "55092", "55093", "55097", "55099", "55101", "55110", "55112", "55113", "55117", "55118", "55120", "55121", "55124", "55127", "55128", "55130", "55133", "55135", "55137", "55138", "55139", "55140", "55141", "55149", "55152", "55156", "55157", "55158", "55160", "55162", "55163", "55166", "55171", "55173", "55175", "55176", "55177", "55178", "55179", "55180", "55181", "55182", "55184", "55185", "55187", "55189", "55190", "55192", "55195", "55196", "55203", "55205", "55206", "55209", "55210", "55212", "55215", "55216", "55218", "55221", "55223", "55229", "55231", "55232", "55234", "55235", "55236", "55238", "55239", "55240", "55241", "55243", "55245", "55246", "55247", "55249", "55250", "55251", "55253", "55256", "55258", "55260", "55262", "55263", "55265", "55267", "55268", "55269", "55270", "55273", "55277", "55281", "55282", "55284", "55287", "55289", "55290", "55291", "55292", "55294", "55295", "55296", "55300", "55302", "55303", "55304", "55305", "55306", "55307", "55309", "55310", "55311", "55314", "55317", "55318", "55320", "55321", "55322", "55324", "55325", "55326", "55327", "55331", "55332", "55333", "55336", "55337", "55339", "55340", "55345", "55346", "55351", "55355", "55362", "55364", "55366", "55367", "55373", "55374", "55375", "55376", "55380", "55382", "55383", "55386", "55387", "55388", "55390", "55392", "55393", "55395", "55396", "55397", "55399", "55400", "55402", "55403", "55407", "55409", "55410", "55411", "55415", "55419", "55420", "55421", "55423", "55424", "55426", "55428", "55429", "55432", "55433", "55435", "55436", "55437", "55439", "55443", "55445", "55449", "55453", "55454", "55455", "55456", "55459", "55460", "55461", "55463", "55466", "55467", "55470", "55472", "55473", "55476", "55478", "55481", "55482", "55484", "55485", "55486", "55488", "55489", "55490", "55493", "55495", "55498", "55500", "55502", "55505", "55508", "55509", "55510", "55511", "55512", "55515", "55516", "55517", "55522", "55523", "55525", "55526", "55528", "55540", "55541", "55543", "55544", "55547", "55552", "55557", "55558", "55560", "55561", "55562", "55563", "55564", "55565", "55569", "55573", "55575", "55576", "55578", "55579", "55584", "55585", "55586", "55587", "55588", "55593", "55594", "55595", "55596", "55597", "55598", "55599", "55600", "55601", "55603", "55605", "55606", "55609", "55611", "55613", "55614", "55615", "55616", "55617", "55618", "55621", "55623", "55624", "55625", "55627", "55628", "55630", "55631", "55633", "55635", "55636", "55637", "55638", "55644", "55647", "55648", "55649", "55651", "55655", "55658", "55662", "55663", "55664", "55665", "55667", "55668", "55669", "55670", "55671", "55674", "55680", "55681", "55683", "55685", "55686", "55687", "55689", "55690", "55691", "55693", "55694", "55697", "55699", "55701", "55705", "55708", "55715", "55716", "55719", "55720", "55723", "55725", "55726", "55727", "55729", "55731", "55732", "55733", "55734", "55737", "55739", "55741", "55742", "55743", "55744", "55747", "55750", "55751", "55753", "55757", "55758", "55761", "55762", "55763", "55765", "55766", "55768", "55769", "55770", "55771", "55772", "55773", "55776", "55778", "55779", "55781", "55782", "55783", "55784", "55787", "55788", "55790", "55791", "55793", "55795", "55797", "55798", "55799", "55802", "55804", "55805", "55807", "55812", "55814", "55816", "55819", "55820", "55821", "55822", "55824", "55827", "55828", "55829", "55830", "55832", "55833", "55834", "55839", "55841", "55842", "55844", "55845", "55847", "55849", "55850", "55851", "55852", "55854", "55855", "55858", "55861", "55862", "55869", "55876", "55877", "55879", "55880", "55881", "55885", "55886", "55890", "55891", "55892", "55893", "55894", "55895", "55897", "55901", "55905", "55906", "55908", "55910", "55911", "55912", "55914", "55917", "55918", "55919", "55920", "55924", "55927", "55933", "55935", "55936", "55938", "55939", "55941", "55942", "55943", "55944", "55945", "55946", "55948", "55949", "55950", "55952", "55953", "55954", "55955", "55956", "55958", "55960", "55961", "55963", "55964", "55965", "55967", "55968", "55969", "55971", "55972", "55973", "55975", "55976", "55977", "55979", "55980", "55981", "55982", "55985", "55986", "55987", "55988", "55989", "55990", "55991", "55992", "55993", "55994", "55995", "55996", "56004", "56005", "56008", "56009", "56011", "56012", "56015", "56018", "56020", "56028", "56030", "56033", "56034", "56038", "56041", "56042", "56043", "56045", "56046", "56049", "56050", "56052", "56053", "56056", "56057", "56059", "56062", "56063", "56064", "56065", "56069", "56071", "56075", "56076", "56078", "56079", "56081", "56083", "56084", "56088", "56090", "56091", "56093", "56097", "56100", "56102", "56104", "56105", "56106", "56107", "56108", "56109", "56112", "56113", "56114", "56116", "56118", "56119", "56120", "56121", "56125", "56129", "56133", "56135", "56140", "56141", "56143", "56146", "56148", "56150", "56151", "56152", "56154", "56155", "56156", "56157", "56158", "56160", "56161", "56162", "56167", "56170", "56174", "56175", "56177", "56179", "56180", "56181", "56184", "56185", "56188", "56189", "56190", "56191", "56194", "56195", "56196", "56198", "56200", "56202", "56203", "56204", "56206", "56207", "56208", "56210", "56211", "56214", "56215", "56217", "56220", "56223", "56224", "56225", "56226", "56227", "56229", "56230", "56231", "56232", "56233", "56237", "56240", "56241", "56242", "56243", "56245", "56247", "56248", "56249", "56250", "56257", "56258", "56260", "56268", "56269", "56273", "56274", "56279", "56281", "56283", "56284", "56286", "56289", "56290", "56291", "56292", "56295", "56298", "56300", "56302", "56305", "56306", "56307", "56310", "56314", "56315", "56316", "56318", "56319", "56323", "56327", "56329", "56330", "56331", "56332", "56333", "56336", "56337", "56340", "56341", "56343", "56345", "56347", "56348", "56349", "56350", "56351", "56352", "56356", "56357", "56359", "56360", "56363", "56364", "56366", "56368", "56369", "56370", "56372", "56373", "56374", "56375", "56376", "56378", "56379", "56380", "56381", "56385", "56387", "56388", "56389", "56390", "56391", "56392", "56393", "56395", "56397", "56398", "56399", "56400", "56402", "56403", "56408", "56409", "56410", "56411", "56413", "56414", "56415", "56419", "56420", "56423", "56426", "56428", "56430", "56432", "56433", "56435", "56436", "56438", "56442", "56443", "56447", "56449", "56452", "56457", "56462", "56466", "56467", "56474", "56479", "56480", "56481", "56482", "56483", "56490", "56492", "56493", "56497", "56499", "56500", "56501", "56502", "56505", "56506", "56507", "56508", "56509", "56511", "56512", "56513", "56517", "56518", "56519", "56520", "56521", "56522", "56523", "56524", "56525", "56526", "56527", "56528", "56532", "56533", "56535", "56537", "56540", "56546", "56548", "56549", "56550", "56551", "56552", "56553", "56554", "56556", "56562", "56563", "56564", "56565", "56567", "56569", "56570", "56573", "56576", "56577", "56578", "56579", "56580", "56581", "56583", "56584", "56585", "56587", "56588", "56589", "56591", "56594", "56596", "56597", "56599", "56600", "56601", "56602", "56605", "56606", "56608", "56612", "56613", "56614", "56618", "56619", "56622", "56623", "56624", "56626", "56627", "56628", "56630", "56633", "56642", "56644", "56646", "56648", "56651", "56655", "56656", "56658", "56659", "56663", "56665", "56667", "56668", "56669", "56672", "56674", "56676", "56677", "56680", "56682", "56683", "56686", "56688", "56693", "56703", "56704", "56705", "56706", "56709", "56710", "56712", "56714", "56716", "56718", "56719", "56720", "56725", "56727", "56729", "56730", "56733", "56735", "56738", "56742", "56743", "56744", "56745", "56747", "56749", "56750", "56754", "56755", "56756", "56757", "56761", "56762", "56763", "56764", "56765", "56770", "56771", "56775", "56778", "56784", "56785", "56786", "56791", "56792", "56793", "56796", "56797", "56800", "56802", "56803", "56804", "56805", "56807", "56816", "56818", "56819", "56821", "56823", "56825", "56826", "56828", "56829", "56831", "56832", "56835", "56836", "56837", "56839", "56842", "56843", "56844", "56846", "56847", "56848", "56850", "56854", "56857", "56861", "56862", "56863", "56868", "56869", "56872", "56873", "56874", "56875", "56876", "56879", "56881", "56882", "56890", "56891", "56894", "56895", "56896", "56897", "56898", "56900", "56901", "56911", "56913", "56914", "56915", "56916", "56918", "56919", "56920", "56924", "56925", "56926", "56927", "56928", "56929", "56930", "56931", "56932", "56936", "56938", "56941", "56943", "56944", "56946", "56948", "56949", "56952", "56953", "56955", "56957", "56960", "56961", "56963", "56964", "56966", "56968", "56970", "56971", "56974", "56977", "56978", "56980", "56981", "56986", "56987", "56988", "56989", "56991", "56994", "56996", "56997", "56999", "57002", "57005", "57006", "57007", "57008", "57009", "57011", "57012", "57021", "57022", "57023", "57025", "57028", "57029", "57032", "57034", "57035", "57036", "57038", "57039", "57041", "57042", "57043", "57046", "57047", "57048", "57049", "57051", "57053", "57055", "57056", "57057", "57058", "57059", "57062", "57063", "57065", "57068", "57073", "57075", "57078", "57081", "57083", "57084", "57085", "57086", "57087", "57088", "57089", "57094", "57096", "57099", "57101", "57102", "57103", "57105", "57106", "57107", "57110", "57112", "57115", "57117", "57122", "57125", "57126", "57127", "57129", "57131", "57133", "57136", "57137", "57138", "57141", "57142", "57145", "57147", "57148", "57150", "57151", "57154", "57156", "57160", "57161", "57162", "57164", "57165", "57166", "57168", "57169", "57170", "57173", "57175", "57182", "57185", "57186", "57188", "57189", "57192", "57193", "57195", "57196", "57198", "57202", "57204", "57206", "57207", "57208", "57212", "57213", "57214", "57215", "57216", "57218", "57220", "57224", "57227", "57229", "57232", "57242", "57243", "57245", "57246", "57248", "57251", "57253", "57255", "57256", "57257", "57258", "57259", "57264", "57266", "57269", "57270", "57273", "57275", "57277", "57278", "57281", "57282", "57287", "57289", "57290", "57292", "57293", "57296", "57297", "57299", "57300", "57303", "57304", "57305", "57306", "57307", "57308", "57309", "57314", "57315", "57316", "57319", "57320", "57322", "57323", "57324", "57325", "57326", "57335", "57336", "57339", "57342", "57344", "57347", "57349", "57352", "57354", "57358", "57359", "57361", "57362", "57363", "57366", "57369", "57372", "57377", "57380", "57381", "57382", "57387", "57388", "57389", "57392", "57394", "57395", "57396", "57399", "57401", "57404", "57407", "57409", "57411", "57414", "57415", "57416", "57417", "57419", "57421", "57422", "57423", "57425", "57427", "57428", "57429", "57431", "57433", "57435", "57437", "57439", "57440", "57441", "57447", "57449", "57450", "57451", "57452", "57453", "57454", "57455", "57456", "57459", "57461", "57462", "57463", "57465", "57466", "57470", "57473", "57476", "57478", "57479", "57481", "57483", "57488", "57489", "57490", "57492", "57497", "57498", "57499", "57500", "57501", "57502", "57503", "57504", "57505", "57509", "57511", "57512", "57515", "57516", "57518", "57519", "57521", "57523", "57525", "57527", "57530", "57531", "57533", "57535", "57537", "57538", "57539", "57541", "57542", "57546", "57547", "57548", "57550", "57551", "57553", "57555", "57560", "57563", "57564", "57567", "57569", "57570", "57574", "57575", "57576", "57579", "57584", "57587", "57589", "57591", "57593", "57594", "57597", "57598", "57599", "57600", "57603", "57605", "57609", "57610", "57612", "57613", "57614", "57615", "57616", "57617", "57618", "57623", "57625", "57626", "57627", "57628", "57629", "57632", "57635", "57637", "57638", "57640", "57643", "57645", "57648", "57650", "57651", "57652", "57656", "57657", "57662", "57667", "57669", "57671", "57676", "57678", "57680", "57681", "57689", "57694", "57695", "57696", "57699", "57700", "57701", "57704", "57705", "57707", "57712", "57716", "57717", "57718", "57720", "57721", "57722", "57723", "57724", "57726", "57728", "57732", "57733", "57734", "57735", "57736", "57738", "57741", "57742", "57745", "57746", "57747", "57748", "57750", "57751", "57753", "57754", "57755", "57758", "57759", "57760", "57762", "57763", "57764", "57765", "57766", "57767", "57770", "57773", "57775", "57776", "57777", "57779", "57783", "57785", "57786", "57787", "57788", "57790", "57791", "57792", "57794", "57795", "57797", "57799", "57800", "57802", "57803", "57805", "57806", "57809", "57811", "57813", "57814", "57818", "57819", "57821", "57822", "57823", "57825", "57826", "57827", "57829", "57838", "57840", "57850", "57851", "57852", "57853", "57855", "57857", "57858", "57859", "57860", "57861", "57862", "57863", "57864", "57867", "57868", "57869", "57871", "57872", "57876", "57879", "57880", "57882", "57885", "57887", "57890", "57891", "57896", "57899", "57901", "57902", "57903", "57906", "57907", "57911", "57912", "57913", "57915", "57916", "57920", "57921", "57926", "57927", "57931", "57932", "57933", "57936", "57938", "57939", "57941", "57952", "57956", "57957", "57959", "57960", "57961", "57962", "57963", "57964", "57966", "57969", "57974", "57975", "57979", "57981", "57984", "57992", "57993", "57994", "57995", "57996", "57997", "57998", "57999", "58001", "58002", "58003", "58004", "58005", "58006", "58011", "58013", "58016", "58019", "58020", "58021", "58022", "58023", "58025", "58026", "58027", "58029", "58037", "58038", "58041", "58043", "58044", "58045", "58046", "58047", "58052", "58054", "58056", "58058", "58059", "58069", "58071", "58073", "58075", "58076", "58078", "58080", "58081", "58085", "58086", "58087", "58088", "58090", "58092", "58095", "58096", "58097", "58100", "58103", "58105", "58106", "58107", "58109", "58112", "58113", "58114", "58115", "58120", "58123", "58125", "58127", "58128", "58132", "58135", "58136", "58139", "58141", "58142", "58143", "58144", "58145", "58146", "58149", "58150", "58151", "58152", "58154", "58156", "58164", "58167", "58168", "58169", "58171", "58174", "58176", "58177", "58178", "58180", "58182", "58184", "58185", "58186", "58187", "58191", "58192", "58198", "58199", "58200", "58203", "58206", "58212", "58214", "58218", "58219", "58220", "58222", "58223", "58228", "58231", "58232", "58234", "58235", "58239", "58240", "58241", "58245", "58246", "58249", "58253", "58256", "58258", "58260", "58261", "58262", "58263", "58264", "58265", "58267", "58268", "58269", "58270", "58273", "58276", "58279", "58280", "58281", "58283", "58287", "58288", "58290", "58291", "58294", "58295", "58296", "58297", "58298", "58299", "58301", "58304", "58305", "58306", "58307", "58308", "58310", "58312", "58313", "58314", "58317", "58320", "58326", "58328", "58329", "58331", "58333", "58334", "58337", "58339", "58340", "58341", "58343", "58344", "58346", "58348", "58349", "58351", "58353", "58355", "58356", "58358", "58359", "58360", "58361", "58363", "58364", "58365", "58366", "58367", "58368", "58369", "58370", "58371", "58373", "58374", "58378", "58384", "58387", "58389", "58392", "58393", "58397", "58398", "58400", "58401", "58402", "58404", "58406", "58409", "58411", "58412", "58414", "58415", "58416", "58420", "58423", "58424", "58425", "58428", "58430", "58432", "58435", "58438", "58440", "58441", "58442", "58447", "58449", "58450", "58451", "58452", "58456", "58462", "58463", "58466", "58468", "58473", "58474", "58476", "58480", "58482", "58483", "58484", "58486", "58487", "58488", "58489", "58490", "58492", "58493", "58494", "58495", "58496", "58500", "58501", "58502", "58503", "58506", "58509", "58510", "58515", "58519", "58520", "58522", "58524", "58525", "58526", "58529", "58530", "58531", "58533", "58540", "58541", "58547", "58550", "58551", "58552", "58553", "58559", "58561", "58567", "58571", "58572", "58573", "58576", "58577", "58578", "58583", "58585", "58586", "58587", "58590", "58592", "58594", "58596", "58597", "58598", "58599", "58600", "58601", "58606", "58608", "58610", "58611", "58613", "58615", "58617", "58619", "58620", "58621", "58622", "58623", "58625", "58626", "58627", "58628", "58632", "58636", "58637", "58640", "58642", "58648", "58649", "58652", "58653", "58656", "58661", "58663", "58665", "58666", "58667", "58668", "58671", "58674", "58675", "58681", "58683", "58684", "58688", "58690", "58691", "58692", "58694", "58696", "58699", "58703", "58705", "58706", "58708", "58709", "58714", "58720", "58722", "58723", "58724", "58725", "58726", "58730", "58733", "58734", "58735", "58736", "58737", "58738", "58746", "58749", "58750", "58751", "58752", "58753", "58754", "58755", "58757", "58758", "58760", "58762", "58764", "58766", "58770", "58771", "58772", "58778", "58779", "58782", "58783", "58785", "58786", "58790", "58793", "58794", "58795", "58796", "58798", "58805", "58806", "58807", "58808", "58809", "58812", "58816", "58818", "58819", "58824", "58825", "58828", "58829", "58830", "58833", "58834", "58835", "58842", "58843", "58848", "58849", "58855", "58856", "58857", "58858", "58860", "58861", "58863", "58866", "58868", "58871", "58872", "58874", "58875", "58876", "58877", "58885", "58888", "58889", "58890", "58892", "58893", "58895", "58896", "58898", "58901", "58902", "58903", "58905", "58906", "58909", "58910", "58912", "58915", "58916", "58917", "58918", "58920", "58925", "58928", "58930", "58937", "58938", "58939", "58940", "58942", "58944", "58945", "58948", "58949", "58950", "58951", "58953", "58956", "58957", "58961", "58963", "58968", "58969", "58973", "58977", "58978", "58979", "58980", "58982", "58983", "58985", "58989", "58990", "58993", "58994", "58995", "58996", "58999", "59001", "59003", "59005", "59009", "59011", "59014", "59015", "59016", "59017", "59019", "59020", "59022", "59024", "59025", "59026", "59028", "59029", "59030", "59037", "59040", "59041", "59042", "59043", "59047", "59048", "59049", "59055", "59060", "59061", "59067", "59069", "59070", "59074", "59075", "59076", "59077", "59082", "59084", "59085", "59089", "59090", "59095", "59096", "59098", "59100", "59101", "59104", "59106", "59108", "59109", "59111", "59112", "59115", "59118", "59119", "59120", "59124", "59126", "59127", "59128", "59134", "59136", "59137", "59140", "59143", "59146", "59147", "59148", "59150", "59152", "59153", "59154", "59158", "59159", "59161", "59162", "59166", "59167", "59168", "59169", "59171", "59173", "59176", "59177", "59179", "59182", "59183", "59185", "59186", "59187", "59188", "59190", "59191", "59193", "59196", "59197", "59199", "59202", "59207", "59211", "59213", "59215", "59217", "59221", "59226", "59230", "59232", "59233", "59234", "59240", "59241", "59245", "59248", "59250", "59251", "59252", "59253", "59254", "59256", "59258", "59260", "59261", "59263", "59268", "59270", "59274", "59276", "59277", "59279", "59281", "59284", "59287", "59288", "59290", "59291", "59292", "59294", "59295", "59298", "59301", "59302", "59305", "59307", "59310", "59311", "59312", "59313", "59314", "59317", "59318", "59321", "59322", "59323", "59324", "59325", "59326", "59328", "59330", "59332", "59333", "59336", "59337", "59338", "59340", "59341", "59345", "59347", "59348", "59349", "59350", "59352", "59354", "59355", "59356", "59359", "59362", "59363", "59366", "59368", "59369", "59370", "59373", "59381", "59383", "59385", "59387", "59389", "59393", "59395", "59396", "59398", "59399", "59400", "59401", "59408", "59410", "59411", "59412", "59413", "59418", "59419", "59422", "59426", "59427", "59429", "59432", "59434", "59439", "59443", "59445", "59446", "59448", "59450", "59452", "59453", "59455", "59457", "59458", "59459", "59462", "59463", "59466", "59474", "59478", "59479", "59480", "59483", "59485", "59488", "59490", "59492", "59493", "59497", "59500", "59502", "59504", "59505", "59506", "59507", "59508", "59509", "59510", "59511", "59512", "59513", "59516", "59517", "59523", "59526", "59528", "59533", "59535", "59536", "59538", "59540", "59541", "59544", "59545", "59546", "59547", "59549", "59554", "59558", "59559", "59561", "59562", "59565", "59566", "59568", "59569", "59570", "59576", "59577", "59579", "59581", "59582", "59583", "59584", "59585", "59586", "59588", "59591", "59592", "59594", "59595", "59596", "59597", "59602", "59605", "59606", "59607", "59611", "59612", "59613", "59617", "59619", "59620", "59625", "59626", "59628", "59633", "59634", "59635", "59636", "59641", "59642", "59643", "59646", "59651", "59652", "59654", "59655", "59657", "59658", "59659", "59661", "59663", "59667", "59668", "59669", "59672", "59673", "59674", "59677", "59678", "59680", "59684", "59685", "59688", "59691", "59697", "59698", "59699", "59700", "59702", "59704", "59705", "59709", "59712", "59713", "59714", "59716", "59720", "59722", "59724", "59727", "59732", "59733", "59735", "59736", "59737", "59740", "59744", "59745", "59748", "59749", "59750", "59751", "59757", "59760", "59763", "59768", "59769", "59770", "59772", "59774", "59776", "59777", "59779", "59782", "59783", "59784", "59789", "59797", "59798", "59799", "59802", "59803", "59804", "59805", "59808", "59811", "59813", "59816", "59817", "59818", "59820", "59824", "59825", "59830", "59833", "59835", "59838", "59841", "59842", "59843", "59844", "59846", "59848", "59849", "59857", "59860", "59862", "59863", "59865", "59867", "59869", "59870", "59872", "59873", "59874", "59875", "59877", "59878", "59879", "59880", "59881", "59882", "59886", "59889", "59890", "59891", "59892", "59895", "59896", "59897", "59898", "59900", "59902", "59905", "59906", "59908", "59910", "59911", "59914", "59915", "59919", "59923", "59925", "59926", "59929", "59933", "59939", "59940", "59941", "59942", "59944", "59948", "59949", "59951", "59952", "59954", "59957", "59958", "59960", "59961", "59962", "59963", "59967", "59968", "59969", "59972", "59973", "59977", "59980", "59981", "59982", "59983", "59986", "59987", "59988", "59991", "59992", "59993", "59994", "59997", "59998", "59999", "60000", "60004", "60006", "60007", "60009", "60012", "60013", "60015", "60018", "60020", "60021", "60027", "60029", "60030", "60034", "60035", "60038", "60039", "60040", "60042", "60044", "60045", "60049", "60050", "60051", "60053", "60056", "60057", "60058", "60062", "60063", "60065", "60066", "60067", "60068", "60070", "60071", "60072", "60073", "60074", "60075", "60076", "60080", "60081", "60082", "60083", "60084", "60087", "60091", "60093", "60096", "60097", "60098", "60101", "60102", "60103", "60105", "60112", "60113", "60114", "60116", "60117", "60123", "60124", "60125", "60127", "60129", "60131", "60133", "60138", "60140", "60143", "60147", "60148", "60149", "60150", "60151", "60152", "60154", "60155", "60156", "60157", "60161", "60162", "60165", "60166", "60168", "60172", "60173", "60174", "60175", "60176", "60178", "60183", "60184", "60185", "60186", "60187", "60189", "60192", "60194", "60197", "60198", "60199", "60200", "60202", "60203", "60204", "60205", "60213", "60217", "60220", "60221", "60222", "60223", "60227", "60229", "60230", "60232", "60235", "60238", "60240", "60244", "60246", "60248", "60249", "60250", "60252", "60257", "60259", "60261", "60263", "60267", "60270", "60274", "60275", "60276", "60277", "60278", "60279", "60280", "60287", "60290", "60291", "60293", "60294", "60295", "60296", "60298", "60300", "60301", "60305", "60306", "60311", "60314", "60316", "60317", "60322", "60323", "60324", "60327", "60328", "60329", "60331", "60332", "60335", "60337", "60339", "60340", "60341", "60342", "60343", "60344", "60345", "60347", "60352", "60356", "60357", "60360", "60361", "60362", "60363", "60365", "60366", "60368", "60371", "60372", "60373", "60376", "60377", "60381", "60387", "60388", "60391", "60393", "60396", "60398", "60399", "60402", "60404", "60410", "60411", "60414", "60416", "60417", "60421", "60423", "60424", "60425", "60426", "60427", "60429", "60431", "60434", "60439", "60441", "60443", "60444", "60446", "60447", "60449", "60452", "60454", "60455", "60457", "60459", "60461", "60463", "60464", "60465", "60466", "60467", "60469", "60474", "60476", "60477", "60480", "60481", "60483", "60486", "60491", "60492", "60493", "60494", "60495", "60496", "60498", "60499", "60500", "60503", "60504", "60510", "60512", "60513", "60514", "60516", "60519", "60520", "60521", "60523", "60524", "60528", "60531", "60532", "60533", "60537", "60540", "60541", "60545", "60548", "60549", "60550", "60553", "60554", "60556", "60559", "60560", "60561", "60562", "60563", "60566", "60567", "60575", "60576", "60577", "60579", "60584", "60585", "60586", "60587", "60588", "60589", "60591", "60592", "60593", "60597", "60601", "60603", "60611", "60612", "60613", "60615", "60618", "60619", "60624", "60629", "60630", "60632", "60633", "60634", "60640", "60644", "60645", "60648", "60649", "60654", "60659", "60660", "60662", "60663", "60665", "60666", "60667", "60668", "60669", "60672", "60680", "60683", "60685", "60686", "60687", "60690", "60691", "60696", "60697", "60698", "60699", "60700", "60702", "60703", "60705", "60708", "60709", "60712", "60713", "60714", "60718", "60719", "60726", "60727", "60729", "60730", "60731", "60737", "60738", "60747", "60748", "60750", "60754", "60755", "60756", "60757", "60758", "60760", "60762", "60765", "60767", "60768", "60771", "60773", "60774", "60775", "60776", "60777", "60780", "60785", "60788", "60789", "60790", "60792", "60794", "60796", "60797", "60798", "60801", "60802", "60803", "60806", "60807", "60810", "60816", "60818", "60819", "60820", "60821", "60822", "60824", "60825", "60826", "60827", "60828", "60830", "60831", "60834", "60836", "60840", "60841", "60842", "60844", "60846", "60849", "60850", "60854", "60856", "60857", "60858", "60859", "60860", "60861", "60863", "60864", "60865", "60866", "60868", "60869", "60870", "60871", "60872", "60880", "60883", "60884", "60885", "60887", "60888", "60890", "60894", "60896", "60898", "60899", "60900", "60901", "60903", "60905", "60907", "60909", "60910", "60914", "60915", "60916", "60917", "60918", "60920", "60922", "60923", "60926", "60927", "60930", "60934", "60937", "60943", "60945", "60947", "60948", "60949", "60950", "60951", "60953", "60954", "60962", "60963", "60964", "60967", "60968", "60969", "60970", "60971", "60973", "60974", "60975", "60976", "60977", "60979", "60980", "60981", "60983", "60988", "60991", "60994", "60995", "60996", "60997", "61001", "61005", "61009", "61010", "61013", "61016", "61020", "61023", "61024", "61028", "61029", "61035", "61036", "61037", "61039", "61040", "61042", "61051", "61052", "61053", "61054", "61055", "61059", "61061", "61063", "61067", "61069", "61071", "61076", "61077", "61078", "61080", "61081", "61083", "61087", "61088", "61089", "61092", "61095", "61097", "61100", "61104", "61107", "61113", "61114", "61115", "61118", "61120", "61121", "61123", "61124", "61126", "61127", "61128", "61129", "61130", "61132", "61135", "61137", "61138", "61139", "61140", "61143", "61144", "61145", "61150", "61151", "61154", "61155", "61159", "61160", "61161", "61162", "61163", "61164", "61166", "61167", "61168", "61169", "61171", "61174", "61178", "61180", "61181", "61182", "61186", "61190", "61192", "61193", "61197", "61200", "61201", "61202", "61203", "61205", "61208", "61209", "61212", "61213", "61215", "61216", "61221", "61223", "61225", "61228", "61229", "61230", "61232", "61233", "61235", "61236", "61239", "61243", "61244", "61245", "61246", "61247", "61248", "61249", "61250", "61251", "61252", "61258", "61260", "61261", "61262", "61267", "61270", "61274", "61277", "61278", "61279", "61280", "61283", "61285", "61287", "61290", "61292", "61294", "61295", "61296", "61297", "61298", "61299", "61300", "61301", "61302", "61303", "61304", "61307", "61312", "61313", "61316", "61317", "61319", "61320", "61323", "61324", "61327", "61328", "61329", "61330", "61331", "61333", "61334", "61335", "61338", "61342", "61344", "61348", "61349", "61350", "61354", "61355", "61356", "61357", "61360", "61362", "61364", "61367", "61368", "61370", "61371", "61372", "61373", "61377", "61379", "61380", "61382", "61383", "61386", "61387", "61388", "61391", "61392", "61394", "61399", "61400", "61401", "61402", "61404", "61405", "61406", "61407", "61408", "61409", "61413", "61414", "61415", "61422", "61425", "61426", "61427", "61428", "61429", "61430", "61432", "61439", "61442", "61444", "61445", "61446", "61456", "61457", "61458", "61459", "61461", "61463", "61467", "61468", "61469", "61470", "61472", "61473", "61474", "61475", "61476", "61485", "61486", "61487", "61490", "61491", "61492", "61493", "61494", "61495", "61496", "61499", "61502", "61503", "61504", "61505", "61506", "61510", "61512", "61513", "61515", "61519", "61520", "61523", "61524", "61525", "61528", "61533", "61534", "61535", "61537", "61540", "61546", "61548", "61550", "61551", "61552", "61553", "61557", "61558", "61560", "61562", "61563", "61564", "61567", "61568", "61569", "61571", "61573", "61574", "61575", "61576", "61577", "61578", "61580", "61583", "61585", "61586", "61587", "61589", "61593", "61595", "61597", "61602", "61605", "61611", "61613", "61614", "61616", "61617", "61618", "61619", "61620", "61623", "61624", "61627", "61630", "61637", "61639", "61641", "61646", "61648", "61650", "61654", "61655", "61656", "61661", "61666", "61671", "61676", "61679", "61683", "61686", "61687", "61688", "61689", "61693", "61695", "61700", "61701", "61702", "61706", "61707", "61708", "61711", "61712", "61713", "61714", "61715", "61716", "61720", "61721", "61722", "61724", "61729", "61730", "61731", "61735", "61736", "61737", "61738", "61743", "61744", "61746", "61754", "61757", "61759", "61763", "61765", "61766", "61769", "61770", "61771", "61772", "61774", "61775", "61776", "61778", "61779", "61780", "61781", "61787", "61789", "61791", "61792", "61793", "61799", "61800", "61801", "61807", "61808", "61809", "61815", "61816", "61819", "61823", "61825", "61827", "61828", "61831", "61833", "61836", "61838", "61840", "61842", "61843", "61844", "61846", "61848", "61849", "61850", "61854", "61855", "61858", "61859", "61860", "61861", "61863", "61865", "61868", "61869", "61874", "61877", "61879", "61881", "61882", "61883", "61884", "61886", "61890", "61892", "61896", "61898", "61900", "61901", "61904", "61905", "61909", "61910", "61912", "61913", "61916", "61918", "61924", "61925", "61926", "61928", "61929", "61930", "61931", "61932", "61933", "61935", "61936", "61942", "61947", "61949", "61952", "61955", "61957", "61958", "61962", "61965", "61966", "61969", "61971", "61973", "61974", "61976", "61977", "61979", "61980", "61984", "61987", "61989", "61991", "61992", "61996", "62003", "62006", "62007", "62008", "62012", "62014", "62016", "62017", "62018", "62020", "62025", "62032", "62033", "62034", "62036", "62037", "62040", "62041", "62042", "62043", "62046", "62048", "62052", "62054", "62055", "62056", "62058", "62059", "62060", "62061", "62062", "62063", "62066", "62068", "62069", "62071", "62072", "62073", "62074", "62076", "62077", "62078", "62079", "62084", "62086", "62089", "62093", "62096", "62097", "62101", "62102", "62103", "62105", "62107", "62109", "62111", "62112", "62114", "62115", "62117", "62121", "62122", "62123", "62125", "62127", "62128", "62130", "62131", "62133", "62134", "62136", "62139", "62142", "62144", "62145", "62148", "62149", "62150", "62152", "62154", "62155", "62158", "62159", "62160", "62162", "62163", "62164", "62165", "62167", "62169", "62170", "62171", "62172", "62173", "62175", "62176", "62181", "62185", "62186", "62187", "62189", "62190", "62191", "62192", "62194", "62198", "62200", "62202", "62204", "62205", "62206", "62208", "62209", "62210", "62213", "62214", "62215", "62217", "62218", "62219", "62220", "62221", "62223", "62228", "62230", "62233", "62234", "62235", "62237", "62238", "62239", "62242", "62245", "62248", "62249", "62250", "62251", "62253", "62254", "62257", "62258", "62262", "62263", "62266", "62268", "62269", "62270", "62274", "62279", "62280", "62282", "62284", "62286", "62290", "62293", "62295", "62296", "62298", "62300", "62301", "62302", "62303", "62307", "62308", "62312", "62316", "62317", "62320", "62325", "62326", "62327", "62328", "62329", "62330", "62331", "62332", "62333", "62334", "62336", "62339", "62340", "62342", "62344", "62345", "62347", "62348", "62350", "62351", "62353", "62355", "62357", "62358", "62361", "62364", "62367", "62370", "62371", "62373", "62375", "62377", "62378", "62379", "62380", "62385", "62386", "62389", "62390", "62392", "62393", "62394", "62395", "62398", "62401", "62403", "62406", "62412", "62414", "62418", "62424", "62426", "62427", "62428", "62429", "62433", "62434", "62436", "62439", "62440", "62441", "62442", "62443", "62446", "62447", "62448", "62450", "62452", "62456", "62458", "62462", "62463", "62464", "62466", "62469", "62471", "62474", "62476", "62478", "62479", "62482", "62484", "62489", "62492", "62493", "62494", "62496", "62498", "62499", "62500", "62501", "62503", "62504", "62506", "62508", "62509", "62510", "62514", "62517", "62518", "62519", "62523", "62525", "62526", "62527", "62528", "62533", "62535", "62538", "62541", "62544", "62548", "62550", "62553", "62554", "62555", "62556", "62558", "62562", "62564", "62565", "62566", "62567", "62569", "62570", "62572", "62575", "62576", "62577", "62578", "62579", "62581", "62583", "62584", "62586", "62588", "62589", "62590", "62591", "62594", "62596", "62600", "62601", "62602", "62605", "62607", "62608", "62610", "62612", "62615", "62616", "62617", "62618", "62620", "62624", "62628", "62633", "62635", "62636", "62637", "62639", "62640", "62641", "62642", "62643", "62645", "62647", "62650", "62653", "62654", "62656", "62658", "62660", "62662", "62663", "62665", "62666", "62669", "62671", "62672", "62673", "62674", "62675", "62677", "62678", "62681", "62682", "62683", "62685", "62688", "62689", "62690", "62691", "62695", "62697", "62698", "62700", "62701", "62702", "62704", "62705", "62706", "62708", "62710", "62711", "62713", "62714", "62715", "62718", "62719", "62720", "62722", "62723", "62726", "62728", "62730", "62731", "62732", "62735", "62737", "62738", "62739", "62741", "62742", "62743", "62744", "62745", "62746", "62747", "62750", "62752", "62754", "62756", "62760", "62762", "62763", "62770", "62774", "62775", "62781", "62784", "62786", "62789", "62790", "62791", "62796", "62802", "62803", "62804", "62805", "62808", "62810", "62811", "62813", "62817", "62820", "62821", "62824", "62827", "62829", "62831", "62833", "62834", "62835", "62837", "62838", "62839", "62840", "62841", "62843", "62845", "62846", "62847", "62849", "62851", "62853", "62854", "62860", "62861", "62862", "62864", "62867", "62868", "62870", "62873", "62877", "62881", "62882", "62884", "62887", "62889", "62891", "62893", "62895", "62896", "62897", "62900", "62903", "62904", "62905", "62907", "62912", "62915", "62918", "62919", "62921", "62922", "62923", "62927", "62929", "62931", "62932", "62934", "62936", "62940", "62943", "62944", "62945", "62947", "62951", "62952", "62957", "62961", "62962", "62968", "62970", "62971", "62972", "62973", "62974", "62976", "62977", "62979", "62980", "62984", "62988", "62989", "62991", "62993", "62994", "62995", "62996", "62997", "62998", "63000", "63002", "63007", "63010", "63012", "63014", "63015", "63016", "63020", "63021", "63024", "63027", "63029", "63030", "63031", "63033", "63036", "63045", "63047", "63048", "63050", "63052", "63053", "63054", "63055", "63056", "63057", "63058", "63059", "63061", "63062", "63063", "63065", "63067", "63068", "63069", "63070", "63073", "63074", "63075", "63077", "63080", "63081", "63084", "63085", "63090", "63092", "63095", "63101", "63105", "63106", "63108", "63109", "63111", "63115", "63118", "63119", "63120", "63121", "63122", "63124", "63125", "63130", "63131", "63132", "63133", "63135", "63139", "63141", "63142", "63144", "63149", "63150", "63151", "63153", "63156", "63157", "63159", "63160", "63162", "63163", "63164", "63166", "63168", "63169", "63173", "63177", "63178", "63179", "63180", "63182", "63183", "63185", "63186", "63187", "63189", "63190", "63191", "63194", "63197", "63198", "63199", "63201", "63203", "63205", "63206", "63207", "63208", "63209", "63210", "63211", "63213", "63215", "63216", "63217", "63218", "63221", "63222", "63224", "63226", "63227", "63228", "63229", "63232", "63234", "63236", "63240", "63241", "63242", "63243", "63244", "63245", "63251", "63253", "63255", "63256", "63260", "63261", "63264", "63268", "63270", "63271", "63272", "63276", "63282", "63286", "63288", "63292", "63293", "63294", "63297", "63305", "63308", "63309", "63313", "63316", "63320", "63321", "63325", "63327", "63329", "63333", "63334", "63335", "63339", "63340", "63345", "63346", "63348", "63350", "63353", "63355", "63356", "63359", "63360", "63361", "63362", "63363", "63367", "63368", "63370", "63371", "63372", "63376", "63377", "63379", "63380", "63384", "63388", "63389", "63391", "63393", "63394", "63397", "63399", "63403", "63405", "63406", "63407", "63410", "63411", "63412", "63413", "63415", "63416", "63417", "63418", "63419", "63420", "63422", "63423", "63424", "63428", "63429", "63430", "63431", "63433", "63437", "63438", "63439", "63443", "63445", "63451", "63454", "63456", "63457", "63460", "63461", "63463", "63464", "63465", "63469", "63470", "63471", "63472", "63475", "63477", "63478", "63479", "63481", "63484", "63485", "63486", "63487", "63488", "63491", "63492", "63494", "63499", "63500", "63501", "63502", "63503", "63504", "63505", "63506", "63508", "63509", "63510", "63511", "63512", "63514", "63516", "63517", "63519", "63520", "63521", "63526", "63529", "63531", "63532", "63534", "63536", "63540", "63541", "63542", "63545", "63546", "63547", "63548", "63551", "63553", "63554", "63556", "63563", "63565", "63569", "63571", "63572", "63575", "63576", "63577", "63578", "63579", "63581", "63582", "63583", "63587", "63588", "63589", "63590", "63594", "63595", "63597", "63599", "63601", "63603", "63605", "63606", "63611", "63617", "63618", "63619", "63620", "63622", "63627", "63628", "63629", "63630", "63631", "63632", "63634", "63635", "63636", "63637", "63638", "63640", "63641", "63643", "63644", "63645", "63646", "63647", "63648", "63651", "63652", "63659", "63661", "63666", "63668", "63670", "63673", "63679", "63683", "63684", "63685", "63686", "63687", "63689", "63693", "63696", "63697", "63699", "63700", "63701", "63702", "63703", "63704", "63706", "63709", "63710", "63711", "63715", "63719", "63720", "63722", "63724", "63729", "63731", "63735", "63737", "63740", "63744", "63746", "63751", "63753", "63755", "63756", "63758", "63760", "63761", "63762", "63763", "63766", "63768", "63769", "63773", "63778", "63780", "63782", "63784", "63785", "63786", "63787", "63788", "63791", "63794", "63795", "63796", "63798", "63800", "63803", "63807", "63810", "63812", "63813", "63818", "63819", "63820", "63821", "63823", "63824", "63825", "63828", "63830", "63831", "63832", "63834", "63835", "63838", "63840", "63843", "63852", "63855", "63856", "63858", "63862", "63863", "63864", "63866", "63870", "63875", "63876", "63877", "63881", "63885", "63887", "63890", "63891", "63892", "63893", "63895", "63897", "63904", "63907", "63908", "63909", "63912", "63913", "63914", "63915", "63916", "63917", "63920", "63929", "63934", "63936", "63942", "63943", "63948", "63949", "63950", "63952", "63954", "63955", "63956", "63960", "63961", "63965", "63966", "63969", "63972", "63977", "63978", "63983", "63984", "63987", "63992", "63995", "63996", "63999", "64001", "64003", "64004", "64007", "64008", "64011", "64012", "64013", "64014", "64017", "64018", "64020", "64021", "64023", "64024", "64026", "64030", "64032", "64033", "64035", "64036", "64037", "64040", "64043", "64047", "64049", "64050", "64055", "64056", "64057", "64062", "64064", "64066", "64068", "64069", "64070", "64071", "64075", "64077", "64081", "64084", "64086", "64087", "64089", "64091", "64092", "64094", "64098", "64099", "64100", "64105", "64106", "64108", "64109", "64110", "64111", "64115", "64116", "64117", "64118", "64120", "64121", "64124", "64126", "64127", "64130", "64131", "64132", "64134", "64138", "64141", "64142", "64143", "64144", "64145", "64147", "64150", "64153", "64154", "64155", "64157", "64158", "64159", "64162", "64163", "64169", "64170", "64175", "64179", "64180", "64181", "64182", "64184", "64187", "64188", "64189", "64190", "64193", "64194", "64195", "64196", "64198", "64199", "64200", "64204", "64206", "64207", "64208", "64209", "64211", "64212", "64214", "64215", "64217", "64218", "64224", "64225", "64228", "64230", "64233", "64235", "64238", "64239", "64242", "64243", "64244", "64245", "64246", "64251", "64253", "64254", "64257", "64258", "64259", "64260", "64261", "64262", "64263", "64264", "64268", "64269", "64270", "64271", "64272", "64275", "64276", "64277", "64278", "64280", "64281", "64282", "64283", "64284", "64286", "64287", "64290", "64292", "64293", "64295", "64298", "64299", "64301", "64303", "64304", "64306", "64307", "64311", "64312", "64315", "64318", "64321", "64323", "64331", "64333", "64337", "64339", "64340", "64342", "64344", "64348", "64349", "64350", "64351", "64353", "64355", "64356", "64357", "64359", "64364", "64365", "64367", "64368", "64369", "64370", "64372", "64376", "64379", "64381", "64386", "64387", "64388", "64389", "64391", "64392", "64394", "64395", "64397", "64398", "64400", "64401", "64405", "64408", "64414", "64416", "64418", "64419", "64421", "64422", "64423", "64424", "64430", "64431", "64437", "64440", "64442", "64445", "64448", "64449", "64450", "64452", "64453", "64454", "64456", "64457", "64459", "64460", "64461", "64464", "64465", "64466", "64467", "64469", "64471", "64472", "64473", "64475", "64477", "64479", "64481", "64484", "64487", "64490", "64491", "64492", "64493", "64498", "64499", "64503", "64505", "64508", "64509", "64510", "64515", "64518", "64519", "64525", "64526", "64527", "64529", "64531", "64532", "64533", "64536", "64538", "64544", "64548", "64550", "64553", "64554", "64555", "64557", "64558", "64559", "64561", "64563", "64564", "64567", "64568", "64569", "64570", "64573", "64574", "64576", "64578", "64579", "64580", "64582", "64586", "64587", "64591", "64592", "64594", "64595", "64596", "64599", "64600", "64603", "64606", "64607", "64608", "64609", "64611", "64612", "64616", "64617", "64618", "64619", "64621", "64622", "64623", "64624", "64627", "64629", "64632", "64633", "64634", "64640", "64641", "64642", "64643", "64648", "64655", "64660", "64661", "64663", "64664", "64667", "64670", "64673", "64675", "64679", "64682", "64684", "64685", "64688", "64692", "64693", "64694", "64695", "64699", "64702", "64704", "64705", "64706", "64707", "64708", "64711", "64712", "64714", "64717", "64721", "64724", "64726", "64727", "64730", "64731", "64732", "64733", "64734", "64735", "64736", "64738", "64739", "64741", "64744", "64745", "64746", "64747", "64751", "64752", "64760", "64762", "64763", "64765", "64767", "64768", "64770", "64771", "64773", "64775", "64776", "64777", "64778", "64779", "64782", "64786", "64787", "64788", "64791", "64792", "64793", "64797", "64798", "64799", "64801", "64809", "64810", "64812", "64813", "64814", "64815", "64818", "64819", "64823", "64824", "64825", "64827", "64831", "64834", "64835", "64836", "64837", "64839", "64840", "64843", "64850", "64853", "64854", "64859", "64864", "64865", "64866", "64868", "64872", "64873", "64874", "64875", "64877", "64881", "64883", "64887", "64890", "64891", "64893", "64895", "64896", "64897", "64898", "64900", "64901", "64904", "64908", "64911", "64914", "64915", "64918", "64919", "64920", "64921", "64922", "64923", "64924", "64928", "64929", "64931", "64933", "64934", "64936", "64940", "64941", "64942", "64945", "64946", "64947", "64950", "64952", "64953", "64957", "64958", "64962", "64965", "64966", "64968", "64969", "64971", "64977", "64978", "64980", "64982", "64983", "64984", "64987", "64989", "64990", "64991", "64994", "64996", "64998", "64999", "65000", "65001", "65004", "65006", "65009", "65014", "65017", "65019", "65020", "65022", "65023", "65024", "65025", "65029", "65031", "65032", "65034", "65035", "65039", "65041", "65042", "65045", "65046", "65048", "65049", "65050", "65051", "65056", "65057", "65058", "65061", "65064", "65065", "65066", "65072", "65073", "65076", "65079", "65080", "65081", "65083", "65084", "65086", "65087", "65088", "65090", "65091", "65096", "65097", "65099", "65100", "65101", "65104", "65105", "65108", "65109", "65110", "65113", "65116", "65118", "65121", "65122", "65123", "65127", "65129", "65130", "65135", "65136", "65140", "65141", "65150", "65151", "65157", "65158", "65159", "65160", "65161", "65164", "65167", "65169", "65171", "65173", "65175", "65177", "65179", "65180", "65181", "65184", "65186", "65187", "65188", "65189", "65190", "65191", "65193", "65196", "65197", "65198", "65199", "65201", "65204", "65205", "65207", "65208", "65219", "65222", "65226", "65227", "65230", "65231", "65232", "65233", "65236", "65237", "65238", "65239", "65240", "65243", "65245", "65247", "65248", "65253", "65259", "65260", "65261", "65263", "65264", "65265", "65266", "65268", "65271", "65273", "65275", "65276", "65281", "65282", "65288", "65289", "65293", "65298", "65299", "65300", "65301", "65303", "65305", "65307", "65313", "65316", "65317", "65318", "65319", "65321", "65326", "65328", "65330", "65331", "65332", "65334", "65340", "65341", "65344", "65345", "65346", "65347", "65354", "65355", "65357", "65361", "65363", "65366", "65367", "65368", "65369", "65370", "65371", "65374", "65376", "65379", "65380", "65383", "65384", "65385", "65387", "65388", "65391", "65393", "65394", "65396", "65397", "65398", "65400", "65401", "65402", "65405", "65409", "65411", "65412", "65413", "65414", "65415", "65416", "65418", "65419", "65422", "65423", "65427", "65428", "65429", "65432", "65434", "65436", "65437", "65438", "65443", "65446", "65452", "65453", "65454", "65460", "65462", "65463", "65466", "65467", "65468", "65470", "65472", "65473", "65475", "65477", "65478", "65480", "65481", "65483", "65485", "65489", "65490", "65498", "65499", "65500", "65501", "65502", "65504", "65505", "65507", "65509", "65510", "65511", "65512", "65514", "65515", "65518", "65519", "65520", "65523", "65525", "65526", "65528", "65530", "65531", "65532", "65535", "65536", "65538", "65539", "65540", "65541", "65542", "65543", "65545", "65547", "65549", "65550", "65551", "65552", "65559", "65560", "65561", "65565", "65566", "65569", "65570", "65572", "65573", "65577", "65578", "65579", "65583", "65584", "65585", "65591", "65593", "65594", "65595", "65596", "65599", "65600", "65602", "65604", "65605", "65606", "65607", "65608", "65609", "65610", "65616", "65617", "65619", "65621", "65626", "65627", "65628", "65630", "65631", "65632", "65635", "65636", "65637", "65638", "65640", "65642", "65643", "65645", "65646", "65652", "65656", "65657", "65661", "65662", "65663", "65664", "65667", "65670", "65673", "65674", "65675", "65677", "65680", "65681", "65682", "65683", "65684", "65689", "65690", "65693", "65696", "65697", "65698", "65702", "65705", "65709", "65711", "65712", "65713", "65714", "65716", "65719", "65721", "65723", "65728", "65729", "65730", "65731", "65732", "65735", "65736", "65739", "65741", "65744", "65747", "65748", "65749", "65752", "65753", "65754", "65757", "65761", "65762", "65763", "65765", "65766", "65768", "65769", "65771", "65772", "65775", "65776", "65780", "65781", "65783", "65784", "65785", "65786", "65787", "65788", "65789", "65791", "65794", "65796", "65798", "65799", "65800", "65802", "65804", "65806", "65808", "65809", "65810", "65812", "65814", "65817", "65818", "65819", "65820", "65821", "65822", "65826", "65828", "65831", "65832", "65833", "65835", "65837", "65838", "65839", "65842", "65844", "65845", "65850", "65851", "65853", "65856", "65859", "65864", "65865", "65867", "65868", "65872", "65873", "65874", "65875", "65876", "65877", "65878", "65879", "65880", "65881", "65882", "65883", "65884", "65885", "65889", "65890", "65891", "65892", "65897", "65899", "65901", "65903", "65904", "65909", "65911", "65914", "65916", "65919", "65920", "65923", "65925", "65927", "65930", "65931", "65932", "65934", "65935", "65936", "65939", "65940", "65942", "65943", "65944", "65945", "65949", "65951", "65953", "65954", "65956", "65958", "65960", "65961", "65963", "65964", "65965", "65966", "65968", "65969", "65972", "65974", "65975", "65977", "65978", "65980", "65981", "65984", "65986", "65988", "65991", "65992", "65993", "65994", "65995", "65997", "65998", "65999", "66001", "66003", "66007", "66008", "66009", "66010", "66011", "66013", "66018", "66020", "66021", "66022", "66026", "66028", "66029", "66031", "66033", "66035", "66037", "66039", "66040", "66041", "66042", "66043", "66044", "66045", "66047", "66050", "66051", "66055", "66058", "66059", "66062", "66063", "66065", "66068", "66071", "66073", "66077", "66088", "66094", "66097", "66101", "66102", "66106", "66108", "66109", "66111", "66114", "66115", "66117", "66118", "66120", "66123", "66124", "66125", "66127", "66134", "66135", "66136", "66137", "66138", "66140", "66141", "66142", "66144", "66147", "66152", "66157", "66159", "66160", "66161", "66162", "66163", "66166", "66167", "66170", "66171", "66173", "66174", "66176", "66180", "66182", "66184", "66185", "66187", "66188", "66191", "66194", "66195", "66196", "66197", "66199", "66203", "66205", "66208", "66209", "66210", "66213", "66215", "66217", "66220", "66221", "66224", "66227", "66230", "66231", "66232", "66233", "66234", "66235", "66237", "66239", "66240", "66243", "66246", "66248", "66249", "66251", "66253", "66254", "66255", "66256", "66260", "66261", "66263", "66264", "66266", "66269", "66270", "66276", "66277", "66278", "66281", "66286", "66288", "66292", "66293", "66295", "66297", "66302", "66303", "66304", "66308", "66309", "66310", "66311", "66312", "66314", "66315", "66316", "66317", "66318", "66319", "66320", "66322", "66323", "66326", "66327", "66329", "66330", "66331", "66334", "66336", "66337", "66338", "66341", "66343", "66344", "66345", "66347", "66348", "66352", "66358", "66364", "66365", "66366", "66367", "66368", "66369", "66372", "66376", "66379", "66380", "66381", "66382", "66386", "66387", "66388", "66390", "66391", "66397", "66398", "66399", "66400", "66401", "66405", "66408", "66410", "66412", "66413", "66414", "66416", "66417", "66418", "66419", "66420", "66422", "66423", "66424", "66425", "66426", "66427", "66428", "66429", "66434", "66436", "66438", "66439", "66440", "66441", "66442", "66445", "66451", "66452", "66454", "66455", "66458", "66459", "66460", "66462", "66463", "66464", "66466", "66468", "66469", "66472", "66473", "66474", "66476", "66477", "66480", "66483", "66489", "66494", "66495", "66497", "66500", "66502", "66505", "66511", "66515", "66518", "66519", "66520", "66522", "66524", "66525", "66530", "66531", "66532", "66533", "66535", "66538", "66539", "66540", "66541", "66542", "66543", "66544", "66545", "66546", "66548", "66550", "66551", "66552", "66553", "66558", "66562", "66563", "66569", "66575", "66576", "66577", "66580", "66584", "66586", "66587", "66588", "66589", "66592", "66594", "66597", "66600", "66603", "66605", "66607", "66612", "66613", "66615", "66618", "66619", "66620", "66624", "66626", "66627", "66628", "66629", "66630", "66633", "66634", "66636", "66639", "66642", "66645", "66647", "66649", "66651", "66656", "66657", "66658", "66661", "66662", "66663", "66664", "66665", "66666", "66672", "66675", "66676", "66680", "66681", "66682", "66684", "66685", "66689", "66691", "66692", "66694", "66696", "66698", "66700", "66702", "66705", "66706", "66709", "66710", "66713", "66717", "66719", "66722", "66727", "66731", "66736", "66738", "66739", "66740", "66741", "66742", "66743", "66744", "66746", "66747", "66751", "66754", "66756", "66758", "66761", "66763", "66765", "66767", "66768", "66769", "66770", "66772", "66774", "66776", "66777", "66778", "66779", "66782", "66783", "66785", "66789", "66792", "66793", "66794", "66796", "66797", "66798", "66799", "66802", "66805", "66806", "66813", "66817", "66819", "66820", "66822", "66824", "66825", "66827", "66828", "66832", "66838", "66840", "66841", "66842", "66843", "66844", "66845", "66848", "66850", "66854", "66856", "66857", "66858", "66859", "66861", "66862", "66863", "66865", "66866", "66867", "66873", "66876", "66877", "66882", "66887", "66888", "66894", "66898", "66900", "66906", "66910", "66911", "66913", "66915", "66916", "66918", "66919", "66920", "66922", "66923", "66926", "66929", "66930", "66933", "66934", "66939", "66940", "66944", "66945", "66948", "66950", "66953", "66958", "66960", "66962", "66964", "66966", "66967", "66968", "66969", "66970", "66975", "66978", "66980", "66981", "66982", "66983", "66984", "66988", "66989", "66993", "66994", "66996", "66998", "67000", "67001", "67002", "67003", "67004", "67005", "67006", "67007", "67008", "67009", "67010", "67011", "67012", "67013", "67014", "67015", "67016", "67018", "67019", "67021", "67027", "67028", "67031", "67034", "67035", "67037", "67038", "67039", "67041", "67042", "67046", "67048", "67049", "67051", "67053", "67059", "67060", "67063", "67065", "67066", "67067", "67068", "67069", "67070", "67072", "67076", "67079", "67081", "67083", "67084", "67085", "67087", "67092", "67093", "67096", "67097", "67099", "67100", "67101", "67102", "67103", "67106", "67107", "67110", "67111", "67113", "67115", "67116", "67117", "67118", "67120", "67122", "67123", "67124", "67125", "67127", "67128", "67133", "67135", "67136", "67137", "67140", "67142", "67143", "67145", "67147", "67150", "67151", "67154", "67156", "67159", "67161", "67164", "67166", "67167", "67170", "67171", "67178", "67179", "67180", "67183", "67188", "67195", "67196", "67198", "67201", "67202", "67205", "67209", "67212", "67220", "67221", "67223", "67225", "67227", "67230", "67231", "67232", "67233", "67236", "67237", "67238", "67239", "67241", "67242", "67246", "67250", "67251", "67256", "67257", "67258", "67259", "67260", "67261", "67263", "67264", "67265", "67267", "67269", "67270", "67272", "67273", "67275", "67278", "67280", "67281", "67282", "67287", "67288", "67293", "67294", "67296", "67300", "67305", "67306", "67307", "67308", "67311", "67312", "67314", "67315", "67316", "67321", "67323", "67325", "67327", "67328", "67330", "67331", "67333", "67334", "67335", "67336", "67337", "67339", "67340", "67342", "67343", "67345", "67348", "67349", "67351", "67353", "67355", "67360", "67361", "67362", "67364", "67367", "67368", "67369", "67374", "67377", "67382", "67383", "67386", "67389", "67390", "67391", "67393", "67397", "67398", "67399", "67406", "67407", "67408", "67411", "67413", "67415", "67418", "67420", "67422", "67424", "67425", "67428", "67429", "67430", "67432", "67434", "67435", "67436", "67438", "67440", "67444", "67445", "67447", "67449", "67450", "67451", "67452", "67455", "67456", "67457", "67458", "67459", "67464", "67469", "67470", "67471", "67473", "67474", "67476", "67477", "67478", "67481", "67482", "67484", "67489", "67490", "67492", "67493", "67495", "67496", "67497", "67498", "67499", "67501", "67504", "67505", "67506", "67508", "67509", "67511", "67517", "67519", "67520", "67522", "67524", "67525", "67528", "67532", "67538", "67539", "67540", "67541", "67546", "67549", "67550", "67552", "67553", "67555", "67557", "67558", "67559", "67560", "67561", "67564", "67567", "67568", "67571", "67574", "67576", "67581", "67583", "67584", "67585", "67587", "67593", "67595", "67597", "67598", "67600", "67602", "67603", "67607", "67610", "67611", "67612", "67613", "67614", "67616", "67618", "67621", "67623", "67628", "67631", "67632", "67633", "67634", "67635", "67637", "67638", "67642", "67644", "67645", "67646", "67647", "67650", "67653", "67654", "67659", "67662", "67663", "67664", "67666", "67667", "67668", "67670", "67671", "67674", "67677", "67680", "67681", "67683", "67684", "67686", "67687", "67689", "67690", "67691", "67692", "67694", "67695", "67696", "67697", "67699", "67700", "67704", "67705", "67706", "67708", "67711", "67713", "67714", "67715", "67717", "67718", "67720", "67722", "67725", "67727", "67730", "67732", "67733", "67734", "67736", "67737", "67738", "67739", "67740", "67742", "67745", "67748", "67749", "67750", "67752", "67754", "67756", "67758", "67760", "67763", "67764", "67766", "67767", "67768", "67769", "67771", "67772", "67773", "67774", "67779", "67780", "67785", "67786", "67787", "67789", "67794", "67795", "67796", "67797", "67799", "67800", "67803", "67807", "67808", "67811", "67812", "67816", "67833", "67835", "67837", "67838", "67842", "67843", "67845", "67846", "67847", "67848", "67854", "67855", "67856", "67857", "67858", "67860", "67861", "67863", "67865", "67866", "67867", "67870", "67874", "67876", "67877", "67879", "67880", "67884", "67885", "67886", "67887", "67889", "67890", "67892", "67893", "67894", "67896", "67897", "67899", "67900", "67901", "67902", "67903", "67905", "67906", "67907", "67908", "67910", "67912", "67913", "67915", "67917", "67919", "67920", "67922", "67923", "67924", "67925", "67926", "67928", "67930", "67934", "67935", "67936", "67939", "67940", "67941", "67942", "67945", "67947", "67955", "67957", "67958", "67960", "67961", "67962", "67963", "67965", "67966", "67967", "67969", "67970", "67973", "67974", "67980", "67982", "67983", "67984", "67990", "67992", "67994", "67995", "67998", "68000", "68002", "68004", "68006", "68009", "68013", "68015", "68017", "68018", "68024", "68025", "68027", "68033", "68034", "68037", "68038", "68040", "68041", "68043", "68046", "68048", "68049", "68050", "68051", "68052", "68055", "68057", "68058", "68062", "68063", "68071", "68072", "68073", "68075", "68076", "68079", "68084", "68085", "68087", "68088", "68089", "68090", "68093", "68095", "68097", "68098", "68099", "68100", "68101", "68103", "68106", "68114", "68116", "68117", "68119", "68120", "68121", "68128", "68130", "68132", "68133", "68134", "68135", "68136", "68137", "68139", "68141", "68143", "68144", "68145", "68148", "68149", "68150", "68151", "68153", "68154", "68156", "68157", "68158", "68160", "68163", "68164", "68167", "68171", "68172", "68174", "68175", "68176", "68181", "68182", "68183", "68184", "68188", "68190", "68192", "68193", "68194", "68198", "68200", "68208", "68210", "68212", "68213", "68218", "68219", "68223", "68225", "68226", "68227", "68230", "68234", "68235", "68236", "68237", "68239", "68241", "68243", "68252", "68253", "68257", "68258", "68259", "68260", "68261", "68262", "68263", "68264", "68272", "68274", "68282", "68283", "68286", "68287", "68288", "68289", "68291", "68292", "68293", "68296", "68297", "68304", "68306", "68309", "68312", "68313", "68314", "68315", "68316", "68317", "68318", "68320", "68322", "68327", "68332", "68333", "68334", "68335", "68341", "68342", "68343", "68345", "68347", "68348", "68352", "68354", "68356", "68357", "68358", "68364", "68366", "68370", "68371", "68373", "68374", "68379", "68382", "68383", "68384", "68387", "68389", "68390", "68392", "68393", "68396", "68398", "68399", "68403", "68405", "68408", "68412", "68415", "68421", "68423", "68428", "68431", "68433", "68434", "68436", "68438", "68439", "68440", "68442", "68443", "68444", "68446", "68451", "68456", "68457", "68461", "68463", "68467", "68468", "68469", "68474", "68475", "68476", "68478", "68480", "68482", "68483", "68484", "68485", "68488", "68489", "68490", "68491", "68492", "68495", "68500", "68502", "68503", "68506", "68509", "68512", "68514", "68515", "68517", "68522", "68524", "68525", "68526", "68527", "68528", "68530", "68533", "68535", "68536", "68537", "68539", "68540", "68541", "68543", "68545", "68546", "68548", "68549", "68551", "68552", "68553", "68555", "68556", "68557", "68558", "68559", "68560", "68563", "68566", "68569", "68572", "68574", "68575", "68577", "68578", "68580", "68582", "68585", "68588", "68589", "68590", "68592", "68593", "68595", "68598", "68599", "68601", "68602", "68604", "68605", "68609", "68611", "68612", "68615", "68616", "68618", "68621", "68622", "68624", "68626", "68627", "68629", "68630", "68631", "68632", "68633", "68639", "68641", "68644", "68649", "68654", "68655", "68663", "68664", "68667", "68668", "68669", "68670", "68673", "68675", "68676", "68677", "68680", "68681", "68683", "68684", "68688", "68690", "68691", "68694", "68697", "68699", "68702", "68704", "68705", "68707", "68709", "68711", "68712", "68715", "68716", "68720", "68722", "68724", "68726", "68730", "68731", "68732", "68734", "68735", "68736", "68737", "68738", "68740", "68741", "68743", "68745", "68746", "68747", "68748", "68749", "68750", "68751", "68753", "68756", "68757", "68758", "68760", "68761", "68763", "68767", "68768", "68774", "68777", "68781", "68782", "68783", "68784", "68788", "68790", "68792", "68794", "68798", "68802", "68804", "68807", "68808", "68811", "68813", "68815", "68816", "68818", "68819", "68821", "68823", "68826", "68827", "68828", "68830", "68831", "68832", "68833", "68835", "68837", "68838", "68839", "68840", "68842", "68843", "68845", "68847", "68848", "68854", "68855", "68857", "68858", "68859", "68860", "68863", "68866", "68868", "68869", "68870", "68871", "68874", "68878", "68879", "68882", "68883", "68884", "68885", "68886", "68887", "68889", "68891", "68895", "68897", "68898", "68900", "68902", "68903", "68905", "68906", "68907", "68908", "68909", "68910", "68912", "68913", "68914", "68915", "68918", "68919", "68921", "68926", "68928", "68929", "68932", "68936", "68938", "68939", "68940", "68943", "68945", "68946", "68948", "68949", "68951", "68953", "68959", "68960", "68961", "68964", "68965", "68968", "68969", "68970", "68972", "68974", "68978", "68980", "68981", "68982", "68984", "68985", "68987", "68988", "68991", "68996", "68997", "68998", "69000", "69002", "69003", "69004", "69005", "69006", "69007", "69010", "69011", "69013", "69015", "69019", "69021", "69022", "69023", "69026", "69028", "69029", "69031", "69033", "69034", "69035", "69037", "69038", "69040", "69041", "69045", "69047", "69049", "69050", "69052", "69055", "69056", "69059", "69060", "69061", "69062", "69069", "69073", "69074", "69076", "69078", "69079", "69080", "69082", "69083", "69088", "69089", "69091", "69095", "69096", "69097", "69098", "69101", "69103", "69104", "69105", "69107", "69111", "69112", "69113", "69115", "69117", "69118", "69120", "69121", "69124", "69125", "69131", "69133", "69134", "69135", "69138", "69143", "69145", "69146", "69147", "69148", "69154", "69155", "69156", "69158", "69159", "69161", "69165", "69166", "69168", "69169", "69170", "69172", "69175", "69176", "69179", "69182", "69184", "69187", "69190", "69191", "69192", "69193", "69200", "69213", "69216", "69217", "69219", "69223", "69224", "69225", "69227", "69230", "69232", "69233", "69235", "69239", "69240", "69241", "69242", "69247", "69248", "69249", "69251", "69252", "69253", "69259", "69260", "69261", "69262", "69264", "69267", "69268", "69269", "69273", "69275", "69276", "69277", "69278", "69279", "69280", "69281", "69282", "69283", "69284", "69285", "69289", "69291", "69293", "69295", "69296", "69306", "69307", "69308", "69309", "69313", "69314", "69315", "69319", "69321", "69322", "69327", "69331", "69334", "69335", "69336", "69337", "69338", "69339", "69340", "69341", "69343", "69348", "69351", "69354", "69357", "69359", "69363", "69367", "69373", "69376", "69377", "69378", "69379", "69380", "69381", "69382", "69383", "69384", "69387", "69389", "69390", "69392", "69393", "69394", "69395", "69397", "69398", "69399", "69400", "69401", "69402", "69404", "69407", "69408", "69409", "69414", "69416", "69417", "69418", "69424", "69425", "69426", "69429", "69430", "69431", "69435", "69437", "69438", "69439", "69442", "69444", "69445", "69448", "69450", "69452", "69454", "69460", "69461", "69462", "69466", "69468", "69470", "69471", "69473", "69475", "69476", "69479", "69480", "69481", "69484", "69485", "69486", "69487", "69488", "69489", "69493", "69494", "69495", "69496", "69497", "69498", "69500", "69502", "69503", "69504", "69506", "69507", "69508", "69509", "69510", "69511", "69513", "69514", "69516", "69517", "69518", "69519", "69520", "69522", "69524", "69525", "69526", "69527", "69528", "69529", "69531", "69534", "69535", "69536", "69538", "69543", "69545", "69546", "69548", "69554", "69555", "69556", "69557", "69558", "69559", "69560", "69563", "69564", "69567", "69570", "69572", "69574", "69576", "69579", "69582", "69585", "69586", "69590", "69591", "69593", "69594", "69599", "69601", "69602", "69604", "69606", "69608", "69609", "69610", "69611", "69612", "69618", "69621", "69630", "69632", "69633", "69634", "69635", "69636", "69637", "69638", "69640", "69641", "69642", "69643", "69646", "69648", "69649", "69650", "69651", "69653", "69657", "69658", "69659", "69660", "69661", "69662", "69663", "69665", "69666", "69669", "69671", "69672", "69677", "69679", "69680", "69682", "69684", "69687", "69688", "69690", "69691", "69692", "69696", "69700", "69702", "69704", "69705", "69707", "69708", "69709", "69710", "69712", "69718", "69720", "69726", "69730", "69731", "69732", "69734", "69739", "69740", "69741", "69742", "69745", "69746", "69748", "69750", "69751", "69752", "69753", "69755", "69756", "69757", "69758", "69761", "69762", "69765", "69768", "69769", "69771", "69773", "69774", "69777", "69782", "69784", "69785", "69786", "69789", "69790", "69793", "69795", "69796", "69798", "69799", "69803", "69806", "69809", "69810", "69812", "69813", "69817", "69818", "69819", "69820", "69821", "69823", "69824", "69825", "69826", "69828", "69831", "69832", "69833", "69834", "69836", "69837", "69838", "69839", "69842", "69843", "69844", "69849", "69850", "69851", "69852", "69854", "69855", "69856", "69858", "69860", "69861", "69863", "69864", "69865", "69866", "69867", "69869", "69872", "69873", "69874", "69875", "69877", "69881", "69882", "69883", "69884", "69885", "69886", "69888", "69889", "69890", "69891", "69892", "69895", "69897", "69898", "69899", "69900", "69902", "69906", "69908", "69909", "69910", "69911", "69915", "69916", "69917", "69918", "69924", "69927", "69931", "69932", "69936", "69939", "69940", "69941", "69945", "69948", "69949", "69950", "69954", "69955", "69958", "69959", "69961", "69962", "69964", "69965", "69966", "69968", "69971", "69975", "69977", "69978", "69979", "69980", "69981", "69982", "69984", "69986", "69987", "69988", "69990", "69992", "69994", "69996", "69997", "69998", "70000", "70002", "70006", "70007", "70013", "70014", "70016", "70020", "70023", "70024", "70026", "70027", "70029", "70030", "70031", "70032", "70033", "70036", "70040", "70042", "70047", "70048", "70049", "70051", "70053", "70054", "70055", "70056", "70058", "70059", "70060", "70061", "70064", "70065", "70066", "70067", "70068", "70069", "70070", "70073", "70074", "70075", "70077", "70078", "70086", "70087", "70088", "70089", "70091", "70092", "70094", "70095", "70097", "70098", "70100", "70101", "70104", "70105", "70110", "70113", "70114", "70117", "70118", "70120", "70123", "70126", "70128", "70129", "70131", "70133", "70136", "70138", "70139", "70144", "70145", "70146", "70147", "70152", "70153", "70154", "70155", "70156", "70158", "70161", "70165", "70169", "70170", "70173", "70174", "70175", "70176", "70177", "70178", "70180", "70186", "70188", "70190", "70192", "70195", "70199", "70200", "70201", "70204", "70205", "70206", "70209", "70210", "70211", "70213", "70215", "70216", "70220", "70222", "70224", "70227", "70231", "70232", "70233", "70234", "70235", "70236", "70237", "70238", "70239", "70243", "70246", "70247", "70255", "70258", "70259", "70260", "70262", "70265", "70266", "70270", "70275", "70278", "70279", "70286", "70288", "70289", "70290", "70291", "70292", "70293", "70294", "70296", "70298", "70302", "70303", "70304", "70306", "70307", "70311", "70312", "70314", "70317", "70318", "70319", "70322", "70330", "70331", "70333", "70334", "70335", "70337", "70343", "70344", "70345", "70346", "70352", "70354", "70356", "70358", "70359", "70361", "70364", "70373", "70377", "70378", "70388", "70389", "70390", "70391", "70392", "70394", "70396", "70401", "70402", "70404", "70405", "70409", "70411", "70412", "70414", "70416", "70425", "70428", "70432", "70435", "70437", "70438", "70441", "70443", "70445", "70446", "70448", "70449", "70452", "70454", "70456", "70457", "70458", "70460", "70461", "70462", "70466", "70470", "70473", "70477", "70481", "70483", "70484", "70488", "70489", "70492", "70493", "70494", "70499", "70501", "70503", "70504", "70505", "70506", "70511", "70513", "70514", "70515", "70522", "70523", "70524", "70526", "70530", "70531", "70534", "70535", "70537", "70539", "70540", "70544", "70546", "70548", "70551", "70554", "70556", "70557", "70558", "70559", "70560", "70561", "70562", "70563", "70566", "70570", "70573", "70574", "70576", "70577", "70579", "70585", "70586", "70588", "70592", "70594", "70597", "70600", "70601", "70603", "70606", "70609", "70610", "70611", "70613", "70617", "70621", "70622", "70623", "70625", "70626", "70633", "70635", "70637", "70638", "70640", "70641", "70646", "70649", "70651", "70655", "70656", "70659", "70662", "70663", "70664", "70666", "70667", "70668", "70669", "70673", "70676", "70677", "70682", "70689", "70690", "70691", "70693", "70694", "70696", "70699", "70701", "70705", "70708", "70709", "70710", "70711", "70718", "70719", "70720", "70722", "70726", "70727", "70729", "70730", "70732", "70733", "70734", "70735", "70737", "70738", "70741", "70743", "70744", "70745", "70748", "70751", "70752", "70757", "70758", "70759", "70761", "70762", "70766", "70772", "70777", "70783", "70785", "70788", "70792", "70795", "70797", "70799", "70801", "70802", "70803", "70806", "70808", "70809", "70813", "70819", "70822", "70823", "70824", "70825", "70831", "70833", "70835", "70836", "70843", "70844", "70846", "70848", "70849", "70850", "70854", "70856", "70857", "70861", "70864", "70872", "70874", "70875", "70878", "70879", "70880", "70883", "70885", "70887", "70888", "70889", "70893", "70897", "70899", "70900", "70902", "70903", "70904", "70907", "70908", "70910", "70912", "70913", "70915", "70917", "70918", "70920", "70921", "70923", "70924", "70925", "70926", "70928", "70929", "70932", "70933", "70934", "70936", "70937", "70941", "70942", "70943", "70944", "70949", "70950", "70952", "70955", "70959", "70960", "70964", "70965", "70966", "70968", "70970", "70972", "70974", "70975", "70976", "70978", "70980", "70982", "70984", "70986", "70992", "70996", "70999", "71000", "71002", "71003", "71005", "71009", "71011", "71016", "71017", "71018", "71019", "71022", "71024", "71025", "71026", "71027", "71028", "71031", "71032", "71034", "71036", "71039", "71047", "71048", "71049", "71052", "71053", "71055", "71056", "71061", "71062", "71063", "71068", "71071", "71072", "71074", "71078", "71079", "71083", "71088", "71092", "71093", "71095", "71096", "71100", "71103", "71104", "71108", "71112", "71114", "71116", "71117", "71118", "71119", "71120", "71121", "71123", "71124", "71125", "71128", "71133", "71136", "71137", "71139", "71140", "71141", "71142", "71143", "71144", "71148", "71149", "71150", "71151", "71153", "71159", "71163", "71167", "71168", "71171", "71172", "71174", "71176", "71177", "71178", "71179", "71184", "71188", "71191", "71194", "71195", "71196", "71199", "71201", "71202", "71203", "71204", "71206", "71212", "71216", "71224", "71229", "71233", "71234", "71236", "71237", "71238", "71242", "71244", "71245", "71248", "71251", "71252", "71253", "71254", "71256", "71257", "71259", "71262", "71263", "71264", "71265", "71267", "71268", "71271", "71273", "71277", "71278", "71279", "71280", "71281", "71283", "71285", "71286", "71288", "71289", "71290", "71292", "71294", "71295", "71301", "71303", "71307", "71309", "71310", "71311", "71313", "71314", "71315", "71316", "71318", "71319", "71321", "71322", "71323", "71324", "71325", "71326", "71327", "71328", "71329", "71330", "71331", "71332", "71335", "71339", "71340", "71341", "71343", "71344", "71346", "71348", "71349", "71351", "71352", "71356", "71358", "71359", "71362", "71363", "71364", "71365", "71367", "71370", "71374", "71375", "71382", "71383", "71384", "71385", "71386", "71391", "71393", "71397", "71398", "71400", "71402", "71403", "71404", "71405", "71407", "71408", "71410", "71413", "71414", "71415", "71416", "71417", "71418", "71419", "71421", "71426", "71429", "71430", "71432", "71435", "71436", "71440", "71443", "71444", "71446", "71447", "71448", "71450", "71451", "71452", "71453", "71454", "71459", "71460", "71461", "71462", "71464", "71465", "71466", "71469", "71470", "71471", "71472", "71473", "71474", "71476", "71477", "71481", "71489", "71491", "71492", "71495", "71496", "71498", "71502", "71503", "71504", "71506", "71509", "71510", "71511", "71512", "71513", "71514", "71516", "71518", "71522", "71524", "71525", "71527", "71530", "71531", "71533", "71534", "71535", "71540", "71544", "71546", "71547", "71548", "71549", "71550", "71551", "71552", "71558", "71559", "71560", "71563", "71569", "71572", "71573", "71574", "71575", "71580", "71589", "71590", "71591", "71594", "71597", "71600", "71602", "71606", "71607", "71608", "71611", "71612", "71614", "71616", "71619", "71620", "71622", "71624", "71626", "71629", "71633", "71638", "71640", "71646", "71648", "71649", "71651", "71654", "71655", "71656", "71657", "71659", "71660", "71661", "71663", "71666", "71668", "71670", "71671", "71672", "71674", "71676", "71677", "71683", "71684", "71686", "71687", "71688", "71691", "71693", "71694", "71699", "71704", "71705", "71706", "71709", "71710", "71711", "71713", "71714", "71715", "71717", "71718", "71719", "71724", "71728", "71730", "71733", "71735", "71736", "71740", "71743", "71744", "71745", "71748", "71749", "71752", "71753", "71754", "71759", "71761", "71763", "71765", "71766", "71767", "71771", "71772", "71773", "71774", "71777", "71778", "71779", "71780", "71783", "71787", "71788", "71790", "71791", "71792", "71795", "71799", "71802", "71803", "71804", "71805", "71809", "71810", "71812", "71814", "71815", "71816", "71817", "71818", "71822", "71824", "71825", "71826", "71829", "71831", "71836", "71843", "71847", "71848", "71849", "71850", "71851", "71859", "71860", "71861", "71863", "71866", "71867", "71868", "71870", "71871", "71872", "71874", "71875", "71876", "71880", "71881", "71882", "71884", "71887", "71888", "71889", "71890", "71892", "71894", "71899", "71900", "71904", "71906", "71909", "71910", "71915", "71917", "71918", "71920", "71921", "71922", "71925", "71929", "71930", "71931", "71933", "71935", "71936", "71937", "71939", "71940", "71942", "71943", "71944", "71946", "71948", "71951", "71952", "71955", "71956", "71957", "71959", "71963", "71964", "71965", "71967", "71970", "71973", "71974", "71975", "71977", "71978", "71980", "71982", "71983", "71984", "71988", "71990", "71991", "71993", "71994", "71997", "72000", "72001", "72003", "72006", "72012", "72013", "72016", "72020", "72024", "72028", "72029", "72030", "72036", "72038", "72040", "72041", "72043", "72046", "72047", "72048", "72049", "72052", "72053", "72054", "72056", "72058", "72060", "72061", "72062", "72067", "72068", "72071", "72077", "72078", "72080", "72081", "72082", "72084", "72087", "72089", "72091", "72093", "72094", "72095", "72098", "72105", "72106", "72108", "72109", "72113", "72114", "72115", "72116", "72118", "72119", "72120", "72122", "72124", "72126", "72127", "72128", "72129", "72130", "72131", "72132", "72133", "72135", "72137", "72139", "72141", "72144", "72145", "72147", "72151", "72152", "72153", "72154", "72156", "72158", "72160", "72161", "72162", "72163", "72165", "72166", "72168", "72169", "72171", "72174", "72176", "72179", "72181", "72183", "72184", "72186", "72187", "72193", "72194", "72198", "72199", "72201", "72203", "72205", "72207", "72210", "72218", "72219", "72220", "72221", "72223", "72224", "72226", "72227", "72229", "72230", "72234", "72235", "72237", "72240", "72242", "72243", "72245", "72248", "72249", "72250", "72251", "72253", "72256", "72260", "72264", "72265", "72267", "72269", "72271", "72274", "72275", "72276", "72278", "72279", "72282", "72283", "72284", "72289", "72290", "72292", "72293", "72298", "72300", "72302", "72304", "72306", "72307", "72308", "72310", "72311", "72313", "72314", "72315", "72316", "72317", "72319", "72320", "72321", "72324", "72325", "72328", "72330", "72337", "72338", "72340", "72341", "72342", "72344", "72349", "72351", "72356", "72357", "72358", "72361", "72362", "72369", "72373", "72375", "72378", "72380", "72381", "72384", "72385", "72390", "72391", "72392", "72393", "72395", "72396", "72403", "72404", "72405", "72407", "72408", "72409", "72412", "72413", "72414", "72415", "72416", "72418", "72421", "72422", "72426", "72428", "72430", "72431", "72438", "72439", "72440", "72441", "72442", "72443", "72446", "72447", "72449", "72450", "72456", "72457", "72458", "72459", "72461", "72463", "72466", "72467", "72469", "72471", "72473", "72474", "72475", "72476", "72477", "72483", "72485", "72486", "72487", "72490", "72491", "72495", "72496", "72497", "72500", "72501", "72503", "72506", "72507", "72511", "72514", "72515", "72516", "72517", "72518", "72523", "72524", "72526", "72527", "72528", "72530", "72531", "72533", "72535", "72536", "72543", "72544", "72551", "72553", "72555", "72556", "72557", "72558", "72559", "72561", "72563", "72565", "72566", "72568", "72569", "72570", "72571", "72573", "72575", "72576", "72577", "72579", "72582", "72583", "72585", "72586", "72587", "72588", "72590", "72593", "72598", "72599", "72602", "72603", "72606", "72610", "72612", "72613", "72614", "72617", "72618", "72622", "72624", "72625", "72626", "72627", "72629", "72630", "72632", "72633", "72636", "72639", "72640", "72641", "72643", "72644", "72650", "72651", "72655", "72662", "72663", "72665", "72666", "72668", "72669", "72670", "72672", "72675", "72680", "72681", "72682", "72683", "72686", "72689", "72691", "72694", "72696", "72697", "72698", "72699", "72700", "72704", "72706", "72707", "72709", "72715", "72716", "72718", "72719", "72721", "72722", "72723", "72725", "72726", "72727", "72731", "72736", "72739", "72740", "72741", "72742", "72744", "72746", "72749", "72750", "72752", "72761", "72762", "72764", "72765", "72766", "72767", "72769", "72776", "72779", "72780", "72782", "72783", "72784", "72793", "72798", "72799", "72802", "72807", "72813", "72815", "72817", "72820", "72821", "72822", "72823", "72824", "72827", "72829", "72832", "72835", "72838", "72839", "72843", "72844", "72846", "72848", "72851", "72853", "72854", "72855", "72856", "72857", "72859", "72861", "72862", "72863", "72869", "72870", "72871", "72873", "72875", "72877", "72880", "72881", "72883", "72884", "72886", "72887", "72888", "72889", "72890", "72892", "72894", "72895", "72896", "72899", "72900", "72904", "72905", "72907", "72908", "72910", "72911", "72914", "72916", "72918", "72919", "72920", "72921", "72922", "72923", "72924", "72926", "72927", "72928", "72933", "72934", "72935", "72937", "72938", "72940", "72942", "72943", "72945", "72946", "72948", "72949", "72950", "72952", "72953", "72954", "72955", "72959", "72960", "72961", "72962", "72965", "72966", "72972", "72974", "72976", "72977", "72978", "72979", "72980", "72982", "72983", "72984", "72986", "72987", "72988", "72989", "72991", "72992", "72993", "72995", "72999", "73002", "73004", "73006", "73007", "73009", "73010", "73012", "73016", "73022", "73023", "73025", "73026", "73028", "73029", "73030", "73031", "73032", "73033", "73038", "73041", "73042", "73044", "73051", "73052", "73054", "73055", "73056", "73060", "73063", "73065", "73066", "73073", "73076", "73077", "73078", "73082", "73085", "73087", "73090", "73091", "73093", "73094", "73095", "73096", "73097", "73098", "73099", "73100", "73102", "73104", "73106", "73108", "73109", "73110", "73111", "73113", "73117", "73118", "73121", "73123", "73124", "73126", "73127", "73128", "73130", "73131", "73133", "73136", "73139", "73140", "73141", "73142", "73143", "73144", "73148", "73149", "73150", "73152", "73156", "73157", "73159", "73160", "73162", "73164", "73165", "73171", "73173", "73174", "73181", "73182", "73185", "73187", "73188", "73189", "73192", "73193", "73196", "73198", "73199", "73202", "73203", "73205", "73207", "73209", "73210", "73212", "73214", "73216", "73217", "73218", "73219", "73220", "73222", "73224", "73225", "73226", "73229", "73231", "73233", "73234", "73236", "73239", "73240", "73241", "73242", "73244", "73246", "73248", "73250", "73253", "73255", "73256", "73257", "73258", "73261", "73262", "73263", "73264", "73266", "73270", "73271", "73272", "73274", "73275", "73278", "73283", "73285", "73292", "73293", "73294", "73297", "73300", "73301", "73302", "73305", "73308", "73309", "73310", "73311", "73317", "73318", "73320", "73321", "73325", "73326", "73327", "73330", "73333", "73339", "73340", "73341", "73342", "73343", "73344", "73345", "73347", "73348", "73350", "73352", "73354", "73356", "73357", "73358", "73359", "73360", "73363", "73366", "73367", "73369", "73370", "73371", "73372", "73374", "73376", "73377", "73379", "73380", "73381", "73382", "73383", "73384", "73386", "73390", "73391", "73393", "73395", "73397", "73398", "73399", "73402", "73406", "73409", "73411", "73415", "73418", "73422", "73426", "73428", "73429", "73431", "73433", "73434", "73437", "73438", "73440", "73443", "73447", "73449", "73450", "73453", "73455", "73461", "73463", "73465", "73466", "73469", "73470", "73472", "73473", "73474", "73478", "73479", "73480", "73481", "73484", "73488", "73490", "73491", "73492", "73494", "73496", "73497", "73498", "73499", "73501", "73502", "73503", "73505", "73509", "73510", "73512", "73513", "73514", "73515", "73517", "73518", "73521", "73524", "73525", "73527", "73529", "73534", "73537", "73538", "73539", "73540", "73543", "73547", "73549", "73552", "73553", "73556", "73560", "73565", "73566", "73567", "73569", "73570", "73571", "73573", "73574", "73575", "73578", "73579", "73580", "73582", "73585", "73586", "73587", "73588", "73594", "73597", "73598", "73599", "73600", "73602", "73603", "73604", "73607", "73609", "73610", "73611", "73612", "73614", "73615", "73620", "73624", "73625", "73626", "73627", "73628", "73633", "73634", "73635", "73637", "73638", "73640", "73642", "73643", "73645", "73646", "73647", "73649", "73650", "73651", "73652", "73653", "73654", "73656", "73657", "73659", "73662", "73664", "73665", "73666", "73670", "73673", "73674", "73676", "73680", "73681", "73682", "73683", "73684", "73686", "73688", "73689", "73691", "73694", "73695", "73697", "73701", "73704", "73705", "73709", "73711", "73713", "73714", "73715", "73716", "73717", "73718", "73721", "73722", "73725", "73726", "73732", "73734", "73737", "73743", "73744", "73746", "73749", "73751", "73754", "73756", "73765", "73769", "73771", "73772", "73774", "73775", "73777", "73781", "73782", "73783", "73784", "73787", "73789", "73793", "73794", "73797", "73798", "73799", "73805", "73809", "73811", "73813", "73814", "73817", "73818", "73819", "73820", "73822", "73823", "73824", "73827", "73828", "73831", "73833", "73834", "73835", "73838", "73839", "73846", "73848", "73850", "73854", "73859", "73864", "73867", "73868", "73874", "73875", "73877", "73879", "73880", "73881", "73882", "73883", "73884", "73885", "73889", "73890", "73891", "73893", "73895", "73897", "73909", "73910", "73911", "73912", "73913", "73914", "73915", "73917", "73920", "73921", "73924", "73929", "73930", "73931", "73932", "73934", "73935", "73938", "73939", "73941", "73943", "73944", "73945", "73952", "73953", "73954", "73955", "73959", "73960", "73962", "73965", "73966", "73967", "73968", "73970", "73971", "73974", "73975", "73977", "73981", "73982", "73983", "73984", "73986", "73987", "73988", "73995", "73996", "73998", "73999", "74006", "74009", "74010", "74011", "74012", "74013", "74016", "74017", "74019", "74020", "74024", "74025", "74028", "74029", "74030", "74031", "74032", "74033", "74035", "74037", "74039", "74040", "74041", "74042", "74044", "74048", "74050", "74051", "74054", "74055", "74056", "74058", "74059", "74064", "74065", "74067", "74068", "74069", "74070", "74071", "74075", "74081", "74082", "74083", "74085", "74086", "74088", "74092", "74094", "74095", "74099", "74104", "74106", "74107", "74108", "74112", "74113", "74116", "74117", "74118", "74119", "74120", "74121", "74122", "74123", "74124", "74130", "74132", "74134", "74135", "74139", "74141", "74144", "74146", "74150", "74151", "74152", "74156", "74157", "74158", "74160", "74161", "74162", "74168", "74171", "74172", "74174", "74176", "74177", "74180", "74181", "74182", "74185", "74186", "74188", "74189", "74190", "74191", "74192", "74193", "74200", "74202", "74203", "74205", "74209", "74211", "74213", "74216", "74219", "74220", "74222", "74223", "74224", "74225", "74226", "74227", "74230", "74231", "74232", "74233", "74235", "74236", "74238", "74240", "74244", "74245", "74248", "74249", "74252", "74253", "74256", "74261", "74262", "74263", "74264", "74265", "74266", "74267", "74268", "74270", "74271", "74276", "74279", "74280", "74282", "74285", "74286", "74287", "74288", "74289", "74291", "74292", "74295", "74299", "74300", "74302", "74303", "74306", "74307", "74309", "74310", "74312", "74313", "74315", "74317", "74319", "74321", "74322", "74325", "74326", "74327", "74328", "74331", "74334", "74335", "74336", "74337", "74343", "74345", "74347", "74349", "74350", "74353", "74357", "74360", "74362", "74363", "74365", "74366", "74368", "74369", "74371", "74372", "74373", "74375", "74376", "74377", "74378", "74379", "74381", "74382", "74384", "74386", "74389", "74390", "74392", "74393", "74401", "74402", "74404", "74409", "74410", "74411", "74412", "74416", "74420", "74423", "74424", "74426", "74428", "74430", "74432", "74433", "74436", "74438", "74439", "74441", "74444", "74448", "74454", "74455", "74457", "74463", "74464", "74467", "74468", "74469", "74470", "74471", "74472", "74475", "74476", "74478", "74480", "74482", "74484", "74487", "74488", "74489", "74493", "74494", "74497", "74498", "74499", "74500", "74502", "74503", "74504", "74510", "74514", "74516", "74518", "74519", "74521", "74524", "74525", "74526", "74528", "74529", "74531", "74533", "74534", "74535", "74536", "74542", "74543", "74544", "74545", "74546", "74547", "74548", "74549", "74550", "74552", "74553", "74554", "74563", "74564", "74567", "74568", "74569", "74570", "74571", "74572", "74575", "74576", "74577", "74579", "74580", "74582", "74583", "74584", "74586", "74587", "74589", "74592", "74595", "74596", "74598", "74601", "74602", "74604", "74605", "74608", "74609", "74610", "74612", "74613", "74614", "74615", "74616", "74618", "74620", "74621", "74622", "74625", "74626", "74630", "74631", "74632", "74634", "74636", "74639", "74641", "74642", "74643", "74645", "74646", "74647", "74648", "74649", "74650", "74652", "74653", "74654", "74655", "74660", "74662", "74665", "74666", "74667", "74668", "74672", "74674", "74675", "74676", "74677", "74678", "74680", "74682", "74684", "74686", "74688", "74689", "74690", "74691", "74692", "74694", "74696", "74698", "74700", "74706", "74708", "74713", "74715", "74717", "74720", "74721", "74722", "74723", "74724", "74725", "74726", "74729", "74730", "74731", "74732", "74733", "74736", "74739", "74742", "74750", "74753", "74754", "74757", "74763", "74764", "74766", "74767", "74770", "74772", "74773", "74775", "74776", "74777", "74780", "74782", "74785", "74787", "74788", "74789", "74790", "74792", "74793", "74794", "74796", "74799", "74800", "74801", "74802", "74803", "74804", "74805", "74806", "74807", "74808", "74809", "74813", "74815", "74818", "74820", "74822", "74823", "74827", "74830", "74831", "74832", "74833", "74834", "74836", "74838", "74841", "74842", "74843", "74852", "74853", "74854", "74855", "74858", "74861", "74864", "74865", "74867", "74868", "74871", "74874", "74876", "74877", "74882", "74884", "74886", "74887", "74888", "74890", "74892", "74894", "74895", "74896", "74898", "74900", "74901", "74904", "74905", "74907", "74914", "74915", "74917", "74918", "74922", "74923", "74924", "74925", "74926", "74927", "74930", "74931", "74932", "74936", "74938", "74939", "74940", "74941", "74942", "74943", "74944", "74948", "74949", "74951", "74954", "74955", "74956", "74962", "74965", "74966", "74967", "74969", "74971", "74972", "74974", "74976", "74979", "74981", "74982", "74984", "74985", "74987", "74988", "74990", "74992", "74994", "74995", "74997", "74998", "74999", "75000", "75002", "75003", "75008", "75009", "75012", "75014", "75015", "75017", "75018", "75021", "75023", "75028", "75030", "75032", "75034", "75036", "75038", "75041", "75044", "75045", "75047", "75049", "75051", "75052", "75053", "75056", "75057", "75059", "75065", "75066", "75067", "75068", "75071", "75072", "75075", "75076", "75078", "75081", "75082", "75084", "75085", "75086", "75090", "75093", "75094", "75096", "75097", "75099", "75107", "75108", "75109", "75112", "75113", "75114", "75116", "75117", "75119", "75120", "75123", "75125", "75130", "75132", "75133", "75134", "75135", "75138", "75139", "75140", "75141", "75142", "75143", "75144", "75145", "75146", "75147", "75150", "75151", "75154", "75156", "75157", "75158", "75159", "75160", "75164", "75165", "75166", "75167", "75170", "75171", "75172", "75173", "75176", "75177", "75180", "75183", "75186", "75188", "75189", "75190", "75192", "75193", "75194", "75197", "75200", "75202", "75205", "75209", "75213", "75218", "75221", "75223", "75224", "75225", "75226", "75228", "75231", "75232", "75234", "75235", "75236", "75237", "75238", "75239", "75241", "75242", "75244", "75246", "75249", "75259", "75261", "75263", "75265", "75268", "75269", "75270", "75271", "75272", "75274", "75275", "75279", "75283", "75284", "75286", "75287", "75288", "75290", "75300", "75301", "75302", "75305", "75307", "75309", "75310", "75311", "75312", "75313", "75314", "75315", "75318", "75319", "75321", "75324", "75325", "75326", "75327", "75328", "75329", "75330", "75331", "75335", "75336", "75337", "75338", "75340", "75341", "75344", "75349", "75350", "75351", "75353", "75355", "75356", "75357", "75359", "75361", "75363", "75367", "75369", "75374", "75376", "75377", "75382", "75383", "75384", "75385", "75388", "75390", "75391", "75392", "75395", "75398", "75402", "75405", "75406", "75407", "75409", "75410", "75411", "75420", "75421", "75423", "75424", "75427", "75428", "75430", "75432", "75434", "75440", "75443", "75444", "75445", "75447", "75448", "75453", "75454", "75455", "75458", "75459", "75461", "75464", "75466", "75469", "75471", "75478", "75480", "75481", "75483", "75484", "75485", "75488", "75492", "75494", "75495", "75496", "75498", "75500", "75501", "75502", "75504", "75505", "75507", "75511", "75513", "75516", "75517", "75519", "75520", "75522", "75525", "75527", "75528", "75530", "75533", "75534", "75536", "75537", "75539", "75540", "75541", "75542", "75543", "75544", "75546", "75549", "75550", "75551", "75552", "75557", "75558", "75559", "75561", "75563", "75569", "75572", "75573", "75577", "75579", "75581", "75583", "75585", "75586", "75587", "75588", "75590", "75593", "75595", "75598", "75599", "75601", "75603", "75604", "75605", "75606", "75610", "75611", "75615", "75616", "75618", "75619", "75620", "75621", "75622", "75626", "75629", "75630", "75631", "75633", "75635", "75636", "75637", "75638", "75640", "75642", "75644", "75645", "75647", "75648", "75651", "75652", "75653", "75654", "75655", "75656", "75660", "75661", "75662", "75663", "75664", "75665", "75667", "75668", "75670", "75671", "75673", "75675", "75677", "75684", "75685", "75686", "75687", "75689", "75690", "75691", "75695", "75696", "75698", "75699", "75702", "75703", "75704", "75705", "75707", "75709", "75712", "75715", "75717", "75721", "75723", "75724", "75726", "75727", "75728", "75731", "75733", "75734", "75740", "75742", "75743", "75746", "75747", "75749", "75750", "75751", "75753", "75755", "75756", "75759", "75761", "75764", "75766", "75767", "75768", "75771", "75774", "75775", "75776", "75778", "75781", "75783", "75784", "75785", "75788", "75790", "75791", "75793", "75795", "75796", "75798", "75799", "75802", "75803", "75805", "75806", "75807", "75808", "75809", "75810", "75811", "75815", "75816", "75822", "75824", "75826", "75827", "75829", "75832", "75833", "75839", "75841", "75842", "75843", "75852", "75853", "75855", "75857", "75858", "75862", "75863", "75864", "75865", "75866", "75867", "75872", "75873", "75874", "75875", "75876", "75877", "75878", "75880", "75881", "75882", "75885", "75889", "75890", "75893", "75894", "75895", "75898", "75900", "75901", "75902", "75906", "75907", "75908", "75909", "75910", "75912", "75915", "75918", "75919", "75921", "75924", "75926", "75927", "75931", "75933", "75934", "75935", "75936", "75940", "75941", "75942", "75944", "75945", "75946", "75947", "75948", "75950", "75951", "75952", "75955", "75956", "75958", "75961", "75963", "75967", "75968", "75970", "75972", "75976", "75979", "75980", "75982", "75984", "75985", "75986", "75988", "75989", "75990", "75991", "75992", "75993", "75994", "75995", "75998", "76002", "76003", "76005", "76006", "76007", "76008", "76009", "76011", "76012", "76014", "76015", "76016", "76017", "76019", "76022", "76026", "76029", "76031", "76033", "76036", "76037", "76043", "76044", "76045", "76047", "76049", "76050", "76058", "76059", "76061", "76064", "76065", "76066", "76067", "76068", "76069", "76072", "76074", "76077", "76079", "76080", "76081", "76084", "76085", "76086", "76087", "76088", "76090", "76091", "76094", "76095", "76097", "76098", "76101", "76105", "76107", "76108", "76110", "76111", "76113", "76115", "76116", "76121", "76122", "76124", "76125", "76127", "76128", "76130", "76131", "76132", "76133", "76134", "76135", "76138", "76139", "76142", "76145", "76146", "76150", "76152", "76154", "76155", "76156", "76158", "76159", "76161", "76163", "76165", "76168", "76171", "76173", "76175", "76180", "76182", "76183", "76184", "76192", "76193", "76194", "76196", "76200", "76206", "76207", "76209", "76211", "76213", "76214", "76216", "76217", "76219", "76221", "76229", "76230", "76231", "76232", "76233", "76234", "76235", "76243", "76244", "76245", "76250", "76254", "76257", "76260", "76261", "76262", "76264", "76268", "76269", "76271", "76272", "76273", "76276", "76277", "76280", "76281", "76282", "76284", "76285", "76286", "76287", "76288", "76291", "76292", "76295", "76297", "76298", "76300", "76302", "76303", "76306", "76312", "76316", "76317", "76318", "76320", "76323", "76324", "76325", "76329", "76331", "76332", "76333", "76334", "76335", "76336", "76337", "76339", "76340", "76342", "76343", "76344", "76346", "76348", "76351", "76353", "76354", "76355", "76356", "76357", "76360", "76363", "76364", "76365", "76367", "76369", "76370", "76372", "76374", "76375", "76376", "76377", "76379", "76380", "76381", "76382", "76384", "76386", "76392", "76393", "76394", "76397", "76398", "76400", "76401", "76405", "76406", "76407", "76408", "76409", "76416", "76417", "76423", "76424", "76425", "76428", "76430", "76431", "76433", "76434", "76435", "76436", "76437", "76440", "76444", "76446", "76447", "76448", "76449", "76451", "76452", "76453", "76454", "76456", "76457", "76459", "76460", "76462", "76463", "76464", "76466", "76469", "76471", "76472", "76474", "76475", "76476", "76477", "76480", "76483", "76484", "76487", "76488", "76491", "76492", "76494", "76496", "76497", "76498", "76500", "76503", "76504", "76505", "76507", "76509", "76510", "76511", "76513", "76516", "76518", "76519", "76520", "76522", "76523", "76524", "76525", "76531", "76532", "76533", "76536", "76537", "76538", "76540", "76546", "76547", "76548", "76549", "76550", "76552", "76554", "76555", "76556", "76557", "76559", "76564", "76565", "76566", "76572", "76573", "76574", "76575", "76581", "76582", "76583", "76585", "76586", "76587", "76588", "76591", "76593", "76594", "76596", "76597", "76599", "76600", "76601", "76602", "76605", "76606", "76611", "76613", "76615", "76619", "76620", "76623", "76624", "76627", "76628", "76630", "76631", "76632", "76637", "76638", "76639", "76641", "76643", "76646", "76649", "76651", "76652", "76656", "76657", "76659", "76660", "76663", "76664", "76666", "76667", "76668", "76671", "76675", "76676", "76678", "76680", "76683", "76684", "76685", "76686", "76687", "76689", "76691", "76693", "76695", "76697", "76698", "76701", "76702", "76703", "76704", "76706", "76707", "76711", "76715", "76718", "76719", "76720", "76725", "76726", "76728", "76731", "76735", "76736", "76740", "76741", "76748", "76751", "76752", "76756", "76758", "76760", "76761", "76762", "76763", "76767", "76769", "76771", "76773", "76775", "76776", "76777", "76778", "76781", "76782", "76785", "76786", "76789", "76790", "76791", "76792", "76794", "76796", "76798", "76800", "76801", "76802", "76806", "76808", "76809", "76810", "76811", "76812", "76813", "76814", "76815", "76819", "76823", "76824", "76825", "76826", "76827", "76828", "76829", "76830", "76831", "76832", "76837", "76840", "76847", "76848", "76850", "76856", "76859", "76861", "76866", "76873", "76874", "76878", "76879", "76880", "76882", "76884", "76888", "76892", "76896", "76898", "76899", "76901", "76902", "76903", "76905", "76906", "76907", "76913", "76914", "76918", "76919", "76922", "76925", "76927", "76931", "76933", "76937", "76939", "76940", "76942", "76943", "76944", "76948", "76949", "76953", "76954", "76958", "76959", "76963", "76966", "76970", "76972", "76974", "76975", "76976", "76977", "76978", "76980", "76989", "76993", "76994", "76997", "76998", "76999", "77001", "77003", "77004", "77008", "77010", "77011", "77013", "77015", "77016", "77017", "77018", "77019", "77022", "77024", "77027", "77028", "77029", "77030", "77032", "77034", "77035", "77038", "77040", "77041", "77043", "77047", "77049", "77051", "77053", "77054", "77055", "77056", "77058", "77060", "77063", "77065", "77070", "77073", "77074", "77076", "77078", "77083", "77084", "77085", "77086", "77087", "77088", "77089", "77090", "77091", "77092", "77093", "77097", "77100", "77102", "77104", "77105", "77107", "77110", "77112", "77113", "77115", "77121", "77125", "77128", "77129", "77132", "77134", "77140", "77141", "77142", "77143", "77145", "77147", "77148", "77150", "77153", "77154", "77156", "77158", "77159", "77160", "77164", "77175", "77176", "77178", "77179", "77183", "77184", "77190", "77192", "77196", "77198", "77199", "77201", "77211", "77215", "77216", "77218", "77219", "77220", "77223", "77224", "77225", "77226", "77230", "77231", "77232", "77235", "77236", "77237", "77238", "77239", "77240", "77241", "77242", "77243", "77246", "77247", "77248", "77249", "77252", "77253", "77255", "77259", "77260", "77261", "77262", "77263", "77265", "77268", "77270", "77272", "77275", "77279", "77280", "77283", "77285", "77290", "77292", "77293", "77296", "77299", "77302", "77303", "77304", "77307", "77308", "77310", "77311", "77312", "77313", "77315", "77317", "77318", "77319", "77320", "77321", "77323", "77325", "77326", "77327", "77329", "77330", "77333", "77335", "77336", "77337", "77338", "77341", "77342", "77343", "77344", "77346", "77349", "77351", "77353", "77355", "77356", "77363", "77366", "77368", "77371", "77372", "77373", "77375", "77379", "77380", "77385", "77386", "77388", "77389", "77391", "77392", "77393", "77396", "77398", "77401", "77402", "77405", "77407", "77411", "77412", "77413", "77414", "77416", "77419", "77420", "77421", "77423", "77427", "77428", "77429", "77439", "77441", "77443", "77444", "77447", "77450", "77451", "77456", "77457", "77458", "77459", "77460", "77463", "77465", "77466", "77467", "77470", "77471", "77472", "77473", "77475", "77477", "77478", "77479", "77481", "77483", "77485", "77486", "77488", "77490", "77496", "77497", "77498", "77500", "77502", "77503", "77504", "77505", "77506", "77507", "77511", "77514", "77515", "77518", "77519", "77522", "77526", "77527", "77529", "77534", "77535", "77537", "77539", "77541", "77542", "77544", "77546", "77547", "77548", "77550", "77556", "77557", "77558", "77559", "77561", "77564", "77567", "77570", "77572", "77575", "77579", "77581", "77582", "77583", "77584", "77587", "77592", "77594", "77596", "77597", "77598", "77599", "77602", "77604", "77605", "77609", "77610", "77615", "77616", "77617", "77618", "77620", "77621", "77622", "77630", "77631", "77632", "77636", "77637", "77643", "77646", "77647", "77648", "77649", "77655", "77657", "77660", "77661", "77664", "77666", "77667", "77670", "77672", "77675", "77676", "77677", "77683", "77684", "77688", "77689", "77690", "77691", "77692", "77695", "77698", "77699", "77700", "77701", "77705", "77709", "77713", "77716", "77717", "77719", "77722", "77724", "77726", "77728", "77729", "77731", "77732", "77733", "77736", "77737", "77738", "77743", "77745", "77746", "77748", "77750", "77755", "77759", "77765", "77766", "77767", "77769", "77771", "77775", "77776", "77778", "77779", "77780", "77782", "77783", "77787", "77788", "77789", "77790", "77791", "77793", "77795", "77798", "77801", "77802", "77803", "77806", "77807", "77811", "77814", "77815", "77817", "77818", "77819", "77820", "77822", "77824", "77827", "77830", "77831", "77833", "77834", "77839", "77841", "77843", "77844", "77845", "77847", "77848", "77850", "77852", "77854", "77856", "77857", "77862", "77863", "77864", "77865", "77866", "77868", "77870", "77872", "77873", "77874", "77875", "77876", "77878", "77879", "77880", "77882", "77884", "77885", "77887", "77888", "77890", "77893", "77897", "77901", "77904", "77905", "77908", "77910", "77914", "77915", "77916", "77917", "77919", "77920", "77922", "77923", "77928", "77930", "77933", "77936", "77937", "77939", "77940", "77944", "77947", "77948", "77949", "77950", "77951", "77953", "77956", "77958", "77959", "77961", "77964", "77966", "77967", "77969", "77970", "77972", "77974", "77975", "77978", "77979", "77980", "77982", "77984", "77985", "77990", "77992", "77993", "77995", "77997", "77999", "78000", "78001", "78004", "78008", "78009", "78010", "78013", "78018", "78020", "78023", "78025", "78028", "78030", "78033", "78034", "78035", "78036", "78037", "78039", "78041", "78043", "78044", "78045", "78048", "78050", "78051", "78054", "78058", "78059", "78061", "78062", "78063", "78065", "78066", "78067", "78069", "78070", "78076", "78078", "78083", "78084", "78085", "78087", "78088", "78089", "78091", "78093", "78094", "78100", "78101", "78102", "78105", "78108", "78109", "78111", "78115", "78119", "78121", "78122", "78126", "78127", "78128", "78130", "78131", "78133", "78135", "78136", "78137", "78138", "78139", "78140", "78142", "78145", "78146", "78147", "78148", "78151", "78152", "78153", "78155", "78159", "78160", "78161", "78163", "78164", "78165", "78166", "78167", "78169", "78170", "78173", "78175", "78177", "78181", "78182", "78184", "78185", "78186", "78187", "78188", "78190", "78191", "78192", "78193", "78194", "78195", "78197", "78198", "78200", "78201", "78205", "78206", "78207", "78209", "78210", "78211", "78213", "78214", "78217", "78222", "78224", "78225", "78226", "78227", "78228", "78229", "78230", "78238", "78239", "78240", "78243", "78247", "78249", "78253", "78255", "78259", "78260", "78262", "78264", "78265", "78268", "78270", "78273", "78275", "78277", "78279", "78282", "78284", "78285", "78286", "78289", "78290", "78293", "78295", "78296", "78297", "78298", "78299", "78300", "78301", "78304", "78305", "78307", "78308", "78311", "78314", "78315", "78316", "78317", "78319", "78323", "78324", "78325", "78327", "78328", "78329", "78332", "78334", "78336", "78337", "78339", "78341", "78342", "78347", "78349", "78350", "78353", "78354", "78355", "78357", "78358", "78359", "78363", "78364", "78365", "78366", "78373", "78375", "78379", "78381", "78382", "78384", "78385", "78386", "78388", "78393", "78396", "78397", "78398", "78399", "78402", "78403", "78406", "78407", "78408", "78409", "78410", "78412", "78417", "78418", "78420", "78421", "78426", "78428", "78429", "78430", "78431", "78432", "78434", "78438", "78440", "78442", "78443", "78444", "78446", "78449", "78451", "78456", "78457", "78458", "78459", "78460", "78461", "78464", "78468", "78469", "78470", "78471", "78475", "78476", "78477", "78480", "78481", "78483", "78484", "78486", "78488", "78489", "78490", "78491", "78492", "78494", "78495", "78498", "78499", "78500", "78501", "78504", "78505", "78506", "78508", "78512", "78514", "78515", "78516", "78519", "78522", "78523", "78525", "78526", "78528", "78530", "78532", "78533", "78534", "78536", "78537", "78538", "78539", "78544", "78546", "78551", "78552", "78553", "78554", "78557", "78560", "78561", "78562", "78564", "78565", "78570", "78571", "78572", "78576", "78577", "78579", "78580", "78581", "78582", "78587", "78588", "78591", "78592", "78593", "78594", "78598", "78600", "78601", "78602", "78605", "78606", "78607", "78608", "78612", "78613", "78617", "78618", "78620", "78621", "78622", "78623", "78624", "78625", "78626", "78627", "78628", "78630", "78632", "78635", "78636", "78637", "78641", "78642", "78645", "78646", "78647", "78648", "78650", "78651", "78653", "78655", "78656", "78657", "78659", "78660", "78665", "78668", "78669", "78672", "78673", "78674", "78676", "78677", "78678", "78680", "78682", "78694", "78695", "78696", "78697", "78698", "78700", "78702", "78703", "78704", "78706", "78708", "78710", "78711", "78714", "78715", "78716", "78718", "78724", "78726", "78730", "78731", "78733", "78737", "78738", "78739", "78744", "78745", "78747", "78748", "78750", "78755", "78756", "78759", "78760", "78761", "78762", "78765", "78766", "78769", "78771", "78774", "78780", "78781", "78783", "78784", "78785", "78786", "78787", "78790", "78791", "78798", "78799", "78804", "78805", "78808", "78809", "78812", "78815", "78816", "78819", "78822", "78824", "78825", "78827", "78828", "78831", "78832", "78834", "78836", "78838", "78839", "78840", "78841", "78845", "78849", "78850", "78854", "78855", "78857", "78858", "78861", "78862", "78864", "78869", "78870", "78871", "78875", "78876", "78878", "78881", "78883", "78886", "78888", "78889", "78891", "78893", "78894", "78895", "78896", "78897", "78898", "78899", "78900", "78903", "78907", "78908", "78909", "78910", "78911", "78913", "78914", "78919", "78920", "78923", "78924", "78926", "78927", "78928", "78934", "78936", "78937", "78938", "78940", "78944", "78946", "78948", "78950", "78951", "78954", "78956", "78957", "78958", "78959", "78960", "78961", "78962", "78970", "78971", "78972", "78974", "78975", "78977", "78979", "78982", "78985", "78987", "78988", "78989", "78990", "78991", "78992", "78993", "78995", "78996", "78998", "78999", "79000", "79007", "79012", "79013", "79014", "79017", "79019", "79020", "79021", "79022", "79024", "79025", "79026", "79027", "79029", "79033", "79036", "79037", "79039", "79040", "79044", "79045", "79047", "79048", "79049", "79050", "79051", "79052", "79053", "79055", "79056", "79058", "79059", "79060", "79062", "79065", "79069", "79072", "79073", "79074", "79075", "79076", "79078", "79079", "79081", "79082", "79083", "79084", "79086", "79088", "79090", "79091", "79092", "79093", "79095", "79096", "79098", "79099", "79103", "79104", "79107", "79109", "79110", "79112", "79113", "79116", "79123", "79126", "79127", "79130", "79131", "79132", "79134", "79136", "79137", "79141", "79142", "79144", "79147", "79152", "79153", "79157", "79158", "79159", "79160", "79164", "79169", "79174", "79179", "79180", "79187", "79189", "79190", "79191", "79196", "79198", "79199", "79203", "79205", "79206", "79208", "79212", "79213", "79216", "79217", "79218", "79223", "79225", "79230", "79233", "79234", "79237", "79238", "79239", "79241", "79249", "79252", "79257", "79258", "79260", "79261", "79262", "79263", "79265", "79267", "79269", "79271", "79272", "79275", "79276", "79278", "79279", "79281", "79283", "79285", "79288", "79292", "79296", "79297", "79298", "79299", "79304", "79310", "79313", "79314", "79316", "79317", "79318", "79319", "79321", "79325", "79327", "79328", "79329", "79331", "79332", "79337", "79338", "79339", "79347", "79348", "79351", "79353", "79354", "79357", "79359", "79361", "79367", "79370", "79371", "79372", "79373", "79374", "79376", "79379", "79380", "79381", "79384", "79387", "79388", "79391", "79392", "79402", "79403", "79407", "79408", "79409", "79410", "79411", "79412", "79416", "79419", "79421", "79422", "79423", "79424", "79425", "79427", "79430", "79431", "79433", "79435", "79436", "79437", "79440", "79442", "79444", "79446", "79447", "79448", "79450", "79451", "79454", "79456", "79457", "79458", "79459", "79461", "79463", "79464", "79469", "79474", "79475", "79476", "79479", "79480", "79481", "79486", "79490", "79491", "79494", "79496", "79502", "79504", "79507", "79513", "79514", "79516", "79518", "79519", "79525", "79527", "79528", "79530", "79531", "79532", "79534", "79535", "79536", "79539", "79542", "79546", "79547", "79548", "79552", "79554", "79555", "79557", "79558", "79562", "79564", "79566", "79567", "79568", "79571", "79572", "79574", "79575", "79576", "79582", "79583", "79590", "79591", "79592", "79593", "79594", "79596", "79597", "79598", "79602", "79603", "79604", "79605", "79607", "79608", "79609", "79610", "79611", "79618", "79619", "79621", "79622", "79623", "79626", "79629", "79631", "79634", "79638", "79642", "79643", "79644", "79646", "79647", "79648", "79650", "79656", "79657", "79659", "79672", "79673", "79675", "79677", "79687", "79690", "79691", "79692", "79693", "79694", "79695", "79696", "79698", "79704", "79705", "79707", "79709", "79710", "79713", "79719", "79720", "79722", "79723", "79724", "79725", "79726", "79730", "79733", "79735", "79737", "79738", "79739", "79740", "79741", "79745", "79746", "79747", "79748", "79749", "79751", "79753", "79754", "79756", "79757", "79760", "79761", "79762", "79763", "79764", "79765", "79766", "79768", "79772", "79773", "79774", "79777", "79778", "79783", "79784", "79785", "79786", "79787", "79788", "79790", "79793", "79799", "79800", "79801", "79803", "79804", "79806", "79807", "79808", "79812", "79813", "79816", "79818", "79819", "79820", "79821", "79822", "79823", "79825", "79827", "79829", "79830", "79835", "79836", "79838", "79842", "79843", "79844", "79847", "79848", "79852", "79853", "79856", "79858", "79859", "79860", "79863", "79864", "79865", "79867", "79868", "79869", "79871", "79874", "79875", "79876", "79878", "79887", "79890", "79894", "79895", "79897", "79898", "79899", "79901", "79902", "79903", "79905", "79906", "79907", "79908", "79909", "79912", "79913", "79914", "79915", "79916", "79917", "79918", "79920", "79921", "79926", "79927", "79930", "79931", "79932", "79934", "79936", "79937", "79939", "79941", "79942", "79943", "79946", "79947", "79948", "79950", "79951", "79952", "79953", "79959", "79960", "79962", "79963", "79966", "79967", "79968", "79975", "79976", "79978", "79980", "79981", "79983", "79985", "79986", "79987", "79988", "79989", "79992", "79993", "79994", "79996", "79999", "80000", "80003", "80007", "80008", "80009", "80012", "80013", "80016", "80017", "80018", "80019", "80021", "80022", "80023", "80024", "80025", "80027", "80028", "80030", "80033", "80034", "80037", "80040", "80045", "80046", "80047", "80048", "80054", "80057", "80058", "80059", "80062", "80063", "80065", "80067", "80068", "80072", "80073", "80078", "80079", "80081", "80082", "80090", "80092", "80096", "80097", "80099", "80101", "80107", "80108", "80111", "80113", "80114", "80116", "80118", "80119", "80120", "80121", "80123", "80124", "80125", "80126", "80127", "80128", "80132", "80135", "80137", "80139", "80140", "80145", "80146", "80148", "80149", "80150", "80151", "80152", "80153", "80155", "80156", "80157", "80160", "80162", "80164", "80165", "80166", "80167", "80169", "80171", "80172", "80173", "80174", "80175", "80176", "80183", "80184", "80185", "80186", "80187", "80188", "80189", "80190", "80191", "80193", "80194", "80197", "80200", "80204", "80206", "80207", "80214", "80215", "80218", "80219", "80220", "80221", "80223", "80226", "80230", "80232", "80235", "80236", "80241", "80244", "80246", "80249", "80250", "80252", "80254", "80255", "80257", "80258", "80259", "80260", "80262", "80265", "80266", "80270", "80272", "80273", "80276", "80279", "80281", "80284", "80287", "80289", "80290", "80291", "80295", "80296", "80299", "80301", "80302", "80303", "80307", "80309", "80312", "80315", "80320", "80322", "80323", "80326", "80328", "80330", "80332", "80333", "80334", "80336", "80338", "80339", "80341", "80342", "80343", "80344", "80345", "80346", "80347", "80348", "80351", "80352", "80354", "80358", "80360", "80361", "80364", "80366", "80367", "80369", "80371", "80374", "80377", "80379", "80381", "80386", "80387", "80391", "80393", "80394", "80396", "80398", "80399", "80402", "80403", "80405", "80407", "80408", "80409", "80410", "80411", "80413", "80414", "80416", "80419", "80421", "80423", "80431", "80433", "80434", "80435", "80436", "80440", "80441", "80442", "80443", "80448", "80450", "80451", "80453", "80454", "80455", "80456", "80457", "80458", "80459", "80461", "80466", "80467", "80468", "80472", "80473", "80474", "80475", "80477", "80478", "80479", "80481", "80484", "80486", "80488", "80489", "80490", "80491", "80493", "80494", "80497", "80499", "80501", "80504", "80509", "80512", "80513", "80517", "80518", "80521", "80524", "80526", "80528", "80529", "80531", "80533", "80535", "80541", "80542", "80543", "80544", "80546", "80548", "80550", "80551", "80553", "80554", "80555", "80557", "80564", "80567", "80568", "80574", "80575", "80576", "80579", "80586", "80587", "80588", "80590", "80591", "80592", "80597", "80599", "80602", "80604", "80606", "80608", "80609", "80611", "80614", "80617", "80619", "80625", "80627", "80628", "80629", "80633", "80635", "80637", "80639", "80640", "80641", "80647", "80648", "80650", "80651", "80652", "80653", "80658", "80660", "80662", "80666", "80667", "80669", "80670", "80671", "80672", "80673", "80677", "80679", "80682", "80683", "80684", "80685", "80687", "80688", "80689", "80690", "80691", "80693", "80694", "80696", "80697", "80699", "80702", "80703", "80706", "80707", "80708", "80709", "80712", "80714", "80715", "80716", "80718", "80721", "80723", "80724", "80727", "80729", "80730", "80731", "80732", "80733", "80735", "80739", "80741", "80742", "80745", "80746", "80748", "80751", "80754", "80759", "80764", "80765", "80767", "80768", "80769", "80773", "80775", "80777", "80778", "80780", "80781", "80782", "80784", "80785", "80791", "80794", "80795", "80797", "80798", "80799", "80804", "80807", "80808", "80809", "80813", "80815", "80816", "80817", "80818", "80819", "80821", "80822", "80824", "80826", "80827", "80830", "80831", "80832", "80833", "80835", "80837", "80839", "80842", "80843", "80849", "80851", "80852", "80859", "80860", "80861", "80862", "80864", "80865", "80867", "80869", "80870", "80871", "80873", "80874", "80879", "80882", "80884", "80885", "80886", "80888", "80892", "80901", "80902", "80905", "80906", "80907", "80910", "80912", "80923", "80924", "80925", "80927", "80928", "80930", "80931", "80932", "80933", "80935", "80936", "80937", "80939", "80940", "80942", "80943", "80944", "80945", "80946", "80949", "80951", "80954", "80955", "80956", "80957", "80958", "80964", "80966", "80968", "80973", "80974", "80975", "80976", "80978", "80980", "80981", "80982", "80985", "80991", "80993", "80995", "80996", "80998", "80999", "81000", "81001", "81003", "81009", "81011", "81012", "81013", "81015", "81017", "81018", "81019", "81020", "81027", "81028", "81029", "81031", "81032", "81034", "81035", "81036", "81038", "81039", "81041", "81042", "81043", "81044", "81048", "81052", "81058", "81059", "81060", "81062", "81063", "81065", "81066", "81067", "81068", "81072", "81073", "81074", "81076", "81077", "81079", "81080", "81081", "81082", "81083", "81085", "81089", "81090", "81094", "81096", "81099", "81101", "81103", "81104", "81107", "81108", "81109", "81110", "81111", "81115", "81116", "81118", "81119", "81123", "81124", "81125", "81126", "81127", "81129", "81132", "81133", "81134", "81137", "81138", "81139", "81141", "81143", "81144", "81145", "81147", "81148", "81149", "81153", "81155", "81158", "81159", "81160", "81162", "81163", "81168", "81171", "81172", "81174", "81175", "81176", "81177", "81178", "81180", "81182", "81183", "81185", "81186", "81187", "81189", "81191", "81192", "81193", "81195", "81199", "81202", "81203", "81204", "81205", "81206", "81211", "81212", "81213", "81215", "81216", "81217", "81218", "81221", "81222", "81224", "81225", "81226", "81227", "81229", "81231", "81232", "81234", "81235", "81236", "81237", "81238", "81240", "81241", "81242", "81243", "81244", "81245", "81246", "81247", "81248", "81250", "81252", "81253", "81254", "81255", "81256", "81257", "81259", "81260", "81264", "81267", "81269", "81274", "81277", "81278", "81280", "81281", "81282", "81286", "81289", "81292", "81294", "81295", "81296", "81297", "81300", "81303", "81305", "81309", "81310", "81312", "81313", "81315", "81317", "81318", "81322", "81323", "81324", "81326", "81329", "81331", "81332", "81334", "81337", "81338", "81341", "81342", "81345", "81346", "81347", "81350", "81351", "81352", "81353", "81354", "81355", "81356", "81357", "81358", "81366", "81367", "81368", "81369", "81371", "81372", "81374", "81377", "81378", "81379", "81380", "81382", "81385", "81387", "81389", "81392", "81393", "81396", "81397", "81398", "81402", "81403", "81405", "81406", "81408", "81412", "81414", "81416", "81418", "81421", "81424", "81427", "81428", "81430", "81432", "81435", "81437", "81440", "81442", "81445", "81446", "81447", "81450", "81454", "81456", "81463", "81465", "81466", "81467", "81469", "81470", "81474", "81475", "81476", "81477", "81482", "81483", "81485", "81487", "81491", "81492", "81493", "81496", "81498", "81505", "81506", "81507", "81508", "81512", "81514", "81516", "81521", "81525", "81527", "81530", "81532", "81533", "81535", "81539", "81540", "81542", "81545", "81546", "81547", "81550", "81551", "81554", "81556", "81557", "81562", "81563", "81564", "81565", "81569", "81570", "81579", "81582", "81583", "81584", "81585", "81586", "81587", "81588", "81590", "81591", "81592", "81593", "81594", "81595", "81596", "81598", "81599", "81603", "81607", "81608", "81613", "81614", "81618", "81620", "81622", "81627", "81631", "81632", "81639", "81641", "81646", "81647", "81649", "81650", "81651", "81652", "81654", "81655", "81656", "81661", "81662", "81664", "81665", "81666", "81668", "81669", "81670", "81671", "81673", "81676", "81678", "81679", "81680", "81681", "81683", "81685", "81692", "81693", "81697", "81700", "81701", "81703", "81704", "81708", "81710", "81711", "81712", "81713", "81715", "81716", "81718", "81719", "81720", "81721", "81724", "81727", "81728", "81731", "81732", "81735", "81737", "81741", "81745", "81747", "81751", "81753", "81755", "81756", "81757", "81759", "81761", "81765", "81768", "81772", "81774", "81776", "81779", "81780", "81784", "81787", "81797", "81799", "81800", "81801", "81802", "81807", "81808", "81812", "81818", "81820", "81821", "81822", "81823", "81824", "81825", "81827", "81828", "81830", "81834", "81835", "81839", "81846", "81848", "81850", "81854", "81855", "81856", "81857", "81858", "81861", "81862", "81863", "81864", "81865", "81868", "81870", "81871", "81875", "81876", "81877", "81880", "81881", "81882", "81884", "81885", "81886", "81887", "81889", "81891", "81893", "81894", "81895", "81896", "81898", "81900", "81902", "81903", "81904", "81906", "81907", "81910", "81914", "81915", "81917", "81918", "81921", "81925", "81926", "81927", "81928", "81931", "81932", "81933", "81936", "81938", "81940", "81942", "81943", "81945", "81946", "81955", "81958", "81961", "81964", "81966", "81967", "81969", "81974", "81976", "81977", "81978", "81981", "81983", "81984", "81991", "81992", "81996", "81999", "82000", "82001", "82002", "82005", "82006", "82007", "82008", "82010", "82011", "82012", "82014", "82015", "82022", "82023", "82025", "82026", "82027", "82028", "82029", "82030", "82031", "82034", "82037", "82038", "82040", "82041", "82044", "82045", "82046", "82048", "82049", "82050", "82051", "82053", "82055", "82057", "82058", "82059", "82061", "82062", "82064", "82071", "82072", "82074", "82075", "82076", "82077", "82078", "82080", "82082", "82088", "82090", "82093", "82096", "82097", "82101", "82102", "82104", "82107", "82108", "82112", "82114", "82116", "82118", "82119", "82122", "82123", "82124", "82126", "82129", "82130", "82132", "82133", "82134", "82136", "82137", "82139", "82142", "82144", "82145", "82146", "82153", "82155", "82157", "82159", "82161", "82162", "82167", "82168", "82169", "82170", "82171", "82173", "82174", "82177", "82180", "82184", "82186", "82187", "82192", "82195", "82196", "82199", "82201", "82204", "82205", "82206", "82208", "82209", "82213", "82216", "82217", "82218", "82219", "82220", "82221", "82222", "82223", "82227", "82228", "82231", "82232", "82233", "82234", "82235", "82237", "82240", "82243", "82245", "82248", "82254", "82255", "82256", "82257", "82258", "82259", "82264", "82266", "82267", "82268", "82272", "82275", "82278", "82279", "82280", "82281", "82283", "82286", "82290", "82298", "82302", "82305", "82306", "82307", "82308", "82309", "82310", "82311", "82313", "82314", "82315", "82316", "82317", "82318", "82322", "82324", "82325", "82327", "82335", "82336", "82338", "82339", "82342", "82343", "82347", "82349", "82350", "82351", "82352", "82353", "82356", "82359", "82363", "82364", "82365", "82367", "82368", "82369", "82370", "82371", "82372", "82373", "82375", "82378", "82380", "82385", "82386", "82387", "82390", "82398", "82400", "82405", "82408", "82409", "82411", "82412", "82413", "82414", "82416", "82417", "82419", "82420", "82429", "82430", "82431", "82435", "82438", "82443", "82444", "82445", "82446", "82447", "82450", "82452", "82453", "82456", "82460", "82464", "82468", "82470", "82472", "82473", "82474", "82476", "82478", "82479", "82480", "82482", "82483", "82485", "82488", "82490", "82491", "82492", "82493", "82497", "82502", "82503", "82505", "82506", "82508", "82509", "82515", "82518", "82519", "82522", "82523", "82524", "82526", "82527", "82528", "82529", "82537", "82538", "82539", "82543", "82546", "82547", "82550", "82552", "82554", "82556", "82558", "82559", "82560", "82562", "82563", "82566", "82567", "82569", "82575", "82576", "82577", "82578", "82581", "82583", "82585", "82589", "82594", "82596", "82598", "82599", "82601", "82603", "82606", "82609", "82610", "82611", "82613", "82614", "82617", "82620", "82622", "82624", "82627", "82629", "82631", "82632", "82633", "82634", "82635", "82639", "82641", "82642", "82643", "82644", "82645", "82648", "82649", "82653", "82658", "82660", "82662", "82663", "82665", "82667", "82670", "82675", "82677", "82679", "82680", "82682", "82683", "82684", "82685", "82687", "82688", "82689", "82690", "82693", "82694", "82695", "82697", "82700", "82703", "82704", "82706", "82707", "82710", "82711", "82712", "82714", "82715", "82718", "82720", "82721", "82722", "82723", "82724", "82725", "82729", "82730", "82731", "82732", "82733", "82735", "82737", "82740", "82741", "82743", "82744", "82746", "82747", "82754", "82755", "82757", "82761", "82763", "82764", "82766", "82767", "82769", "82771", "82772", "82773", "82775", "82777", "82779", "82781", "82786", "82788", "82791", "82792", "82793", "82794", "82795", "82803", "82804", "82808", "82809", "82811", "82814", "82815", "82816", "82824", "82826", "82827", "82829", "82831", "82832", "82833", "82835", "82837", "82839", "82840", "82842", "82845", "82848", "82851", "82852", "82856", "82857", "82858", "82859", "82861", "82865", "82870", "82872", "82879", "82880", "82881", "82884", "82885", "82886", "82890", "82892", "82895", "82896", "82897", "82898", "82899", "82900", "82903", "82904", "82905", "82906", "82908", "82915", "82917", "82918", "82919", "82921", "82922", "82923", "82924", "82926", "82928", "82929", "82932", "82936", "82939", "82941", "82944", "82946", "82949", "82950", "82952", "82954", "82955", "82957", "82959", "82960", "82962", "82966", "82967", "82968", "82969", "82970", "82972", "82973", "82975", "82979", "82980", "82981", "82983", "82985", "82987", "82989", "82992", "82994", "82997", "82998", "82999", "83001", "83004", "83006", "83011", "83012", "83016", "83018", "83019", "83020", "83022", "83027", "83029", "83031", "83033", "83037", "83041", "83042", "83043", "83044", "83045", "83046", "83050", "83054", "83055", "83056", "83057", "83058", "83059", "83061", "83062", "83063", "83067", "83068", "83070", "83072", "83076", "83082", "83085", "83087", "83089", "83090", "83092", "83093", "83095", "83098", "83101", "83102", "83103", "83104", "83105", "83108", "83109", "83113", "83114", "83116", "83118", "83122", "83124", "83125", "83126", "83128", "83130", "83133", "83134", "83135", "83137", "83138", "83144", "83146", "83151", "83153", "83154", "83159", "83162", "83163", "83164", "83165", "83166", "83168", "83173", "83176", "83179", "83180", "83181", "83182", "83184", "83186", "83188", "83189", "83196", "83197", "83200", "83201", "83203", "83209", "83213", "83214", "83221", "83222", "83224", "83226", "83227", "83228", "83229", "83230", "83231", "83232", "83236", "83237", "83241", "83245", "83246", "83247", "83252", "83255", "83257", "83259", "83260", "83261", "83263", "83264", "83267", "83269", "83270", "83274", "83275", "83277", "83280", "83282", "83283", "83284", "83285", "83288", "83293", "83294", "83295", "83297", "83299", "83304", "83305", "83307", "83308", "83310", "83311", "83312", "83314", "83315", "83317", "83319", "83320", "83321", "83322", "83323", "83324", "83325", "83326", "83327", "83334", "83337", "83340", "83341", "83342", "83345", "83348", "83349", "83350", "83351", "83352", "83354", "83355", "83358", "83360", "83363", "83364", "83368", "83369", "83370", "83373", "83375", "83378", "83379", "83380", "83381", "83382", "83389", "83391", "83393", "83394", "83395", "83397", "83400", "83401", "83404", "83405", "83407", "83409", "83410", "83411", "83415", "83416", "83417", "83418", "83419", "83421", "83424", "83425", "83426", "83427", "83429", "83431", "83432", "83433", "83434", "83436", "83442", "83443", "83446", "83447", "83451", "83452", "83454", "83459", "83461", "83464", "83465", "83467", "83468", "83472", "83473", "83476", "83477", "83481", "83482", "83485", "83487", "83488", "83491", "83494", "83496", "83498", "83499", "83501", "83505", "83508", "83510", "83511", "83512", "83514", "83515", "83516", "83517", "83518", "83519", "83520", "83521", "83522", "83524", "83526", "83528", "83529", "83530", "83532", "83533", "83535", "83537", "83538", "83539", "83542", "83544", "83549", "83550", "83552", "83553", "83555", "83556", "83557", "83558", "83560", "83561", "83566", "83567", "83569", "83570", "83573", "83574", "83580", "83581", "83583", "83585", "83591", "83592", "83594", "83596", "83598", "83600", "83601", "83604", "83605", "83607", "83609", "83610", "83612", "83616", "83619", "83620", "83621", "83624", "83625", "83627", "83632", "83633", "83635", "83639", "83643", "83644", "83645", "83646", "83647", "83650", "83652", "83654", "83655", "83658", "83660", "83661", "83663", "83666", "83667", "83670", "83671", "83674", "83678", "83682", "83684", "83685", "83686", "83690", "83691", "83692", "83693", "83699", "83701", "83702", "83703", "83704", "83706", "83710", "83711", "83713", "83714", "83717", "83718", "83719", "83720", "83721", "83725", "83727", "83728", "83729", "83730", "83733", "83734", "83735", "83737", "83738", "83740", "83742", "83743", "83744", "83747", "83750", "83755", "83757", "83759", "83761", "83763", "83764", "83765", "83767", "83769", "83770", "83771", "83772", "83773", "83775", "83784", "83785", "83786", "83787", "83790", "83793", "83794", "83796", "83797", "83799", "83800", "83801", "83802", "83804", "83806", "83808", "83809", "83811", "83812", "83815", "83821", "83823", "83824", "83825", "83826", "83829", "83830", "83831", "83832", "83833", "83834", "83836", "83837", "83838", "83839", "83842", "83843", "83852", "83853", "83854", "83855", "83856", "83863", "83864", "83865", "83866", "83867", "83868", "83869", "83871", "83872", "83873", "83875", "83876", "83881", "83882", "83883", "83886", "83887", "83888", "83890", "83891", "83892", "83895", "83899", "83902", "83906", "83908", "83909", "83910", "83911", "83914", "83915", "83916", "83917", "83922", "83929", "83930", "83931", "83933", "83935", "83938", "83939", "83941", "83945", "83947", "83950", "83951", "83952", "83954", "83956", "83958", "83959", "83961", "83962", "83963", "83965", "83968", "83970", "83972", "83975", "83976", "83978", "83980", "83981", "83982", "83987", "83989", "83990", "83992", "83993", "83994", "84002", "84004", "84005", "84007", "84008", "84009", "84013", "84015", "84016", "84017", "84020", "84025", "84026", "84028", "84029", "84030", "84034", "84036", "84037", "84038", "84039", "84042", "84047", "84050", "84051", "84052", "84053", "84054", "84058", "84059", "84062", "84065", "84066", "84067", "84069", "84072", "84073", "84074", "84075", "84076", "84077", "84078", "84080", "84081", "84082", "84083", "84084", "84085", "84089", "84090", "84092", "84099", "84102", "84103", "84106", "84107", "84110", "84112", "84114", "84115", "84116", "84118", "84119", "84124", "84125", "84127", "84128", "84132", "84137", "84140", "84141", "84145", "84146", "84147", "84150", "84151", "84154", "84155", "84156", "84157", "84158", "84159", "84160", "84162", "84163", "84165", "84170", "84172", "84173", "84175", "84176", "84180", "84182", "84185", "84187", "84188", "84189", "84190", "84191", "84193", "84194", "84197", "84198", "84199", "84202", "84207", "84208", "84214", "84216", "84217", "84220", "84225", "84229", "84230", "84231", "84232", "84233", "84235", "84236", "84237", "84240", "84244", "84247", "84248", "84252", "84254", "84256", "84257", "84258", "84261", "84263", "84266", "84268", "84270", "84272", "84273", "84275", "84276", "84277", "84281", "84283", "84286", "84287", "84288", "84289", "84292", "84295", "84296", "84297", "84299", "84300", "84302", "84303", "84304", "84306", "84309", "84311", "84313", "84314", "84317", "84319", "84321", "84323", "84325", "84327", "84332", "84338", "84339", "84340", "84341", "84342", "84343", "84345", "84346", "84347", "84348", "84351", "84353", "84355", "84357", "84358", "84359", "84360", "84362", "84363", "84364", "84365", "84368", "84370", "84372", "84373", "84374", "84375", "84376", "84377", "84379", "84380", "84384", "84386", "84388", "84391", "84393", "84395", "84397", "84398", "84400", "84402", "84404", "84406", "84408", "84409", "84414", "84415", "84417", "84419", "84420", "84421", "84423", "84425", "84429", "84431", "84433", "84435", "84437", "84440", "84445", "84452", "84453", "84455", "84456", "84457", "84458", "84459", "84461", "84464", "84465", "84466", "84467", "84468", "84469", "84471", "84474", "84475", "84476", "84479", "84480", "84482", "84483", "84486", "84487", "84493", "84496", "84497", "84498", "84499", "84500", "84501", "84502", "84506", "84507", "84508", "84509", "84510", "84512", "84514", "84517", "84522", "84523", "84525", "84528", "84530", "84531", "84533", "84534", "84535", "84537", "84539", "84540", "84541", "84543", "84547", "84552", "84554", "84557", "84561", "84562", "84563", "84564", "84565", "84566", "84568", "84569", "84570", "84571", "84572", "84573", "84574", "84575", "84576", "84577", "84578", "84579", "84582", "84584", "84588", "84589", "84591", "84593", "84595", "84596", "84598", "84602", "84603", "84604", "84611", "84612", "84613", "84614", "84615", "84618", "84620", "84621", "84622", "84626", "84627", "84630", "84631", "84632", "84633", "84635", "84636", "84638", "84639", "84640", "84641", "84642", "84645", "84647", "84648", "84649", "84651", "84652", "84654", "84655", "84657", "84659", "84661", "84664", "84665", "84666", "84669", "84672", "84675", "84676", "84679", "84681", "84682", "84684", "84685", "84688", "84690", "84692", "84696", "84699", "84700", "84701", "84703", "84705", "84706", "84709", "84710", "84711", "84712", "84713", "84715", "84719", "84721", "84722", "84724", "84728", "84729", "84734", "84736", "84737", "84738", "84741", "84742", "84743", "84745", "84750", "84757", "84758", "84760", "84762", "84766", "84767", "84768", "84773", "84774", "84780", "84782", "84788", "84792", "84793", "84794", "84796", "84797", "84799", "84800", "84801", "84803", "84804", "84808", "84809", "84811", "84815", "84816", "84818", "84824", "84825", "84826", "84827", "84828", "84831", "84833", "84834", "84837", "84839", "84840", "84841", "84845", "84846", "84851", "84858", "84859", "84860", "84863", "84864", "84865", "84866", "84867", "84869", "84870", "84879", "84880", "84883", "84884", "84885", "84887", "84888", "84893", "84894", "84895", "84896", "84897", "84898", "84899", "84901", "84902", "84905", "84906", "84907", "84908", "84910", "84911", "84913", "84914", "84918", "84919", "84921", "84926", "84927", "84928", "84931", "84932", "84936", "84937", "84941", "84944", "84945", "84948", "84949", "84950", "84951", "84954", "84956", "84958", "84960", "84961", "84962", "84965", "84966", "84967", "84971", "84973", "84974", "84975", "84977", "84979", "84980", "84981", "84983", "84984", "84986", "84987", "84989", "84990", "84991", "84994", "84996", "84998", "85001", "85002", "85003", "85005", "85007", "85008", "85012", "85013", "85016", "85018", "85019", "85020", "85021", "85022", "85024", "85025", "85028", "85030", "85033", "85035", "85036", "85037", "85038", "85039", "85042", "85043", "85045", "85046", "85048", "85049", "85052", "85054", "85055", "85059", "85060", "85062", "85065", "85066", "85067", "85068", "85069", "85073", "85074", "85075", "85078", "85081", "85084", "85086", "85089", "85091", "85092", "85094", "85096", "85097", "85099", "85100", "85101", "85103", "85104", "85105", "85107", "85110", "85111", "85112", "85113", "85114", "85115", "85118", "85119", "85121", "85123", "85131", "85133", "85134", "85138", "85139", "85140", "85142", "85143", "85145", "85146", "85147", "85148", "85149", "85153", "85154", "85157", "85159", "85161", "85163", "85165", "85169", "85174", "85182", "85183", "85184", "85186", "85189", "85195", "85196", "85198", "85200", "85201", "85202", "85203", "85204", "85208", "85209", "85210", "85214", "85215", "85220", "85221", "85222", "85223", "85225", "85228", "85229", "85232", "85233", "85237", "85238", "85239", "85241", "85242", "85243", "85244", "85247", "85248", "85250", "85258", "85259", "85260", "85264", "85266", "85269", "85270", "85271", "85272", "85273", "85276", "85277", "85279", "85281", "85282", "85283", "85284", "85286", "85288", "85289", "85291", "85292", "85293", "85294", "85295", "85303", "85305", "85309", "85314", "85315", "85316", "85317", "85318", "85319", "85320", "85321", "85322", "85326", "85328", "85329", "85331", "85332", "85333", "85336", "85337", "85341", "85343", "85346", "85350", "85351", "85355", "85358", "85362", "85364", "85365", "85366", "85370", "85371", "85372", "85375", "85376", "85377", "85379", "85381", "85382", "85383", "85384", "85385", "85386", "85391", "85392", "85393", "85394", "85396", "85399", "85400", "85401", "85402", "85403", "85404", "85405", "85406", "85409", "85410", "85411", "85412", "85413", "85415", "85416", "85417", "85419", "85420", "85422", "85424", "85425", "85426", "85427", "85428", "85429", "85430", "85431", "85434", "85436", "85446", "85448", "85452", "85454", "85455", "85457", "85460", "85461", "85462", "85464", "85465", "85467", "85468", "85469", "85471", "85472", "85474", "85479", "85483", "85485", "85486", "85487", "85491", "85493", "85495", "85496", "85497", "85498", "85499", "85501", "85503", "85504", "85506", "85507", "85509", "85512", "85513", "85514", "85515", "85519", "85520", "85521", "85523", "85524", "85526", "85528", "85533", "85534", "85536", "85546", "85547", "85550", "85551", "85554", "85555", "85556", "85558", "85560", "85564", "85566", "85567", "85568", "85575", "85576", "85577", "85580", "85581", "85583", "85589", "85593", "85594", "85596", "85597", "85599", "85601", "85602", "85603", "85604", "85605", "85606", "85609", "85611", "85614", "85615", "85617", "85618", "85619", "85620", "85623", "85624", "85625", "85626", "85633", "85634", "85636", "85637", "85638", "85642", "85643", "85645", "85646", "85647", "85652", "85653", "85654", "85656", "85657", "85658", "85659", "85661", "85663", "85666", "85670", "85671", "85673", "85675", "85676", "85679", "85681", "85682", "85684", "85686", "85687", "85688", "85692", "85693", "85695", "85697", "85698", "85704", "85705", "85706", "85707", "85708", "85709", "85711", "85717", "85718", "85719", "85721", "85722", "85724", "85725", "85727", "85728", "85731", "85732", "85734", "85735", "85737", "85738", "85740", "85742", "85743", "85744", "85748", "85753", "85754", "85755", "85756", "85758", "85759", "85766", "85767", "85768", "85770", "85773", "85775", "85777", "85779", "85781", "85782", "85786", "85787", "85788", "85790", "85791", "85792", "85793", "85796", "85797", "85799", "85802", "85804", "85808", "85815", "85816", "85818", "85821", "85822", "85823", "85827", "85828", "85829", "85830", "85833", "85834", "85836", "85839", "85840", "85842", "85846", "85847", "85849", "85850", "85851", "85852", "85853", "85855", "85856", "85858", "85861", "85863", "85864", "85866", "85867", "85868", "85869", "85870", "85873", "85875", "85876", "85879", "85881", "85882", "85885", "85886", "85887", "85889", "85891", "85893", "85894", "85896", "85898", "85899", "85902", "85903", "85904", "85905", "85906", "85908", "85909", "85911", "85912", "85914", "85917", "85919", "85920", "85922", "85923", "85924", "85925", "85926", "85928", "85929", "85931", "85934", "85936", "85938", "85942", "85945", "85947", "85948", "85949", "85950", "85953", "85954", "85958", "85961", "85963", "85966", "85968", "85969", "85971", "85972", "85974", "85975", "85976", "85977", "85982", "85986", "85987", "85988", "85990", "85991", "85994", "85995", "85997", "85998", "86001", "86004", "86006", "86009", "86010", "86011", "86012", "86014", "86015", "86019", "86025", "86027", "86028", "86029", "86030", "86032", "86033", "86034", "86035", "86036", "86038", "86041", "86042", "86044", "86045", "86048", "86049", "86051", "86052", "86054", "86055", "86057", "86058", "86059", "86062", "86063", "86069", "86073", "86076", "86080", "86081", "86083", "86087", "86088", "86089", "86091", "86094", "86097", "86099", "86102", "86103", "86106", "86108", "86110", "86111", "86113", "86114", "86121", "86123", "86125", "86126", "86127", "86132", "86133", "86135", "86136", "86139", "86140", "86141", "86144", "86145", "86148", "86149", "86152", "86153", "86155", "86157", "86158", "86163", "86168", "86169", "86170", "86174", "86175", "86177", "86179", "86180", "86182", "86185", "86186", "86192", "86193", "86194", "86197", "86199", "86200", "86202", "86209", "86210", "86212", "86214", "86216", "86217", "86218", "86220", "86224", "86226", "86227", "86229", "86231", "86232", "86236", "86238", "86239", "86244", "86245", "86246", "86248", "86250", "86255", "86257", "86258", "86259", "86260", "86261", "86262", "86267", "86269", "86272", "86273", "86274", "86277", "86281", "86285", "86286", "86287", "86290", "86292", "86293", "86296", "86298", "86300", "86301", "86302", "86304", "86309", "86311", "86314", "86315", "86317", "86318", "86319", "86320", "86321", "86322", "86323", "86326", "86327", "86328", "86331", "86337", "86338", "86339", "86340", "86341", "86342", "86343", "86345", "86348", "86350", "86351", "86352", "86354", "86357", "86359", "86361", "86362", "86363", "86364", "86366", "86368", "86369", "86370", "86371", "86374", "86375", "86376", "86377", "86383", "86384", "86386", "86388", "86389", "86396", "86397", "86401", "86402", "86403", "86404", "86405", "86407", "86408", "86409", "86411", "86412", "86418", "86420", "86424", "86428", "86429", "86430", "86431", "86432", "86434", "86436", "86439", "86440", "86441", "86443", "86445", "86446", "86447", "86448", "86449", "86450", "86453", "86454", "86457", "86459", "86461", "86462", "86464", "86468", "86470", "86475", "86479", "86481", "86483", "86485", "86489", "86492", "86493", "86495", "86498", "86499", "86500", "86503", "86504", "86506", "86507", "86508", "86510", "86511", "86513", "86515", "86518", "86519", "86520", "86521", "86524", "86525", "86528", "86530", "86531", "86537", "86538", "86540", "86542", "86543", "86544", "86548", "86551", "86552", "86555", "86556", "86557", "86558", "86560", "86561", "86563", "86564", "86565", "86566", "86573", "86574", "86578", "86581", "86583", "86584", "86585", "86589", "86592", "86598", "86600", "86605", "86606", "86607", "86610", "86619", "86626", "86629", "86631", "86632", "86633", "86634", "86636", "86638", "86641", "86642", "86644", "86647", "86649", "86652", "86653", "86654", "86656", "86658", "86660", "86662", "86664", "86667", "86672", "86673", "86674", "86677", "86683", "86684", "86686", "86687", "86690", "86691", "86693", "86694", "86698", "86703", "86706", "86712", "86713", "86715", "86716", "86717", "86720", "86721", "86722", "86723", "86724", "86727", "86729", "86732", "86733", "86735", "86736", "86737", "86739", "86742", "86743", "86744", "86745", "86748", "86751", "86754", "86755", "86758", "86759", "86762", "86763", "86765", "86767", "86769", "86773", "86774", "86775", "86776", "86777", "86778", "86780", "86782", "86785", "86786", "86787", "86788", "86789", "86793", "86794", "86796", "86799", "86801", "86802", "86803", "86804", "86806", "86808", "86809", "86812", "86814", "86817", "86822", "86824", "86828", "86830", "86831", "86832", "86834", "86835", "86836", "86837", "86838", "86842", "86844", "86845", "86846", "86847", "86848", "86849", "86850", "86851", "86852", "86855", "86856", "86857", "86859", "86862", "86863", "86864", "86865", "86867", "86868", "86872", "86874", "86875", "86876", "86877", "86880", "86881", "86884", "86889", "86894", "86897", "86898", "86899", "86901", "86902", "86905", "86906", "86907", "86908", "86909", "86913", "86914", "86915", "86916", "86917", "86918", "86920", "86921", "86923", "86927", "86930", "86932", "86934", "86937", "86939", "86940", "86941", "86944", "86946", "86947", "86948", "86951", "86952", "86953", "86955", "86957", "86958", "86962", "86965", "86967", "86972", "86973", "86974", "86983", "86984", "86986", "86987", "86988", "86990", "86991", "86994", "86995", "86997", "86999", "87002", "87005", "87008", "87011", "87014", "87017", "87020", "87023", "87026", "87027", "87032", "87033", "87034", "87037", "87038", "87039", "87041", "87044", "87047", "87048", "87049", "87056", "87060", "87063", "87064", "87065", "87066", "87069", "87070", "87071", "87073", "87075", "87079", "87083", "87084", "87086", "87087", "87089", "87090", "87091", "87092", "87093", "87094", "87097", "87098", "87099", "87100", "87101", "87103", "87104", "87106", "87107", "87109", "87110", "87112", "87116", "87117", "87118", "87119", "87120", "87123", "87128", "87130", "87131", "87132", "87134", "87138", "87141", "87144", "87146", "87148", "87150", "87151", "87152", "87153", "87154", "87157", "87160", "87161", "87163", "87164", "87165", "87167", "87172", "87173", "87174", "87175", "87176", "87177", "87178", "87183", "87184", "87185", "87187", "87188", "87190", "87193", "87194", "87195", "87198", "87199", "87200", "87202", "87203", "87209", "87211", "87212", "87216", "87218", "87220", "87221", "87222", "87226", "87228", "87230", "87231", "87232", "87235", "87237", "87238", "87240", "87242", "87244", "87245", "87247", "87248", "87249", "87250", "87253", "87258", "87259", "87260", "87261", "87266", "87269", "87272", "87276", "87277", "87278", "87280", "87281", "87282", "87283", "87284", "87285", "87288", "87291", "87292", "87293", "87294", "87296", "87302", "87303", "87304", "87305", "87308", "87311", "87313", "87314", "87315", "87317", "87318", "87323", "87324", "87325", "87326", "87328", "87329", "87331", "87337", "87343", "87346", "87349", "87350", "87352", "87353", "87354", "87355", "87357", "87358", "87359", "87361", "87362", "87364", "87365", "87366", "87367", "87368", "87370", "87371", "87376", "87378", "87379", "87381", "87384", "87386", "87391", "87392", "87393", "87396", "87399", "87400", "87401", "87402", "87403", "87406", "87407", "87409", "87411", "87414", "87419", "87422", "87423", "87425", "87428", "87432", "87434", "87437", "87438", "87439", "87442", "87444", "87445", "87447", "87449", "87450", "87451", "87453", "87456", "87457", "87459", "87461", "87462", "87464", "87466", "87468", "87471", "87472", "87473", "87477", "87478", "87479", "87481", "87482", "87484", "87486", "87487", "87488", "87491", "87492", "87493", "87494", "87496", "87497", "87498", "87501", "87502", "87503", "87504", "87505", "87511", "87513", "87515", "87517", "87521", "87522", "87523", "87524", "87525", "87526", "87530", "87531", "87533", "87535", "87536", "87538", "87539", "87540", "87541", "87543", "87544", "87545", "87548", "87550", "87551", "87552", "87553", "87555", "87558", "87559", "87560", "87562", "87568", "87571", "87572", "87573", "87574", "87575", "87577", "87580", "87581", "87583", "87584", "87585", "87586", "87587", "87590", "87592", "87594", "87596", "87600", "87602", "87605", "87606", "87609", "87612", "87614", "87615", "87617", "87622", "87623", "87628", "87632", "87633", "87634", "87635", "87637", "87640", "87641", "87645", "87646", "87649", "87651", "87654", "87658", "87660", "87662", "87664", "87665", "87669", "87673", "87675", "87677", "87683", "87685", "87686", "87687", "87688", "87691", "87692", "87701", "87710", "87712", "87713", "87715", "87716", "87718", "87720", "87722", "87723", "87729", "87731", "87732", "87734", "87737", "87738", "87739", "87742", "87743", "87745", "87746", "87751", "87752", "87753", "87757", "87758", "87759", "87763", "87764", "87766", "87771", "87773", "87774", "87776", "87778", "87779", "87783", "87786", "87787", "87788", "87789", "87790", "87791", "87793", "87794", "87795", "87797", "87801", "87803", "87804", "87807", "87808", "87809", "87810", "87811", "87812", "87813", "87815", "87816", "87822", "87824", "87827", "87829", "87830", "87832", "87834", "87836", "87837", "87838", "87841", "87842", "87849", "87850", "87851", "87852", "87855", "87857", "87860", "87863", "87866", "87867", "87868", "87869", "87870", "87873", "87874", "87875", "87877", "87878", "87883", "87884", "87885", "87888", "87889", "87890", "87892", "87894", "87896", "87905", "87907", "87908", "87909", "87911", "87914", "87915", "87916", "87917", "87920", "87921", "87923", "87925", "87926", "87930", "87933", "87934", "87935", "87940", "87942", "87944", "87945", "87946", "87947", "87949", "87953", "87955", "87956", "87957", "87958", "87960", "87964", "87965", "87967", "87968", "87969", "87970", "87971", "87972", "87973", "87974", "87975", "87976", "87977", "87978", "87979", "87980", "87983", "87984", "87985", "87986", "87988", "87993", "87998", "88004", "88008", "88010", "88012", "88015", "88016", "88018", "88019", "88020", "88021", "88022", "88023", "88024", "88025", "88026", "88028", "88031", "88033", "88035", "88040", "88041", "88042", "88043", "88049", "88055", "88059", "88062", "88063", "88065", "88066", "88067", "88068", "88071", "88072", "88074", "88076", "88080", "88081", "88082", "88084", "88085", "88088", "88089", "88090", "88091", "88092", "88095", "88098", "88099", "88102", "88104", "88110", "88112", "88113", "88114", "88115", "88117", "88118", "88119", "88120", "88122", "88123", "88126", "88129", "88130", "88136", "88139", "88140", "88141", "88142", "88145", "88149", "88150", "88152", "88155", "88157", "88161", "88162", "88165", "88166", "88170", "88171", "88173", "88174", "88175", "88176", "88177", "88179", "88180", "88182", "88183", "88185", "88187", "88189", "88191", "88192", "88196", "88200", "88202", "88204", "88206", "88207", "88209", "88215", "88216", "88220", "88221", "88226", "88227", "88230", "88234", "88235", "88237", "88241", "88242", "88243", "88244", "88245", "88246", "88247", "88249", "88251", "88255", "88259", "88260", "88261", "88262", "88265", "88268", "88269", "88270", "88271", "88273", "88275", "88278", "88279", "88280", "88283", "88284", "88287", "88290", "88292", "88293", "88295", "88296", "88297", "88299", "88300", "88301", "88303", "88304", "88306", "88307", "88310", "88311", "88314", "88315", "88316", "88317", "88318", "88321", "88323", "88324", "88325", "88329", "88330", "88331", "88334", "88336", "88337", "88340", "88342", "88344", "88345", "88347", "88348", "88349", "88350", "88352", "88356", "88358", "88359", "88362", "88364", "88365", "88366", "88368", "88371", "88373", "88376", "88384", "88385", "88387", "88394", "88397", "88398", "88400", "88403", "88405", "88406", "88407", "88410", "88412", "88416", "88418", "88420", "88421", "88423", "88427", "88430", "88431", "88433", "88434", "88436", "88438", "88440", "88445", "88446", "88447", "88448", "88449", "88451", "88452", "88453", "88454", "88455", "88457", "88459", "88463", "88464", "88465", "88470", "88471", "88472", "88473", "88477", "88479", "88480", "88481", "88482", "88485", "88486", "88487", "88493", "88498", "88499", "88500", "88503", "88510", "88512", "88513", "88515", "88518", "88519", "88522", "88524", "88525", "88530", "88534", "88536", "88540", "88543", "88544", "88546", "88547", "88548", "88550", "88551", "88553", "88554", "88558", "88561", "88562", "88564", "88566", "88567", "88569", "88570", "88572", "88573", "88574", "88576", "88579", "88580", "88583", "88584", "88586", "88588", "88589", "88590", "88591", "88593", "88594", "88595", "88598", "88603", "88604", "88605", "88607", "88608", "88611", "88612", "88613", "88616", "88619", "88624", "88627", "88629", "88630", "88631", "88632", "88634", "88642", "88643", "88644", "88645", "88648", "88649", "88652", "88653", "88654", "88660", "88663", "88664", "88665", "88670", "88671", "88672", "88673", "88674", "88676", "88678", "88679", "88680", "88682", "88683", "88686", "88687", "88689", "88690", "88691", "88693", "88694", "88695", "88696", "88700", "88701", "88705", "88706", "88707", "88708", "88712", "88713", "88716", "88717", "88721", "88726", "88733", "88737", "88739", "88740", "88744", "88746", "88753", "88755", "88759", "88760", "88761", "88762", "88763", "88767", "88768", "88769", "88770", "88771", "88777", "88781", "88782", "88783", "88784", "88785", "88789", "88791", "88793", "88794", "88796", "88798", "88800", "88802", "88803", "88805", "88807", "88810", "88812", "88813", "88814", "88816", "88819", "88820", "88821", "88823", "88824", "88827", "88828", "88830", "88833", "88835", "88836", "88840", "88842", "88844", "88846", "88849", "88850", "88851", "88852", "88853", "88854", "88857", "88863", "88868", "88870", "88871", "88872", "88874", "88876", "88879", "88881", "88883", "88888", "88889", "88893", "88896", "88897", "88900", "88906", "88907", "88911", "88912", "88914", "88917", "88923", "88924", "88926", "88927", "88928", "88929", "88930", "88931", "88933", "88938", "88939", "88941", "88944", "88946", "88950", "88952", "88954", "88955", "88956", "88958", "88960", "88962", "88967", "88968", "88969", "88970", "88972", "88973", "88975", "88976", "88978", "88981", "88982", "88983", "88984", "88989", "88994", "88995", "88996", "88999", "89000", "89001", "89002", "89003", "89006", "89010", "89014", "89016", "89018", "89019", "89020", "89021", "89022", "89024", "89025", "89027", "89028", "89032", "89034", "89036", "89037", "89042", "89047", "89054", "89056", "89057", "89058", "89061", "89065", "89069", "89073", "89076", "89077", "89082", "89085", "89087", "89088", "89089", "89091", "89092", "89093", "89096", "89097", "89100", "89101", "89105", "89107", "89108", "89111", "89112", "89115", "89117", "89119", "89121", "89122", "89125", "89126", "89127", "89130", "89134", "89137", "89141", "89143", "89144", "89145", "89146", "89152", "89156", "89157", "89158", "89161", "89163", "89164", "89166", "89167", "89168", "89170", "89174", "89175", "89177", "89179", "89183", "89185", "89186", "89187", "89190", "89192", "89193", "89195", "89196", "89197", "89198", "89199", "89200", "89201", "89202", "89203", "89205", "89206", "89207", "89209", "89211", "89212", "89214", "89216", "89218", "89225", "89227", "89232", "89233", "89234", "89235", "89236", "89240", "89241", "89245", "89246", "89247", "89248", "89251", "89252", "89256", "89259", "89263", "89264", "89270", "89274", "89276", "89277", "89278", "89279", "89281", "89283", "89284", "89288", "89289", "89292", "89293", "89300", "89301", "89303", "89304", "89306", "89307", "89309", "89310", "89311", "89313", "89314", "89315", "89317", "89318", "89319", "89321", "89322", "89329", "89330", "89331", "89339", "89340", "89341", "89343", "89345", "89348", "89349", "89350", "89352", "89354", "89355", "89359", "89361", "89364", "89370", "89374", "89375", "89376", "89378", "89379", "89381", "89385", "89386", "89388", "89389", "89390", "89391", "89397", "89400", "89401", "89405", "89409", "89410", "89412", "89414", "89416", "89417", "89418", "89420", "89421", "89423", "89424", "89426", "89428", "89429", "89431", "89433", "89434", "89437", "89439", "89444", "89445", "89448", "89450", "89452", "89455", "89456", "89459", "89461", "89462", "89463", "89464", "89465", "89467", "89468", "89469", "89471", "89475", "89481", "89485", "89486", "89487", "89488", "89489", "89494", "89496", "89498", "89499", "89503", "89505", "89508", "89509", "89512", "89514", "89515", "89516", "89519", "89520", "89528", "89531", "89532", "89533", "89535", "89536", "89541", "89542", "89543", "89545", "89547", "89548", "89550", "89552", "89553", "89554", "89557", "89558", "89560", "89561", "89562", "89565", "89566", "89567", "89568", "89571", "89574", "89580", "89582", "89583", "89584", "89588", "89591", "89598", "89599", "89602", "89603", "89605", "89610", "89611", "89613", "89618", "89619", "89623", "89626", "89628", "89629", "89631", "89632", "89634", "89635", "89637", "89639", "89640", "89641", "89642", "89643", "89646", "89650", "89651", "89653", "89655", "89656", "89657", "89658", "89659", "89661", "89662", "89664", "89666", "89667", "89670", "89672", "89673", "89677", "89679", "89682", "89684", "89686", "89687", "89688", "89694", "89695", "89699", "89700", "89704", "89705", "89706", "89707", "89708", "89710", "89715", "89717", "89718", "89720", "89723", "89726", "89727", "89728", "89729", "89731", "89732", "89735", "89736", "89739", "89740", "89741", "89742", "89743", "89744", "89745", "89747", "89749", "89750", "89751", "89755", "89756", "89758", "89759", "89760", "89761", "89765", "89769", "89772", "89776", "89777", "89778", "89779", "89780", "89781", "89784", "89785", "89787", "89788", "89792", "89793", "89795", "89799", "89801", "89804", "89806", "89809", "89813", "89814", "89815", "89816", "89817", "89818", "89819", "89820", "89821", "89822", "89823", "89825", "89828", "89831", "89832", "89833", "89834", "89835", "89837", "89840", "89841", "89842", "89843", "89845", "89847", "89848", "89851", "89852", "89853", "89857", "89859", "89862", "89865", "89869", "89871", "89873", "89874", "89876", "89878", "89879", "89880", "89882", "89883", "89886", "89888", "89890", "89895", "89896", "89897", "89899", "89902", "89904", "89907", "89908", "89910", "89915", "89916", "89917", "89920", "89924", "89925", "89931", "89933", "89937", "89940", "89944", "89949", "89954", "89956", "89958", "89959", "89960", "89962", "89963", "89964", "89965", "89967", "89968", "89970", "89973", "89976", "89979", "89980", "89981", "89984", "89990", "89992", "89994", "89995", "89997", "89999", "90000", "90002", "90003", "90008", "90009", "90012", "90014", "90015", "90016", "90018", "90019", "90020", "90023", "90024", "90025", "90028", "90030", "90032", "90033", "90035", "90036", "90037", "90040", "90041", "90043", "90045", "90046", "90048", "90052", "90053", "90055", "90056", "90057", "90058", "90060", "90062", "90063", "90067", "90072", "90074", "90076", "90077", "90078", "90079", "90080", "90081", "90082", "90085", "90086", "90087", "90096", "90097", "90099", "90101", "90102", "90104", "90105", "90106", "90111", "90112", "90114", "90115", "90116", "90117", "90118", "90119", "90121", "90123", "90124", "90125", "90126", "90127", "90128", "90129", "90131", "90132", "90133", "90135", "90136", "90138", "90139", "90142", "90143", "90144", "90147", "90150", "90152", "90155", "90157", "90158", "90159", "90161", "90162", "90163", "90165", "90167", "90169", "90170", "90175", "90176", "90178", "90179", "90183", "90184", "90185", "90186", "90187", "90188", "90189", "90191", "90192", "90194", "90196", "90198", "90200", "90205", "90207", "90208", "90209", "90210", "90211", "90213", "90215", "90216", "90219", "90221", "90222", "90223", "90227", "90228", "90231", "90233", "90234", "90237", "90238", "90239", "90241", "90247", "90248", "90250", "90251", "90253", "90256", "90257", "90258", "90259", "90261", "90262", "90263", "90267", "90268", "90272", "90273", "90274", "90275", "90277", "90281", "90284", "90285", "90286", "90287", "90289", "90290", "90291", "90292", "90296", "90299", "90301", "90302", "90306", "90307", "90308", "90311", "90312", "90313", "90315", "90318", "90319", "90320", "90321", "90322", "90325", "90326", "90328", "90329", "90330", "90334", "90335", "90336", "90337", "90338", "90339", "90340", "90345", "90346", "90352", "90353", "90357", "90359", "90363", "90365", "90369", "90370", "90375", "90376", "90377", "90378", "90379", "90380", "90382", "90383", "90387", "90388", "90390", "90391", "90394", "90402", "90405", "90407", "90408", "90409", "90416", "90417", "90418", "90419", "90420", "90423", "90426", "90427", "90428", "90429", "90430", "90431", "90432", "90434", "90436", "90438", "90439", "90442", "90443", "90444", "90446", "90447", "90451", "90452", "90455", "90456", "90457", "90462", "90463", "90469", "90470", "90473", "90474", "90475", "90480", "90483", "90486", "90487", "90488", "90493", "90494", "90495", "90496", "90497", "90498", "90499", "90500", "90501", "90502", "90504", "90506", "90508", "90513", "90516", "90517", "90518", "90520", "90524", "90525", "90526", "90528", "90530", "90531", "90532", "90534", "90535", "90536", "90537", "90538", "90539", "90542", "90546", "90549", "90551", "90553", "90555", "90557", "90558", "90561", "90565", "90566", "90567", "90569", "90570", "90574", "90575", "90578", "90580", "90581", "90583", "90584", "90585", "90586", "90588", "90589", "90590", "90592", "90594", "90597", "90598", "90599", "90604", "90605", "90608", "90611", "90612", "90614", "90615", "90617", "90620", "90621", "90622", "90623", "90627", "90628", "90629", "90630", "90631", "90632", "90633", "90635", "90639", "90643", "90644", "90645", "90647", "90648", "90650", "90651", "90653", "90654", "90655", "90656", "90659", "90660", "90662", "90664", "90665", "90669", "90672", "90674", "90675", "90677", "90678", "90680", "90682", "90683", "90685", "90686", "90689", "90693", "90695", "90697", "90698", "90702", "90704", "90706", "90707", "90708", "90710", "90711", "90712", "90713", "90715", "90716", "90717", "90720", "90721", "90723", "90724", "90725", "90726", "90729", "90731", "90732", "90733", "90734", "90735", "90741", "90742", "90744", "90745", "90750", "90751", "90752", "90753", "90754", "90755", "90763", "90764", "90765", "90766", "90769", "90772", "90774", "90775", "90780", "90785", "90791", "90792", "90796", "90797", "90802", "90803", "90804", "90807", "90808", "90811", "90812", "90813", "90814", "90815", "90818", "90819", "90820", "90821", "90822", "90826", "90827", "90829", "90830", "90833", "90836", "90837", "90838", "90839", "90840", "90841", "90842", "90843", "90844", "90845", "90847", "90849", "90852", "90855", "90856", "90858", "90863", "90864", "90868", "90872", "90877", "90878", "90880", "90881", "90882", "90883", "90884", "90885", "90886", "90889", "90891", "90893", "90896", "90900", "90901", "90902", "90903", "90905", "90906", "90908", "90910", "90911", "90914", "90918", "90921", "90922", "90923", "90924", "90928", "90929", "90930", "90932", "90933", "90934", "90935", "90937", "90938", "90939", "90940", "90941", "90943", "90944", "90945", "90949", "90950", "90953", "90957", "90958", "90959", "90961", "90962", "90963", "90965", "90967", "90968", "90970", "90971", "90972", "90974", "90975", "90976", "90978", "90982", "90984", "90988", "90989", "90990", "90991", "90992", "90994", "90996", "90998", "91003", "91005", "91006", "91009", "91010", "91011", "91012", "91014", "91015", "91017", "91018", "91021", "91023", "91024", "91025", "91027", "91031", "91032", "91035", "91037", "91039", "91043", "91045", "91048", "91049", "91052", "91055", "91058", "91059", "91061", "91063", "91067", "91070", "91071", "91072", "91073", "91075", "91077", "91078", "91080", "91081", "91083", "91084", "91090", "91093", "91094", "91095", "91096", "91097", "91099", "91100", "91102", "91105", "91108", "91110", "91111", "91114", "91116", "91117", "91118", "91124", "91125", "91126", "91127", "91128", "91129", "91130", "91132", "91134", "91135", "91136", "91138", "91139", "91141", "91144", "91145", "91146", "91147", "91150", "91153", "91154", "91155", "91156", "91157", "91159", "91160", "91163", "91164", "91167", "91168", "91170", "91173", "91176", "91179", "91180", "91182", "91185", "91187", "91190", "91192", "91193", "91194", "91195", "91199", "91200", "91202", "91204", "91205", "91206", "91207", "91208", "91211", "91215", "91216", "91219", "91220", "91224", "91226", "91229", "91230", "91231", "91234", "91235", "91240", "91241", "91243", "91244", "91245", "91250", "91253", "91258", "91260", "91262", "91265", "91267", "91268", "91269", "91270", "91272", "91273", "91274", "91277", "91280", "91291", "91292", "91293", "91298", "91300", "91301", "91302", "91306", "91308", "91310", "91311", "91317", "91318", "91319", "91320", "91321", "91323", "91324", "91326", "91329", "91331", "91333", "91337", "91342", "91343", "91344", "91347", "91354", "91355", "91356", "91357", "91358", "91359", "91361", "91362", "91365", "91367", "91370", "91371", "91373", "91375", "91377", "91378", "91382", "91384", "91385", "91386", "91387", "91388", "91389", "91390", "91392", "91393", "91394", "91395", "91396", "91397", "91399", "91400", "91404", "91405", "91407", "91408", "91410", "91414", "91416", "91424", "91427", "91428", "91432", "91434", "91436", "91437", "91438", "91440", "91441", "91443", "91445", "91447", "91448", "91450", "91452", "91454", "91461", "91462", "91464", "91468", "91469", "91473", "91474", "91476", "91484", "91486", "91487", "91489", "91490", "91500", "91502", "91503", "91506", "91507", "91508", "91509", "91510", "91512", "91513", "91514", "91515", "91517", "91518", "91521", "91526", "91530", "91535", "91541", "91544", "91545", "91552", "91554", "91555", "91560", "91567", "91568", "91569", "91571", "91574", "91575", "91578", "91579", "91581", "91582", "91586", "91589", "91590", "91591", "91592", "91597", "91598", "91600", "91603", "91605", "91608", "91609", "91610", "91611", "91613", "91614", "91616", "91617", "91620", "91622", "91624", "91629", "91631", "91638", "91640", "91642", "91643", "91644", "91646", "91648", "91650", "91651", "91655", "91663", "91670", "91676", "91677", "91678", "91679", "91683", "91686", "91687", "91690", "91691", "91692", "91693", "91695", "91696", "91697", "91698", "91699", "91700", "91701", "91702", "91704", "91705", "91706", "91707", "91708", "91711", "91712", "91713", "91715", "91717", "91718", "91720", "91723", "91725", "91727", "91728", "91729", "91730", "91731", "91732", "91733", "91735", "91737", "91738", "91741", "91742", "91743", "91744", "91749", "91750", "91753", "91754", "91755", "91762", "91765", "91768", "91770", "91771", "91774", "91775", "91779", "91780", "91781", "91782", "91783", "91785", "91788", "91790", "91793", "91794", "91798", "91801", "91803", "91807", "91809", "91810", "91812", "91814", "91815", "91816", "91819", "91820", "91822", "91823", "91828", "91830", "91831", "91832", "91835", "91836", "91837", "91838", "91840", "91844", "91847", "91848", "91849", "91850", "91852", "91857", "91858", "91861", "91862", "91863", "91867", "91873", "91875", "91877", "91878", "91879", "91880", "91881", "91884", "91894", "91895", "91896", "91898", "91903", "91906", "91910", "91914", "91915", "91916", "91917", "91919", "91922", "91925", "91928", "91930", "91931", "91933", "91935", "91938", "91939", "91941", "91942", "91944", "91945", "91946", "91950", "91951", "91955", "91956", "91957", "91958", "91962", "91963", "91966", "91968", "91971", "91972", "91973", "91975", "91977", "91978", "91980", "91981", "91983", "91984", "91987", "91988", "91989", "91992", "91993", "91994", "91995", "91997", "92008", "92009", "92011", "92012", "92013", "92016", "92017", "92020", "92021", "92022", "92025", "92026", "92027", "92028", "92032", "92033", "92034", "92036", "92039", "92040", "92042", "92043", "92046", "92047", "92048", "92053", "92056", "92057", "92059", "92060", "92063", "92066", "92070", "92071", "92073", "92074", "92075", "92079", "92082", "92084", "92085", "92086", "92089", "92091", "92092", "92094", "92095", "92097", "92100", "92102", "92104", "92105", "92106", "92109", "92110", "92111", "92112", "92113", "92116", "92118", "92122", "92124", "92128", "92130", "92131", "92134", "92137", "92140", "92142", "92144", "92145", "92147", "92148", "92149", "92150", "92151", "92152", "92153", "92154", "92155", "92156", "92157", "92158", "92161", "92163", "92165", "92169", "92172", "92175", "92176", "92178", "92182", "92184", "92187", "92188", "92190", "92191", "92194", "92195", "92198", "92199", "92205", "92207", "92213", "92215", "92216", "92218", "92220", "92221", "92222", "92224", "92225", "92232", "92233", "92234", "92235", "92239", "92240", "92241", "92242", "92244", "92248", "92249", "92250", "92253", "92254", "92256", "92258", "92260", "92262", "92264", "92265", "92270", "92271", "92272", "92275", "92278", "92279", "92281", "92288", "92289", "92293", "92296", "92297", "92299", "92304", "92306", "92312", "92313", "92315", "92316", "92317", "92318", "92321", "92324", "92326", "92331", "92332", "92333", "92335", "92338", "92339", "92340", "92341", "92342", "92346", "92347", "92348", "92350", "92351", "92352", "92354", "92357", "92358", "92359", "92362", "92370", "92371", "92373", "92375", "92376", "92380", "92381", "92382", "92383", "92384", "92385", "92387", "92389", "92390", "92391", "92392", "92397", "92400", "92401", "92406", "92407", "92408", "92410", "92412", "92413", "92416", "92418", "92420", "92422", "92424", "92425", "92426", "92427", "92428", "92430", "92435", "92437", "92439", "92443", "92445", "92446", "92447", "92449", "92452", "92453", "92454", "92461", "92466", "92471", "92472", "92475", "92476", "92478", "92479", "92481", "92483", "92484", "92485", "92486", "92488", "92489", "92492", "92493", "92494", "92501", "92502", "92504", "92507", "92509", "92510", "92514", "92516", "92517", "92518", "92519", "92521", "92525", "92527", "92529", "92531", "92532", "92533", "92535", "92536", "92537", "92541", "92546", "92547", "92549", "92550", "92551", "92552", "92553", "92555", "92556", "92558", "92560", "92563", "92568", "92569", "92570", "92571", "92572", "92573", "92574", "92575", "92576", "92584", "92585", "92586", "92593", "92596", "92598", "92600", "92602", "92604", "92606", "92608", "92609", "92610", "92611", "92614", "92615", "92616", "92620", "92623", "92624", "92625", "92626", "92627", "92629", "92630", "92632", "92633", "92637", "92641", "92643", "92648", "92649", "92650", "92654", "92657", "92658", "92659", "92663", "92664", "92665", "92667", "92668", "92670", "92671", "92672", "92673", "92674", "92677", "92679", "92680", "92681", "92682", "92683", "92685", "92693", "92697", "92699", "92701", "92702", "92705", "92706", "92710", "92711", "92713", "92715", "92716", "92719", "92720", "92721", "92723", "92724", "92726", "92730", "92731", "92732", "92733", "92735", "92736", "92737", "92738", "92740", "92742", "92744", "92746", "92753", "92754", "92755", "92756", "92757", "92759", "92763", "92769", "92770", "92772", "92773", "92775", "92776", "92778", "92780", "92782", "92783", "92785", "92786", "92788", "92789", "92790", "92795", "92797", "92800", "92805", "92807", "92809", "92813", "92816", "92817", "92818", "92820", "92824", "92826", "92827", "92829", "92830", "92831", "92833", "92835", "92837", "92838", "92839", "92840", "92847", "92850", "92851", "92854", "92856", "92857", "92858", "92860", "92865", "92866", "92867", "92870", "92871", "92873", "92875", "92879", "92888", "92889", "92891", "92892", "92893", "92894", "92895", "92898", "92901", "92903", "92905", "92908", "92911", "92912", "92913", "92916", "92919", "92925", "92926", "92927", "92928", "92929", "92930", "92931", "92938", "92939", "92940", "92943", "92944", "92947", "92950", "92951", "92953", "92955", "92956", "92958", "92959", "92962", "92965", "92968", "92972", "92975", "92980", "92984", "92985", "92986", "92987", "92988", "92990", "92992", "92994", "92998", "93001", "93002", "93004", "93010", "93012", "93015", "93016", "93018", "93019", "93020", "93021", "93022", "93023", "93026", "93027", "93029", "93030", "93035", "93037", "93038", "93042", "93044", "93049", "93053", "93054", "93058", "93060", "93062", "93063", "93065", "93070", "93072", "93073", "93074", "93075", "93076", "93079", "93080", "93086", "93088", "93090", "93092", "93093", "93094", "93097", "93098", "93099", "93102", "93103", "93109", "93110", "93112", "93114", "93116", "93117", "93118", "93119", "93120", "93121", "93125", "93126", "93128", "93130", "93131", "93133", "93137", "93139", "93140", "93141", "93144", "93147", "93148", "93149", "93152", "93156", "93161", "93168", "93170", "93174", "93175", "93183", "93185", "93186", "93187", "93188", "93189", "93190", "93191", "93192", "93193", "93194", "93198", "93199", "93200", "93201", "93202", "93203", "93204", "93206", "93208", "93213", "93214", "93222", "93224", "93227", "93229", "93233", "93234", "93235", "93236", "93242", "93243", "93244", "93248", "93253", "93256", "93259", "93261", "93263", "93264", "93269", "93270", "93272", "93278", "93279", "93281", "93284", "93286", "93290", "93291", "93294", "93297", "93298", "93299", "93304", "93307", "93308", "93310", "93311", "93313", "93314", "93317", "93320", "93321", "93322", "93323", "93328", "93329", "93330", "93335", "93343", "93345", "93347", "93348", "93349", "93350", "93355", "93356", "93358", "93359", "93362", "93363", "93364", "93365", "93368", "93371", "93372", "93373", "93374", "93375", "93377", "93378", "93380", "93381", "93384", "93385", "93386", "93387", "93388", "93393", "93394", "93398", "93401", "93404", "93405", "93408", "93409", "93410", "93413", "93414", "93415", "93416", "93418", "93419", "93420", "93421", "93425", "93426", "93427", "93428", "93430", "93431", "93432", "93435", "93439", "93440", "93442", "93443", "93445", "93446", "93447", "93448", "93454", "93456", "93461", "93463", "93464", "93465", "93468", "93469", "93473", "93474", "93475", "93482", "93483", "93484", "93485", "93486", "93492", "93495", "93497", "93498", "93499", "93504", "93505", "93506", "93508", "93512", "93513", "93516", "93517", "93519", "93520", "93521", "93522", "93524", "93527", "93528", "93531", "93533", "93534", "93536", "93537", "93540", "93541", "93543", "93546", "93547", "93548", "93550", "93551", "93552", "93556", "93558", "93559", "93560", "93561", "93564", "93565", "93567", "93568", "93571", "93573", "93575", "93578", "93580", "93581", "93583", "93590", "93591", "93592", "93593", "93594", "93595", "93598", "93600", "93601", "93602", "93603", "93606", "93607", "93609", "93610", "93611", "93612", "93615", "93617", "93618", "93619", "93621", "93622", "93624", "93635", "93637", "93638", "93639", "93640", "93642", "93643", "93645", "93651", "93652", "93653", "93657", "93658", "93659", "93661", "93665", "93666", "93667", "93668", "93669", "93673", "93675", "93680", "93682", "93684", "93685", "93688", "93689", "93691", "93692", "93693", "93694", "93695", "93696", "93702", "93703", "93704", "93706", "93714", "93716", "93720", "93721", "93722", "93724", "93725", "93726", "93731", "93732", "93734", "93736", "93737", "93739", "93740", "93741", "93742", "93743", "93747", "93748", "93750", "93751", "93752", "93753", "93754", "93756", "93758", "93763", "93764", "93766", "93768", "93773", "93774", "93778", "93782", "93784", "93785", "93788", "93789", "93798", "93800", "93803", "93807", "93808", "93809", "93810", "93813", "93814", "93819", "93820", "93822", "93824", "93830", "93835", "93840", "93845", "93846", "93848", "93849", "93853", "93854", "93856", "93858", "93860", "93862", "93863", "93866", "93867", "93868", "93871", "93873", "93874", "93875", "93877", "93879", "93880", "93884", "93885", "93886", "93888", "93890", "93891", "93892", "93893", "93895", "93898", "93899", "93900", "93901", "93904", "93905", "93906", "93907", "93908", "93909", "93910", "93912", "93913", "93914", "93915", "93916", "93918", "93919", "93922", "93924", "93931", "93933", "93934", "93935", "93937", "93938", "93940", "93945", "93946", "93949", "93950", "93955", "93957", "93958", "93959", "93961", "93962", "93965", "93966", "93968", "93970", "93972", "93973", "93974", "93975", "93977", "93983", "93984", "93985", "93986", "93987", "93990", "93996", "94003", "94004", "94007", "94010", "94014", "94016", "94020", "94021", "94022", "94024", "94026", "94029", "94032", "94037", "94039", "94040", "94042", "94043", "94044", "94051", "94052", "94054", "94059", "94063", "94064", "94067", "94069", "94070", "94071", "94073", "94078", "94079", "94080", "94081", "94083", "94084", "94085", "94086", "94087", "94089", "94090", "94092", "94095", "94096", "94097", "94101", "94104", "94105", "94106", "94107", "94108", "94109", "94111", "94112", "94113", "94115", "94116", "94117", "94121", "94122", "94124", "94126", "94127", "94128", "94132", "94133", "94136", "94137", "94139", "94140", "94142", "94143", "94144", "94146", "94147", "94148", "94152", "94153", "94154", "94158", "94159", "94162", "94163", "94164", "94165", "94168", "94170", "94171", "94174", "94175", "94176", "94181", "94182", "94184", "94186", "94187", "94189", "94190", "94193", "94194", "94195", "94198", "94199", "94201", "94203", "94204", "94208", "94210", "94211", "94213", "94216", "94217", "94221", "94222", "94223", "94226", "94227", "94231", "94232", "94235", "94236", "94241", "94244", "94245", "94247", "94258", "94259", "94260", "94263", "94264", "94265", "94266", "94268", "94270", "94271", "94275", "94277", "94278", "94279", "94287", "94288", "94290", "94291", "94293", "94296", "94300", "94304", "94308", "94309", "94314", "94316", "94317", "94321", "94324", "94326", "94329", "94330", "94331", "94332", "94333", "94336", "94338", "94340", "94341", "94342", "94343", "94344", "94346", "94348", "94349", "94351", "94354", "94355", "94356", "94359", "94360", "94361", "94364", "94365", "94368", "94371", "94372", "94374", "94379", "94380", "94382", "94384", "94387", "94390", "94392", "94394", "94395", "94396", "94397", "94398", "94399", "94400", "94404", "94405", "94406", "94408", "94411", "94412", "94414", "94415", "94420", "94422", "94423", "94424", "94425", "94426", "94427", "94428", "94429", "94432", "94434", "94438", "94440", "94443", "94444", "94445", "94446", "94448", "94450", "94454", "94456", "94457", "94458", "94459", "94460", "94464", "94465", "94467", "94469", "94471", "94473", "94474", "94475", "94476", "94477", "94478", "94479", "94481", "94484", "94485", "94486", "94488", "94489", "94490", "94491", "94494", "94495", "94498", "94499", "94501", "94502", "94503", "94510", "94512", "94517", "94519", "94525", "94527", "94529", "94531", "94532", "94534", "94536", "94541", "94542", "94544", "94545", "94546", "94547", "94549", "94550", "94554", "94557", "94559", "94560", "94564", "94566", "94567", "94570", "94576", "94577", "94578", "94580", "94582", "94585", "94587", "94593", "94597", "94602", "94603", "94604", "94605", "94609", "94612", "94614", "94615", "94617", "94618", "94619", "94620", "94622", "94623", "94628", "94629", "94630", "94631", "94632", "94633", "94635", "94638", "94639", "94640", "94641", "94642", "94646", "94648", "94649", "94650", "94651", "94652", "94653", "94654", "94658", "94661", "94662", "94664", "94665", "94666", "94667", "94670", "94671", "94673", "94676", "94678", "94679", "94680", "94681", "94690", "94692", "94694", "94695", "94696", "94698", "94699", "94704", "94705", "94706", "94708", "94709", "94710", "94711", "94712", "94716", "94717", "94721", "94723", "94725", "94726", "94727", "94728", "94730", "94731", "94732", "94735", "94738", "94739", "94740", "94743", "94749", "94751", "94752", "94756", "94760", "94761", "94762", "94766", "94767", "94768", "94771", "94772", "94774", "94775", "94776", "94777", "94778", "94779", "94781", "94782", "94783", "94785", "94786", "94787", "94789", "94790", "94793", "94794", "94796", "94798", "94800", "94803", "94805", "94806", "94808", "94811", "94812", "94814", "94816", "94817", "94818", "94820", "94821", "94822", "94823", "94825", "94827", "94835", "94842", "94845", "94850", "94854", "94855", "94857", "94859", "94862", "94864", "94866", "94872", "94873", "94877", "94879", "94881", "94882", "94884", "94888", "94889", "94890", "94891", "94892", "94893", "94896", "94898", "94901", "94903", "94904", "94906", "94908", "94909", "94913", "94916", "94917", "94918", "94921", "94922", "94924", "94927", "94928", "94929", "94932", "94933", "94934", "94937", "94940", "94943", "94951", "94952", "94954", "94959", "94960", "94962", "94963", "94965", "94966", "94969", "94970", "94971", "94972", "94976", "94977", "94978", "94979", "94980", "94981", "94982", "94983", "94985", "94986", "94987", "94988", "94989", "94990", "94992", "94995", "94998", "94999", "95000", "95002", "95006", "95007", "95008", "95009", "95010", "95017", "95020", "95021", "95022", "95023", "95024", "95025", "95027", "95030", "95031", "95032", "95034", "95036", "95037", "95041", "95042", "95043", "95046", "95047", "95048", "95053", "95055", "95058", "95063", "95064", "95065", "95068", "95069", "95075", "95076", "95077", "95078", "95079", "95081", "95084", "95085", "95086", "95087", "95088", "95091", "95093", "95101", "95103", "95104", "95105", "95107", "95108", "95111", "95112", "95114", "95115", "95116", "95120", "95121", "95128", "95131", "95136", "95137", "95142", "95144", "95145", "95150", "95152", "95154", "95156", "95159", "95160", "95162", "95163", "95165", "95168", "95169", "95170", "95172", "95173", "95176", "95178", "95182", "95183", "95189", "95193", "95194", "95196", "95198", "95199", "95201", "95204", "95206", "95207", "95208", "95209", "95211", "95212", "95213", "95216", "95219", "95221", "95224", "95225", "95233", "95234", "95235", "95236", "95237", "95239", "95241", "95242", "95244", "95245", "95248", "95250", "95254", "95255", "95256", "95257", "95258", "95259", "95260", "95261", "95263", "95265", "95268", "95269", "95273", "95274", "95277", "95280", "95281", "95284", "95285", "95286", "95287", "95288", "95289", "95290", "95298", "95299", "95301", "95302", "95305", "95307", "95308", "95309", "95310", "95312", "95316", "95318", "95319", "95320", "95321", "95322", "95323", "95326", "95330", "95335", "95336", "95337", "95341", "95343", "95345", "95346", "95350", "95351", "95360", "95363", "95366", "95368", "95372", "95377", "95379", "95380", "95382", "95383", "95384", "95385", "95386", "95387", "95391", "95393", "95394", "95396", "95399", "95400", "95401", "95404", "95406", "95409", "95410", "95411", "95412", "95413", "95414", "95415", "95417", "95418", "95419", "95424", "95426", "95428", "95433", "95434", "95436", "95437", "95440", "95446", "95447", "95448", "95450", "95453", "95459", "95462", "95463", "95465", "95466", "95467", "95470", "95474", "95476", "95477", "95479", "95481", "95485", "95487", "95488", "95489", "95491", "95494", "95497", "95498", "95502", "95504", "95506", "95507", "95508", "95509", "95513", "95515", "95516", "95520", "95522", "95524", "95526", "95529", "95530", "95531", "95533", "95534", "95538", "95541", "95543", "95544", "95545", "95546", "95547", "95550", "95551", "95552", "95553", "95554", "95557", "95560", "95562", "95563", "95567", "95569", "95574", "95577", "95578", "95579", "95580", "95585", "95586", "95587", "95588", "95590", "95598", "95601", "95603", "95604", "95608", "95610", "95613", "95614", "95620", "95621", "95623", "95625", "95626", "95627", "95629", "95630", "95633", "95636", "95637", "95639", "95643", "95645", "95649", "95650", "95652", "95655", "95656", "95660", "95661", "95662", "95665", "95666", "95667", "95669", "95670", "95671", "95673", "95676", "95677", "95678", "95681", "95682", "95684", "95685", "95689", "95690", "95692", "95693", "95695", "95696", "95697", "95699", "95701", "95703", "95704", "95706", "95707", "95708", "95710", "95711", "95712", "95713", "95717", "95719", "95722", "95723", "95726", "95727", "95729", "95730", "95731", "95732", "95735", "95737", "95738", "95741", "95744", "95746", "95748", "95749", "95752", "95754", "95755", "95756", "95757", "95763", "95766", "95768", "95770", "95771", "95772", "95776", "95779", "95784", "95785", "95787", "95788", "95789", "95790", "95792", "95795", "95796", "95798", "95799", "95802", "95804", "95805", "95806", "95808", "95815", "95817", "95818", "95819", "95820", "95822", "95823", "95826", "95827", "95831", "95833", "95836", "95837", "95841", "95843", "95844", "95848", "95849", "95850", "95852", "95853", "95857", "95859", "95860", "95862", "95863", "95865", "95868", "95869", "95871", "95876", "95880", "95882", "95883", "95884", "95885", "95886", "95887", "95892", "95897", "95902", "95903", "95908", "95909", "95910", "95911", "95913", "95915", "95918", "95919", "95922", "95925", "95926", "95928", "95932", "95934", "95935", "95936", "95937", "95938", "95940", "95942", "95944", "95945", "95946", "95951", "95952", "95954", "95957", "95959", "95960", "95961", "95962", "95963", "95968", "95969", "95971", "95972", "95973", "95974", "95975", "95977", "95981", "95983", "95985", "95986", "95988", "95993", "95996", "96000", "96001", "96002", "96005", "96007", "96008", "96009", "96011", "96012", "96016", "96018", "96023", "96024", "96026", "96029", "96030", "96033", "96036", "96037", "96045", "96046", "96049", "96053", "96054", "96058", "96059", "96061", "96065", "96072", "96073", "96074", "96077", "96078", "96079", "96084", "96086", "96088", "96089", "96091", "96092", "96094", "96095", "96096", "96101", "96103", "96105", "96106", "96108", "96109", "96111", "96114", "96116", "96118", "96119", "96125", "96127", "96128", "96131", "96134", "96137", "96138", "96139", "96140", "96141", "96143", "96144", "96146", "96151", "96153", "96155", "96157", "96158", "96159", "96160", "96161", "96165", "96171", "96174", "96176", "96179", "96181", "96182", "96184", "96185", "96187", "96188", "96189", "96192", "96194", "96195", "96196", "96197", "96198", "96199", "96200", "96208", "96210", "96212", "96215", "96216", "96217", "96225", "96226", "96227", "96229", "96233", "96235", "96236", "96237", "96240", "96243", "96245", "96248", "96250", "96251", "96252", "96253", "96254", "96256", "96257", "96258", "96260", "96261", "96263", "96264", "96267", "96268", "96269", "96270", "96271", "96276", "96280", "96281", "96283", "96285", "96286", "96288", "96290", "96294", "96295", "96296", "96297", "96298", "96300", "96301", "96305", "96306", "96307", "96308", "96309", "96310", "96312", "96315", "96320", "96321", "96323", "96326", "96328", "96329", "96334", "96336", "96339", "96341", "96342", "96344", "96348", "96350", "96351", "96353", "96355", "96360", "96361", "96363", "96364", "96366", "96369", "96370", "96377", "96378", "96381", "96382", "96383", "96385", "96386", "96387", "96388", "96389", "96393", "96401", "96403", "96405", "96406", "96407", "96408", "96409", "96411", "96412", "96413", "96414", "96420", "96421", "96422", "96423", "96424", "96425", "96428", "96429", "96431", "96432", "96433", "96434", "96436", "96438", "96443", "96444", "96445", "96449", "96450", "96453", "96455", "96457", "96466", "96467", "96468", "96472", "96473", "96474", "96475", "96477", "96479", "96480", "96481", "96482", "96483", "96484", "96486", "96488", "96489", "96491", "96492", "96496", "96499", "96502", "96504", "96507", "96508", "96510", "96511", "96513", "96514", "96515", "96517", "96518", "96519", "96521", "96523", "96526", "96531", "96532", "96533", "96534", "96535", "96537", "96538", "96541", "96542", "96543", "96548", "96549", "96551", "96554", "96555", "96558", "96559", "96560", "96565", "96566", "96567", "96570", "96571", "96572", "96576", "96578", "96579", "96581", "96583", "96589", "96590", "96591", "96592", "96593", "96595", "96596", "96598", "96600", "96602", "96603", "96604", "96607", "96608", "96610", "96613", "96614", "96615", "96617", "96620", "96621", "96626", "96627", "96628", "96629", "96630", "96634", "96636", "96638", "96639", "96640", "96641", "96642", "96647", "96649", "96650", "96654", "96655", "96656", "96657", "96658", "96660", "96661", "96667", "96669", "96671", "96673", "96675", "96678", "96679", "96684", "96685", "96688", "96692", "96693", "96697", "96699", "96701", "96704", "96707", "96709", "96712", "96716", "96718", "96719", "96720", "96723", "96724", "96725", "96726", "96728", "96730", "96733", "96735", "96738", "96739", "96740", "96742", "96743", "96744", "96745", "96748", "96749", "96750", "96751", "96753", "96754", "96758", "96759", "96761", "96764", "96765", "96767", "96768", "96772", "96773", "96774", "96778", "96780", "96781", "96782", "96790", "96793", "96794", "96797", "96799", "96800", "96801", "96803", "96804", "96810", "96811", "96817", "96819", "96820", "96822", "96826", "96828", "96833", "96834", "96836", "96838", "96839", "96842", "96845", "96847", "96850", "96854", "96857", "96860", "96862", "96870", "96873", "96874", "96877", "96878", "96879", "96880", "96882", "96883", "96884", "96885", "96886", "96887", "96888", "96890", "96891", "96892", "96894", "96895", "96897", "96898", "96899", "96906", "96909", "96913", "96914", "96919", "96920", "96921", "96923", "96924", "96925", "96926", "96928", "96929", "96930", "96931", "96933", "96934", "96935", "96936", "96939", "96940", "96941", "96944", "96946", "96948", "96950", "96956", "96957", "96958", "96960", "96962", "96963", "96964", "96968", "96970", "96971", "96972", "96973", "96974", "96975", "96977", "96981", "96985", "96987", "96988", "96992", "96993", "96994", "96995", "96996", "96998", "96999", "97000", "97001", "97002", "97003", "97006", "97008", "97011", "97012", "97018", "97019", "97023", "97025", "97026", "97027", "97028", "97029", "97030", "97033", "97034", "97036", "97037", "97039", "97045", "97046", "97047", "97049", "97050", "97051", "97053", "97054", "97055", "97057", "97058", "97059", "97061", "97062", "97063", "97064", "97065", "97067", "97069", "97070", "97072", "97073", "97074", "97075", "97078", "97080", "97081", "97083", "97087", "97088", "97089", "97091", "97093", "97099", "97100", "97103", "97109", "97111", "97112", "97116", "97117", "97121", "97123", "97124", "97126", "97127", "97128", "97133", "97134", "97135", "97136", "97137", "97141", "97142", "97143", "97145", "97146", "97147", "97151", "97152", "97158", "97161", "97164", "97165", "97166", "97167", "97169", "97170", "97171", "97173", "97174", "97176", "97177", "97178", "97186", "97187", "97190", "97191", "97195", "97196", "97197", "97199", "97202", "97203", "97207", "97209", "97210", "97213", "97216", "97218", "97219", "97220", "97227", "97228", "97232", "97234", "97236", "97239", "97243", "97245", "97247", "97248", "97249", "97250", "97251", "97252", "97253", "97254", "97257", "97258", "97259", "97261", "97262", "97263", "97265", "97266", "97274", "97276", "97280", "97281", "97282", "97283", "97285", "97288", "97290", "97293", "97294", "97298", "97302", "97303", "97306", "97313", "97314", "97315", "97317", "97318", "97320", "97321", "97322", "97324", "97329", "97333", "97334", "97335", "97337", "97338", "97340", "97342", "97344", "97349", "97351", "97352", "97354", "97356", "97358", "97361", "97363", "97364", "97365", "97366", "97367", "97371", "97374", "97376", "97377", "97379", "97383", "97389", "97390", "97392", "97394", "97396", "97397", "97399", "97401", "97403", "97407", "97408", "97411", "97412", "97413", "97414", "97415", "97416", "97417", "97418", "97420", "97425", "97426", "97428", "97429", "97431", "97433", "97434", "97435", "97436", "97438", "97443", "97447", "97448", "97452", "97453", "97454", "97455", "97457", "97459", "97460", "97461", "97462", "97464", "97467", "97469", "97471", "97472", "97474", "97477", "97478", "97480", "97482", "97483", "97485", "97486", "97489", "97490", "97492", "97493", "97497", "97504", "97506", "97509", "97510", "97511", "97514", "97515", "97518", "97519", "97521", "97523", "97524", "97525", "97527", "97533", "97534", "97535", "97538", "97540", "97541", "97542", "97543", "97546", "97547", "97549", "97553", "97555", "97557", "97559", "97560", "97561", "97563", "97565", "97569", "97572", "97574", "97577", "97582", "97583", "97584", "97586", "97591", "97592", "97608", "97609", "97611", "97613", "97614", "97615", "97616", "97618", "97619", "97622", "97623", "97630", "97631", "97632", "97633", "97634", "97635", "97639", "97640", "97641", "97642", "97643", "97644", "97645", "97646", "97649", "97650", "97653", "97658", "97659", "97660", "97661", "97662", "97663", "97667", "97669", "97671", "97673", "97677", "97678", "97679", "97681", "97682", "97683", "97686", "97689", "97691", "97692", "97693", "97695", "97696", "97702", "97703", "97709", "97712", "97714", "97716", "97717", "97718", "97719", "97721", "97724", "97727", "97728", "97729", "97732", "97733", "97734", "97736", "97737", "97739", "97743", "97744", "97745", "97746", "97749", "97750", "97751", "97755", "97761", "97765", "97769", "97777", "97778", "97779", "97781", "97783", "97785", "97787", "97788", "97789", "97793", "97794", "97796", "97797", "97798", "97799", "97800", "97801", "97802", "97803", "97804", "97805", "97810", "97814", "97815", "97817", "97819", "97825", "97827", "97830", "97832", "97833", "97835", "97838", "97840", "97841", "97842", "97843", "97844", "97845", "97846", "97847", "97851", "97855", "97857", "97858", "97860", "97867", "97869", "97870", "97872", "97874", "97878", "97880", "97884", "97885", "97888", "97889", "97890", "97891", "97893", "97894", "97897", "97900", "97901", "97902", "97903", "97904", "97909", "97911", "97913", "97914", "97918", "97920", "97921", "97923", "97924", "97925", "97926", "97928", "97929", "97930", "97932", "97933", "97938", "97942", "97943", "97944", "97945", "97947", "97950", "97951", "97953", "97955", "97956", "97960", "97963", "97966", "97971", "97973", "97974", "97976", "97977", "97979", "97981", "97982", "97983", "97984", "97986", "97987", "97989", "97990", "97993", "97998", "98000", "98002", "98010", "98011", "98014", "98017", "98019", "98021", "98022", "98024", "98025", "98026", "98027", "98028", "98031", "98032", "98033", "98035", "98036", "98037", "98038", "98040", "98043", "98045", "98048", "98049", "98052", "98058", "98060", "98061", "98062", "98065", "98067", "98071", "98074", "98075", "98076", "98077", "98078", "98079", "98080", "98081", "98084", "98086", "98091", "98092", "98096", "98098", "98099", "98100", "98107", "98108", "98109", "98112", "98113", "98115", "98116", "98119", "98120", "98121", "98122", "98124", "98125", "98126", "98127", "98130", "98133", "98136", "98139", "98141", "98142", "98143", "98144", "98145", "98147", "98148", "98150", "98151", "98152", "98153", "98154", "98158", "98161", "98162", "98163", "98164", "98166", "98168", "98169", "98170", "98171", "98173", "98177", "98179", "98180", "98189", "98190", "98194", "98198", "98200", "98201", "98202", "98204", "98205", "98206", "98208", "98209", "98210", "98211", "98212", "98215", "98216", "98217", "98222", "98224", "98226", "98227", "98229", "98232", "98233", "98234", "98235", "98237", "98239", "98241", "98242", "98243", "98245", "98246", "98248", "98249", "98250", "98252", "98257", "98258", "98261", "98262", "98263", "98265", "98266", "98267", "98270", "98272", "98275", "98278", "98280", "98282", "98285", "98287", "98289", "98290", "98291", "98292", "98293", "98294", "98295", "98297", "98298", "98301", "98302", "98303", "98305", "98306", "98307", "98309", "98313", "98315", "98317", "98318", "98319", "98321", "98322", "98324", "98325", "98326", "98327", "98330", "98332", "98335", "98336", "98338", "98340", "98345", "98346", "98347", "98348", "98350", "98352", "98356", "98360", "98363", "98365", "98368", "98369", "98370", "98374", "98375", "98379", "98380", "98381", "98383", "98384", "98386", "98387", "98388", "98390", "98391", "98396", "98399", "98400", "98402", "98404", "98405", "98406", "98407", "98410", "98412", "98413", "98415", "98416", "98420", "98421", "98424", "98427", "98431", "98433", "98437", "98438", "98442", "98443", "98446", "98447", "98448", "98453", "98458", "98463", "98465", "98466", "98469", "98470", "98471", "98472", "98473", "98475", "98476", "98477", "98478", "98479", "98485", "98486", "98487", "98488", "98493", "98494", "98495", "98497", "98498", "98499", "98501", "98502", "98505", "98506", "98511", "98513", "98516", "98520", "98521", "98522", "98523", "98525", "98526", "98527", "98528", "98529", "98530", "98532", "98533", "98534", "98538", "98539", "98541", "98542", "98543", "98546", "98547", "98548", "98549", "98551", "98554", "98556", "98558", "98562", "98565", "98566", "98568", "98569", "98570", "98572", "98574", "98576", "98577", "98578", "98579", "98580", "98581", "98582", "98583", "98586", "98587", "98593", "98595", "98597", "98601", "98605", "98606", "98609", "98610", "98611", "98612", "98613", "98614", "98615", "98617", "98620", "98621", "98622", "98625", "98626", "98628", "98629", "98630", "98631", "98634", "98636", "98637", "98639", "98640", "98642", "98646", "98647", "98649", "98650", "98651", "98653", "98654", "98657", "98658", "98659", "98660", "98661", "98666", "98667", "98668", "98670", "98671", "98673", "98675", "98678", "98680", "98681", "98687", "98688", "98689", "98691", "98694", "98696", "98697", "98698", "98699", "98700", "98702", "98704", "98707", "98713", "98718", "98720", "98723", "98725", "98728", "98729", "98731", "98734", "98736", "98738", "98739", "98741", "98743", "98745", "98746", "98747", "98748", "98749", "98754", "98761", "98762", "98763", "98764", "98765", "98770", "98771", "98773", "98774", "98775", "98780", "98783", "98784", "98785", "98787", "98788", "98789", "98791", "98792", "98797", "98798", "98799", "98805", "98806", "98807", "98812", "98813", "98814", "98818", "98819", "98821", "98822", "98823", "98825", "98827", "98830", "98831", "98834", "98839", "98841", "98842", "98843", "98845", "98846", "98847", "98848", "98849", "98852", "98853", "98854", "98855", "98858", "98863", "98866", "98872", "98878", "98879", "98883", "98884", "98885", "98888", "98891", "98895", "98897", "98899", "98903", "98905", "98907", "98911", "98912", "98914", "98915", "98917", "98919", "98923", "98924", "98925", "98928", "98929", "98931", "98932", "98934", "98937", "98938", "98939", "98944", "98945", "98946", "98947", "98948", "98953", "98965", "98966", "98969", "98970", "98971", "98973", "98975", "98976", "98977", "98978", "98980", "98982", "98985", "98987", "98988", "98989", "98992", "98996", "99001", "99002", "99006", "99007", "99008", "99009", "99010", "99013", "99016", "99017", "99020", "99021", "99022", "99025", "99027", "99028", "99033", "99034", "99038", "99040", "99041", "99044", "99045", "99046", "99047", "99051", "99052", "99053", "99054", "99056", "99059", "99061", "99063", "99065", "99068", "99069", "99070", "99071", "99073", "99074", "99075", "99076", "99079", "99081", "99084", "99085", "99086", "99088", "99089", "99092", "99095", "99096", "99097", "99105", "99106", "99109", "99110", "99111", "99112", "99113", "99117", "99118", "99119", "99121", "99122", "99123", "99125", "99126", "99133", "99135", "99137", "99138", "99140", "99142", "99146", "99147", "99148", "99149", "99151", "99154", "99155", "99156", "99157", "99160", "99161", "99162", "99163", "99166", "99167", "99172", "99174", "99178", "99179", "99180", "99184", "99187", "99188", "99190", "99198", "99199", "99200", "99203", "99206", "99208", "99209", "99210", "99211", "99219", "99222", "99223", "99225", "99226", "99229", "99230", "99231", "99233", "99234", "99236", "99239", "99240", "99241", "99242", "99245", "99246", "99247", "99248", "99249", "99254", "99255", "99256", "99259", "99260", "99271", "99272", "99275", "99276", "99278", "99280", "99282", "99283", "99285", "99289", "99291", "99292", "99293", "99294", "99296", "99298", "99301", "99307", "99308", "99309", "99310", "99312", "99313", "99315", "99316", "99317", "99319", "99321", "99324", "99328", "99329", "99330", "99332", "99333", "99334", "99335", "99336", "99340", "99341", "99344", "99345", "99346", "99347", "99349", "99350", "99352", "99353", "99354", "99356", "99358", "99359", "99361", "99363", "99366", "99367", "99368", "99369", "99374", "99375", "99376", "99377", "99378", "99379", "99380", "99382", "99383", "99385", "99386", "99388", "99392", "99393", "99395", "99397", "99398", "99400", "99404", "99405", "99406", "99407", "99415", "99417", "99420", "99422", "99423", "99425", "99427", "99428", "99429", "99432", "99433", "99435", "99436", "99437", "99440", "99442", "99443", "99444", "99445", "99446", "99450", "99453", "99454", "99457", "99459", "99461", "99462", "99464", "99467", "99468", "99471", "99474", "99475", "99476", "99477", "99478", "99480", "99481", "99482", "99483", "99484", "99485", "99490", "99491", "99492", "99493", "99494", "99495", "99496", "99497", "99498", "99502", "99506", "99507", "99511", "99512", "99513", "99515", "99517", "99518", "99519", "99520", "99524", "99525", "99526", "99528", "99529", "99530", "99531", "99532", "99534", "99536", "99539", "99540", "99541", "99543", "99546", "99547", "99549", "99551", "99552", "99553", "99555", "99557", "99558", "99561", "99562", "99563", "99564", "99565", "99566", "99568", "99569", "99571", "99576", "99577", "99578", "99579", "99580", "99581", "99585", "99587", "99590", "99592", "99593", "99594", "99595", "99597", "99598", "99599", "99601", "99605", "99608", "99611", "99614", "99615", "99617", "99618", "99619", "99622", "99624", "99625", "99626", "99628", "99631", "99633", "99636", "99637", "99638", "99639", "99640", "99642", "99644", "99645", "99646", "99647", "99648", "99649", "99658", "99659", "99660", "99662", "99667", "99669", "99672", "99676", "99677", "99678", "99680", "99681", "99682", "99683", "99685", "99686", "99687", "99688", "99690", "99691", "99692", "99694", "99697", "99698", "99701", "99704", "99707", "99708", "99709", "99712", "99713", "99717", "99718", "99724", "99725", "99729", "99730", "99735", "99740", "99742", "99744", "99745", "99751", "99752", "99753", "99754", "99755", "99756", "99758", "99764", "99767", "99768", "99770", "99771", "99773", "99774", "99775", "99776", "99779", "99780", "99781", "99782", "99784", "99786", "99790", "99792", "99793", "99794", "99797", "99800", "99802", "99808", "99810", "99811", "99815", "99816", "99817", "99818", "99819", "99820", "99822", "99825", "99826", "99827", "99833", "99834", "99836", "99837", "99842", "99843", "99844", "99845", "99847", "99851", "99855", "99856", "99857", "99858", "99860", "99862", "99863", "99867", "99868", "99869", "99871", "99872", "99873", "99875", "99877", "99879", "99882", "99883", "99887", "99888", "99889", "99890", "99892", "99894", "99895", "99896", "99900", "99906", "99908", "99909", "99910", "99911", "99912", "99913", "99915", "99917", "99918", "99925", "99928", "99929", "99931", "99936", "99939", "99940", "99941", "99942", "99943", "99947", "99948", "99950", "99951", "99952", "99955", "99956", "99961", "99962", "99963", "99965", "99967", "99968", "99969", "99971", "99974", "99977", "99978", "99981", "99982", "99983", "99985", "99987", "99995", "99996", "99999", "100000", "100003", "100005", "100007", "100012", "100013", "100015", "100016", "100018", "100019", "100024", "100025", "100026", "100027", "100030", "100031", "100036", "100038", "100039", "100040", "100041", "100042", "100043", "100044", "100046", "100047", "100048", "100051", "100053", "100055", "100056", "100057", "100058", "100062", "100063", "100068", "100070", "100072", "100074", "100077", "100078", "100083", "100085", "100086", "100088", "100089", "100092", "100093", "100094", "100096", "100099", "100100", "100101", "100104", "100105", "100107", "100108", "100110", "100112", "100113", "100115", "100116", "100117", "100119", "100120", "100125", "100127", "100131", "100136", "100138", "100139", "100140", "100141", "100146", "100147", "100148", "100149", "100153", "100156", "100157", "100158", "100164", "100166", "100170", "100173", "100174", "100175", "100179", "100180", "100181", "100182", "100183", "100184", "100185", "100186", "100187", "100188", "100189", "100190", "100194", "100195", "100196", "100197", "100199", "100200", "100202", "100203", "100208", "100209", "100210", "100214", "100215", "100216", "100218", "100219", "100221", "100222", "100223", "100229", "100230", "100231", "100233", "100235", "100236", "100237", "100238", "100239", "100245", "100246", "100250", "100252", "100253", "100254", "100255", "100256", "100258", "100260", "100267", "100269", "100270", "100271", "100274", "100275", "100276", "100277", "100278", "100282", "100283", "100287", "100288", "100289", "100291", "100297", "100299", "100300", "100304", "100307", "100308", "100309", "100311", "100312", "100313", "100314", "100316", "100318", "100319", "100320", "100321", "100322", "100323", "100325", "100326", "100328", "100329", "100332", "100333", "100336", "100337", "100339", "100344", "100346", "100347", "100348", "100353", "100356", "100357", "100360", "100361", "100362", "100363", "100365", "100368", "100370", "100373", "100374", "100376", "100378", "100380", "100381", "100382", "100383", "100385", "100386", "100387", "100388", "100389", "100398", "100399", "100400", "100401", "100405", "100408", "100409", "100413", "100415", "100416", "100418", "100419", "100420", "100421", "100424", "100425", "100430", "100431", "100432", "100434", "100435", "100437", "100438", "100442", "100443", "100444", "100445", "100446", "100447", "100450", "100455", "100456", "100458", "100460", "100463", "100464", "100465", "100466", "100469", "100472", "100474", "100476", "100479", "100482", "100485", "100487", "100489", "100491", "100494", "100501", "100504", "100505", "100507", "100509", "100511", "100512", "100515", "100517", "100519", "100522", "100524", "100526", "100527", "100529", "100530", "100533", "100537", "100538", "100543", "100544", "100549", "100550", "100555", "100558", "100559", "100560", "100561", "100562", "100563", "100564", "100565", "100569", "100571", "100572", "100573", "100574", "100575", "100576", "100579", "100586", "100590", "100592", "100593", "100594", "100598", "100599", "100601", "100604", "100608", "100611", "100613", "100614", "100615", "100617", "100619", "100621", "100622", "100623", "100626", "100629", "100630", "100632", "100634", "100635", "100640", "100644", "100646", "100647", "100648", "100650", "100651", "100652", "100653", "100660", "100663", "100664", "100665", "100666", "100667", "100668", "100669", "100671", "100672", "100674", "100676", "100678", "100684", "100685", "100688", "100690", "100691", "100692", "100694", "100699", "100701", "100704", "100705", "100706", "100708", "100709", "100711", "100712", "100718", "100719", "100722", "100723", "100727", "100728", "100731", "100733", "100734", "100735", "100738", "100739", "100740", "100741", "100745", "100746", "100748", "100749", "100750", "100752", "100754", "100757", "100759", "100761", "100762", "100763", "100764", "100766", "100768", "100770", "100772", "100773", "100778", "100779", "100783", "100784", "100787", "100791", "100792", "100793", "100795", "100796", "100797", "100800", "100801", "100803", "100804", "100806", "100807", "100809", "100812", "100816", "100819", "100820", "100821", "100822", "100824", "100825", "100828", "100829", "100831", "100833", "100834", "100837", "100838", "100839", "100841", "100842", "100843", "100846", "100847", "100848", "100851", "100852", "100853", "100855", "100857", "100859", "100860", "100862", "100863", "100864", "100865", "100866", "100867", "100868", "100869", "100871", "100873", "100875", "100878", "100881", "100884", "100885", "100886", "100888", "100889", "100890", "100893", "100894", "100899", "100902", "100903", "100907", "100908", "100910", "100913", "100914", "100916", "100918", "100922", "100924", "100927", "100930", "100931", "100932", "100934", "100935", "100936", "100941", "100942", "100943", "100944", "100945", "100946", "100949", "100950", "100953", "100954", "100956", "100960", "100965", "100966", "100967", "100968", "100970", "100971", "100972", "100973", "100978", "100979", "100980", "100983", "100985", "100987", "100989", "100991", "100992", "100995", "100996", "100999", "101000", "101002", "101004", "101005", "101007", "101008", "101009", "101010", "101012", "101016", "101017", "101018", "101020", "101022", "101023", "101024", "101025", "101026", "101027", "101028", "101029", "101030", "101031", "101032", "101033", "101036", "101039", "101041", "101042", "101043", "101044", "101045", "101046", "101047", "101048", "101049", "101050", "101051", "101053", "101054", "101055", "101057", "101058", "101059", "101062", "101063", "101069", "101073", "101074", "101075", "101077", "101078", "101080", "101081", "101086", "101087", "101088", "101090", "101095", "101097", "101098", "101099", "101100", "101103", "101105", "101109", "101110", "101111", "101112", "101118", "101119", "101121", "101122", "101127", "101128", "101130", "101132", "101133", "101135", "101136", "101137", "101139", "101140", "101148", "101149", "101151", "101152", "101153", "101155", "101157", "101159", "101161", "101162", "101164", "101165", "101168", "101169", "101171", "101172", "101174", "101175", "101176", "101177", "101178", "101179", "101180", "101184", "101187", "101188", "101189", "101190", "101193", "101195", "101196", "101198", "101199", "101200", "101202", "101205", "101206", "101207", "101212", "101213", "101214", "101216", "101218", "101220", "101221", "101225", "101226", "101228", "101230", "101231", "101233", "101235", "101236", "101238", "101240", "101241", "101243", "101244", "101245", "101246", "101247", "101250", "101253", "101257", "101261", "101262", "101263", "101265", "101266", "101269", "101270", "101271", "101273", "101274", "101276", "101278", "101281", "101282", "101283", "101284", "101285", "101287", "101288", "101289", "101290", "101291", "101295", "101296", "101297", "101299", "101300", "101301", "101302", "101305", "101306", "101308", "101309", "101311", "101313", "101314", "101316", "101318", "101319", "101321", "101323", "101324", "101328", "101331", "101332", "101335", "101336", "101337", "101338", "101339", "101341", "101342", "101343", "101345", "101346", "101347", "101348", "101351", "101352", "101357", "101358", "101360", "101363", "101365", "101366", "101367", "101368", "101369", "101372", "101373", "101374", "101376", "101382", "101385", "101386", "101389", "101390", "101391", "101392", "101396", "101398", "101399", "101400", "101401", "101402", "101403", "101405", "101406", "101408", "101410", "101411", "101413", "101416", "101418", "101421", "101423", "101426", "101428", "101429", "101433", "101436", "101438", "101439", "101440", "101445", "101450", "101451", "101452", "101456", "101458", "101459", "101466", "101470", "101473", "101474", "101475", "101477", "101478", "101479", "101481", "101482", "101484", "101487", "101489", "101490", "101491", "101492", "101493", "101496", "101498", "101499", "101500", "101501", "101503", "101505", "101506", "101509", "101512", "101514", "101515", "101522", "101523", "101524", "101528", "101529", "101531", "101532", "101534", "101535", "101539", "101540", "101541", "101542", "101543", "101544", "101545", "101547", "101549", "101550", "101553", "101556", "101558", "101560", "101561", "101562", "101563", "101568", "101570", "101571", "101572", "101574", "101575", "101576", "101579", "101584", "101588", "101589", "101591", "101592", "101593", "101599", "101600", "101605", "101606", "101607", "101609", "101611", "101613", "101615", "101617", "101620", "101621", "101623", "101627", "101628", "101629", "101632", "101633", "101634", "101635", "101636", "101638", "101641", "101645", "101646", "101648", "101650", "101652", "101653", "101654", "101655", "101656", "101658", "101659", "101662", "101663", "101665", "101669", "101672", "101673", "101674", "101675", "101679", "101680", "101681", "101682", "101683", "101686", "101690", "101693", "101696", "101697", "101700", "101702", "101703", "101704", "101706", "101708", "101710", "101713", "101715", "101716", "101717", "101720", "101725", "101726", "101728", "101731", "101734", "101736", "101737", "101738", "101739", "101741", "101742", "101745", "101747", "101749", "101751", "101752", "101754", "101757", "101759", "101760", "101761", "101763", "101771", "101773", "101775", "101776", "101779", "101782", "101783", "101785", "101786", "101788", "101790", "101793", "101795", "101796", "101797", "101798", "101799", "101800", "101802", "101805", "101809", "101811", "101813", "101814", "101816", "101817", "101820", "101821", "101823", "101825", "101826", "101829", "101830", "101833", "101834", "101835", "101837", "101838", "101840", "101845", "101849", "101856", "101865", "101867", "101869", "101871", "101872", "101873", "101880", "101881", "101882", "101883", "101884", "101885", "101886", "101888", "101890", "101891", "101895", "101896", "101899", "101900", "101901", "101903", "101905", "101908", "101909", "101910", "101912", "101914", "101915", "101916", "101917", "101920", "101923", "101929", "101933", "101937", "101938", "101941", "101943", "101948", "101950", "101951", "101952", "101954", "101955", "101957", "101959", "101962", "101963", "101964", "101968", "101969", "101970", "101976", "101977", "101979", "101981", "101982", "101983", "101986", "101987", "101988", "101990", "101991", "101992", "101994", "101995", "101996", "101997", "102000", "102001", "102002", "102003", "102005", "102006", "102013", "102015", "102016", "102021", "102023", "102024", "102025", "102026", "102031", "102032", "102039", "102041", "102042", "102044", "102046", "102047", "102048", "102051", "102052", "102054", "102055", "102057", "102058", "102059", "102062", "102065", "102066", "102067", "102070", "102072", "102074", "102076", "102079", "102081", "102083", "102086", "102087", "102090", "102091", "102093", "102094", "102098", "102099", "102100", "102106", "102108", "102109", "102110", "102111", "102114", "102116", "102119", "102120", "102121", "102125", "102126", "102128", "102129", "102130", "102133", "102135", "102136", "102139", "102140", "102141", "102143", "102146", "102149", "102151", "102152", "102153", "102154", "102155", "102156", "102157", "102160", "102162", "102164", "102167", "102168", "102169", "102170", "102172", "102174", "102175", "102176", "102181", "102183", "102184", "102186", "102187", "102188", "102191", "102193", "102194", "102195", "102198", "102201", "102203", "102206", "102207", "102208", "102209", "102211", "102212", "102213", "102214", "102215", "102217", "102222", "102223", "102224", "102225", "102227", "102228", "102229", "102231", "102232", "102235", "102238", "102240", "102241", "102247", "102248", "102250", "102254", "102256", "102257", "102258", "102259", "102260", "102262", "102263", "102264", "102265", "102267", "102268", "102270", "102273", "102274", "102275", "102277", "102278", "102279", "102280", "102281", "102282", "102283", "102284", "102286", "102290", "102291", "102292", "102294", "102295", "102298", "102299", "102301", "102302", "102305", "102306", "102307", "102309", "102311", "102312", "102314", "102315", "102317", "102318", "102320", "102323", "102325", "102326", "102328", "102331", "102332", "102333", "102334", "102335", "102336", "102337", "102338", "102339", "102341", "102345", "102347", "102348", "102349", "102350", "102351", "102352", "102353", "102354", "102356", "102359", "102360", "102361", "102362", "102363", "102367", "102368", "102369", "102371", "102372", "102373", "102376", "102382", "102384", "102386", "102388", "102389", "102395", "102399", "102401", "102405", "102410", "102412", "102413", "102414", "102416", "102417", "102419", "102420", "102421", "102425", "102429", "102430", "102435", "102437", "102439", "102440", "102442", "102443", "102444", "102447", "102448", "102449", "102452", "102455", "102456", "102458", "102461", "102464", "102467", "102468", "102469", "102472", "102473", "102474", "102478", "102479", "102480", "102482", "102483", "102485", "102486", "102487", "102488", "102489", "102490", "102491", "102494", "102495", "102497", "102501", "102505", "102506", "102507", "102508", "102510", "102511", "102514", "102517", "102519", "102522", "102527", "102529", "102532", "102534", "102535", "102536", "102538", "102544", "102546", "102547", "102549", "102550", "102555", "102556", "102557", "102565", "102567", "102570", "102573", "102575", "102578", "102579", "102580", "102581", "102582", "102587", "102589", "102590", "102592", "102593", "102594", "102598", "102599", "102604", "102606", "102607", "102608", "102615", "102616", "102617", "102618", "102620", "102621", "102624", "102626", "102630", "102634", "102637", "102639", "102640", "102649", "102651", "102652", "102653", "102656", "102658", "102659", "102664", "102665", "102666", "102670", "102673", "102675", "102677", "102683", "102684", "102685", "102687", "102688", "102692", "102693", "102695", "102700", "102701", "102702", "102704", "102705", "102706", "102708", "102709", "102710", "102713", "102714", "102718", "102719", "102720", "102722", "102725", "102726", "102727", "102728", "102729", "102732", "102734", "102738", "102740", "102742", "102744", "102748", "102752", "102755", "102756", "102757", "102758", "102759", "102760", "102761", "102762", "102768", "102769", "102771", "102777", "102778", "102779", "102780", "102783", "102785", "102786", "102787", "102788", "102789", "102791", "102792", "102794", "102795", "102797", "102798", "102799", "102804", "102805", "102806", "102807", "102809", "102813", "102815", "102817", "102819", "102824", "102825", "102826", "102827", "102830", "102831", "102832", "102834", "102835", "102836", "102838", "102840", "102845", "102846", "102847", "102852", "102853", "102855", "102860", "102861", "102862", "102864", "102865", "102866", "102868", "102869", "102870", "102871", "102873", "102874", "102875", "102879", "102880", "102885", "102886", "102890", "102892", "102893", "102894", "102896", "102897", "102899", "102901", "102902", "102903", "102905", "102908", "102911", "102913", "102915", "102918", "102919", "102920", "102921", "102925", "102929", "102931", "102932", "102938", "102941", "102942", "102943", "102945", "102948", "102950", "102951", "102953", "102955", "102956", "102957", "102958", "102960", "102962", "102963", "102967", "102969", "102971", "102972", "102973", "102974", "102976", "102977", "102978", "102979", "102984", "102985", "102986", "102990", "102991", "102998", "103000", "103001", "103005", "103006", "103008", "103011", "103012", "103013", "103018", "103019", "103020", "103022", "103023", "103025", "103029", "103031", "103034", "103035", "103036", "103039", "103040", "103041", "103042", "103044", "103045", "103046", "103047", "103049", "103051", "103053", "103055", "103059", "103061", "103064", "103065", "103066", "103068", "103073", "103074", "103075", "103076", "103078", "103084", "103088", "103089", "103092", "103094", "103098", "103099", "103104", "103109", "103114", "103118", "103124", "103125", "103126", "103128", "103131", "103132", "103137", "103139", "103140", "103141", "103142", "103143", "103144", "103146", "103148", "103149", "103153", "103154", "103155", "103157", "103158", "103159", "103161", "103162", "103163", "103169", "103170", "103171", "103173", "103174", "103179", "103180", "103185", "103187", "103188", "103189", "103191", "103193", "103195", "103202", "103204", "103205", "103207", "103208", "103209", "103210", "103214", "103216", "103217", "103218", "103219", "103224", "103227", "103228", "103229", "103230", "103231", "103235", "103236", "103240", "103241", "103242", "103245", "103246", "103247", "103250", "103253", "103255", "103261", "103262", "103263", "103264", "103266", "103268", "103269", "103270", "103271", "103275", "103277", "103280", "103287", "103289", "103291", "103292", "103295", "103297", "103298", "103300", "103302", "103304", "103305", "103309", "103311", "103315", "103316", "103318", "103320", "103321", "103322", "103323", "103326", "103327", "103328", "103329", "103330", "103332", "103335", "103337", "103339", "103340", "103341", "103342", "103343", "103345", "103347", "103351", "103354", "103355", "103359", "103360", "103361", "103362", "103364", "103366", "103367", "103368", "103369", "103372", "103373", "103383", "103384", "103385", "103388", "103391", "103392", "103396", "103397", "103399", "103400", "103403", "103406", "103407", "103412", "103413", "103414", "103415", "103416", "103418", "103419", "103420", "103421", "103422", "103423", "103428", "103429", "103430", "103431", "103434", "103435", "103436", "103437", "103440", "103443", "103444", "103445", "103446", "103450", "103455", "103457", "103458", "103460", "103462", "103464", "103466", "103467", "103468", "103471", "103474", "103475", "103478", "103479", "103484", "103486", "103489", "103490", "103493", "103495", "103503", "103508", "103511", "103512", "103516", "103520", "103524", "103525", "103527", "103528", "103529", "103530", "103531", "103532", "103535", "103536", "103537", "103538", "103540", "103543", "103544", "103545", "103548", "103550", "103552", "103553", "103555", "103557", "103559", "103561", "103562", "103563", "103566", "103567", "103568", "103570", "103572", "103573", "103576", "103577", "103578", "103579", "103580", "103584", "103586", "103587", "103588", "103590", "103591", "103592", "103596", "103597", "103598", "103599", "103600", "103602", "103603", "103606", "103607", "103608", "103611", "103615", "103619", "103621", "103622", "103623", "103624", "103625", "103627", "103629", "103631", "103633", "103636", "103639", "103642", "103645", "103648", "103650", "103651", "103655", "103656", "103657", "103658", "103659", "103660", "103661", "103663", "103665", "103669", "103670", "103671", "103676", "103679", "103680", "103682", "103683", "103685", "103687", "103690", "103691", "103693", "103696", "103697", "103700", "103702", "103703", "103704", "103706", "103707", "103709", "103714", "103715", "103717", "103718", "103719", "103722", "103723", "103725", "103727", "103729", "103730", "103732", "103733", "103736", "103738", "103739", "103740", "103742", "103745", "103746", "103749", "103750", "103752", "103753", "103755", "103760", "103761", "103765", "103769", "103770", "103771", "103773", "103774", "103780", "103781", "103783", "103787", "103788", "103789", "103790", "103792", "103793", "103797", "103798", "103800", "103802", "103803", "103805", "103806", "103809", "103811", "103812", "103815", "103817", "103819", "103823", "103824", "103825", "103828", "103829", "103830", "103831", "103832", "103833", "103837", "103841", "103842", "103847", "103852", "103853", "103860", "103861", "103862", "103865", "103867", "103868", "103870", "103874", "103876", "103877", "103879", "103880", "103881", "103882", "103884", "103886", "103890", "103893", "103894", "103897", "103901", "103902", "103903", "103904", "103905", "103906", "103907", "103908", "103910", "103913", "103915", "103918", "103919", "103920", "103921", "103924", "103925", "103927", "103928", "103929", "103930", "103931", "103932", "103933", "103934", "103936", "103938", "103939", "103941", "103946", "103949", "103950", "103952", "103953", "103955", "103956", "103957", "103958", "103962", "103963", "103964", "103965", "103968", "103969", "103971", "103976", "103977", "103979", "103980", "103981", "103983", "103988", "103990", "103991", "103993", "103994", "103998", "104000", "104001", "104004", "104014", "104017", "104018", "104020", "104022", "104023", "104026", "104028", "104029", "104032", "104034", "104037", "104038", "104039", "104040", "104042", "104043", "104044", "104045", "104046", "104048", "104051", "104053", "104055", "104057", "104059", "104060", "104066", "104067", "104071", "104073", "104075", "104076", "104077", "104078", "104081", "104083", "104084", "104085", "104087", "104088", "104093", "104096", "104098", "104099", "104100", "104101", "104102", "104103", "104104", "104108", "104109", "104110", "104111", "104116", "104121", "104124", "104125", "104126", "104128", "104136", "104137", "104138", "104139", "104140", "104143", "104144", "104145", "104147", "104150", "104151", "104153", "104154", "104161", "104162", "104166", "104170", "104172", "104178", "104179", "104180", "104182", "104183", "104185", "104186", "104187", "104189", "104190", "104191", "104192", "104193", "104195", "104196", "104198", "104200", "104202", "104203", "104205", "104207", "104209", "104211", "104212", "104213", "104217", "104218", "104220", "104221", "104222", "104223", "104228", "104230", "104231", "104232", "104234", "104235", "104240", "104241", "104242", "104244", "104245", "104246", "104247", "104248", "104249", "104250", "104253", "104256", "104257", "104259", "104260", "104261", "104262", "104267", "104270", "104271", "104272", "104279", "104280", "104281", "104284", "104285", "104288", "104289", "104291", "104293", "104295", "104296", "104297", "104299", "104303", "104304", "104305", "104308", "104309", "104312", "104313", "104314", "104316", "104319", "104322", "104324", "104326", "104327", "104329", "104330", "104331", "104332", "104335", "104339", "104342", "104343", "104344", "104346", "104351", "104353", "104355", "104356", "104357", "104360", "104361", "104362", "104364", "104365", "104368", "104369", "104370", "104371", "104373", "104378", "104379", "104380", "104381", "104382", "104384", "104385", "104386", "104388", "104391", "104392", "104394", "104395", "104396", "104397", "104399", "104401", "104403", "104404", "104405", "104406", "104409", "104410", "104413", "104414", "104415", "104416", "104419", "104433", "104434", "104437", "104438", "104439", "104441", "104442", "104444", "104445", "104448", "104449", "104450", "104451", "104452", "104454", "104459", "104462", "104464", "104466", "104468", "104470", "104475", "104476", "104478", "104480", "104482", "104483", "104485", "104486", "104487", "104488", "104490", "104492", "104493", "104495", "104496", "104498", "104501", "104504", "104505", "104506", "104507", "104509", "104510", "104512", "104513", "104517", "104518", "104520", "104522", "104523", "104526", "104528", "104529", "104531", "104532", "104534", "104535", "104536", "104537", "104538", "104539", "104540", "104541", "104542", "104543", "104546", "104555", "104556", "104557", "104559", "104561", "104562", "104563", "104564", "104565", "104566", "104569", "104572", "104574", "104582", "104584", "104589", "104591", "104596", "104597", "104599", "104601", "104604", "104605", "104610", "104612", "104613", "104614", "104615", "104616", "104618", "104621", "104623", "104626", "104628", "104634", "104636", "104637", "104638", "104640", "104641", "104642", "104643", "104644", "104647", "104649", "104650", "104652", "104653", "104656", "104657", "104659", "104661", "104669", "104670", "104671", "104677", "104679", "104681", "104682", "104684", "104686", "104688", "104689", "104690", "104691", "104692", "104693", "104694", "104695", "104697", "104700", "104701", "104703", "104704", "104705", "104707", "104709", "104710", "104711", "104712", "104715", "104718", "104719", "104720", "104721", "104727", "104731", "104734", "104736", "104740", "104743", "104745", "104750", "104751", "104752", "104753", "104754", "104756", "104757", "104758", "104763", "104765", "104767", "104768", "104769", "104772", "104775", "104778", "104779", "104781", "104787", "104788", "104790", "104791", "104793", "104794", "104796", "104797", "104798", "104799", "104801", "104802", "104804", "104805", "104806", "104807", "104808", "104813", "104815", "104816", "104817", "104819", "104820", "104822", "104823", "104824", "104825", "104827", "104832", "104834", "104835", "104841", "104843", "104844", "104845", "104848", "104849", "104850", "104851", "104853", "104856", "104859", "104860", "104865", "104866", "104867", "104868", "104869", "104870", "104872", "104875", "104877", "104878", "104879", "104880", "104881", "104882", "104883", "104886", "104888", "104891", "104893", "104894", "104895", "104896", "104897", "104898", "104902", "104905", "104906", "104908", "104912", "104913", "104914", "104920", "104922", "104923", "104925", "104940", "104943", "104945", "104946", "104947", "104948", "104949", "104951", "104952", "104954", "104955", "104956", "104960", "104962", "104967", "104973", "104974", "104976", "104977", "104979", "104981", "104984", "104986", "104987", "104992", "104995", "104996", "104997", "104999", "105004", "105005", "105007", "105012", "105013", "105014", "105016", "105021", "105022", "105023", "105024", "105025", "105026", "105027", "105028", "105029", "105030", "105035", "105037", "105040", "105042", "105043", "105044", "105047", "105049", "105051", "105054", "105055", "105056", "105057", "105058", "105060", "105062", "105065", "105067", "105071", "105072", "105074", "105078", "105079", "105080", "105082", "105086", "105092", "105093", "105094", "105097", "105098", "105099", "105101", "105102", "105105", "105107", "105109", "105110", "105111", "105115", "105116", "105118", "105124", "105125", "105126", "105127", "105132", "105135", "105138", "105141", "105143", "105147", "105150", "105152", "105153", "105154", "105156", "105157", "105158", "105160", "105162", "105164", "105165", "105167", "105168", "105169", "105171", "105175", "105176", "105177", "105182", "105183", "105184", "105185", "105186", "105187", "105191", "105195", "105196", "105199", "105200", "105201", "105202", "105205", "105206", "105207", "105208", "105209", "105210", "105212", "105214", "105216", "105218", "105219", "105221", "105223", "105228", "105229", "105232", "105233", "105234", "105235", "105240", "105246", "105247", "105248", "105251", "105252", "105256", "105259", "105261", "105262", "105263", "105268", "105269", "105271", "105272", "105273", "105274", "105276", "105278", "105279", "105280", "105281", "105282", "105284", "105286", "105288", "105290", "105293", "105294", "105297", "105298", "105299", "105300", "105301", "105303", "105304", "105306", "105308", "105310", "105311", "105312", "105314", "105315", "105318", "105319", "105321", "105322", "105323", "105325", "105327", "105328", "105329", "105333", "105334", "105335", "105337", "105338", "105340", "105341", "105342", "105343", "105347", "105348", "105351", "105352", "105354", "105355", "105356", "105361", "105365", "105373", "105376", "105378", "105379", "105380", "105381", "105382", "105383", "105385", "105387", "105389", "105390", "105391", "105396", "105397", "105400", "105402", "105404", "105405", "105406", "105408", "105410", "105411", "105412", "105415", "105416", "105417", "105418", "105419", "105420", "105421", "105422", "105425", "105426", "105429", "105431", "105432", "105433", "105437", "105438", "105439", "105440", "105443", "105445", "105447", "105451", "105455", "105457", "105459", "105461", "105466", "105471", "105472", "105473", "105474", "105476", "105477", "105479", "105481", "105482", "105483", "105486", "105487", "105489", "105493", "105494", "105495", "105496", "105497", "105499", "105500", "105501", "105502", "105503", "105504", "105505", "105506", "105508", "105509", "105511", "105514", "105516", "105517", "105520", "105525", "105526", "105528", "105529", "105530", "105532", "105535", "105538", "105540", "105542", "105544", "105546", "105547", "105549", "105550", "105552", "105553", "105554", "105555", "105558", "105560", "105564", "105570", "105572", "105573", "105574", "105577", "105578", "105580", "105581", "105582", "105584", "105586", "105587", "105589", "105594", "105595", "105596", "105597", "105599", "105600", "105602", "105604", "105608", "105610", "105612", "105614", "105615", "105619", "105620", "105621", "105622", "105623", "105624", "105626", "105628", "105629", "105630", "105632", "105633", "105640", "105641", "105642", "105647", "105648", "105650", "105655", "105656", "105657", "105658", "105660", "105662", "105664", "105665", "105667", "105669", "105670", "105671", "105672", "105675", "105676", "105678", "105680", "105682", "105683", "105684", "105688", "105689", "105690", "105693", "105697", "105701", "105702", "105703", "105705", "105706", "105707", "105709", "105713", "105714", "105715", "105717", "105718", "105720", "105722", "105723", "105727", "105729", "105737", "105738", "105739", "105741", "105743", "105749", "105750", "105752", "105755", "105756", "105758", "105760", "105765", "105767", "105773", "105774", "105775", "105776", "105778", "105780", "105783", "105785", "105786", "105787", "105789", "105793", "105794", "105796", "105798", "105799", "105800", "105801", "105802", "105804", "105805", "105807", "105808", "105813", "105814", "105815", "105822", "105824", "105825", "105826", "105827", "105832", "105834", "105835", "105836", "105838", "105845", "105846", "105849", "105850", "105851", "105854", "105855", "105856", "105860", "105861", "105863", "105864", "105869", "105871", "105872", "105873", "105874", "105876", "105877", "105878", "105880", "105883", "105884", "105886", "105888", "105892", "105895", "105897", "105898", "105900", "105904", "105907", "105911", "105912", "105913", "105914", "105916", "105918", "105920", "105921", "105922", "105925", "105927", "105929", "105930", "105932", "105933", "105934", "105935", "105936", "105937", "105938", "105942", "105947", "105948", "105950", "105952", "105953", "105954", "105955", "105956", "105961", "105967", "105968", "105971", "105973", "105976", "105977", "105984", "105985", "105988", "105989", "105990", "105991", "105993", "105994", "105995", "105997", "105998", "105999", "106000", "106004", "106012", "106014", "106015", "106019", "106024", "106026", "106028", "106029", "106031", "106034", "106035", "106036", "106037", "106038", "106040", "106042", "106047", "106049", "106050", "106053", "106059", "106060", "106061", "106068", "106070", "106071", "106074", "106079", "106081", "106082", "106084", "106088", "106091", "106093", "106094", "106098", "106100", "106104", "106105", "106106", "106108", "106109", "106110", "106111", "106112", "106115", "106118", "106120", "106121", "106126", "106127", "106128", "106131", "106132", "106133", "106136", "106140", "106141", "106143", "106145", "106147", "106148", "106149", "106150", "106151", "106153", "106156", "106158", "106159", "106160", "106162", "106169", "106172", "106174", "106175", "106177", "106180", "106183", "106185", "106186", "106188", "106189", "106190", "106191", "106195", "106197", "106198", "106199", "106200", "106205", "106206", "106207", "106211", "106214", "106215", "106216", "106218", "106219", "106220", "106221", "106222", "106224", "106226", "106228", "106229", "106231", "106237", "106238", "106239", "106240", "106243", "106244", "106246", "106248", "106251", "106252", "106253", "106259", "106261", "106263", "106266", "106268", "106269", "106271", "106273", "106275", "106276", "106278", "106281", "106282", "106287", "106289", "106295", "106297", "106299", "106300", "106301", "106304", "106305", "106306", "106309", "106310", "106311", "106312", "106314", "106316", "106318", "106320", "106322", "106326", "106327", "106328", "106329", "106330", "106331", "106332", "106338", "106341", "106342", "106343", "106345", "106346", "106347", "106349", "106350", "106352", "106355", "106357", "106358", "106361", "106363", "106366", "106369", "106371", "106375", "106376", "106379", "106380", "106382", "106383", "106385", "106386", "106387", "106388", "106389", "106394", "106395", "106396", "106399", "106401", "106402", "106405", "106407", "106409", "106410", "106412", "106415", "106416", "106418", "106419", "106421", "106425", "106426", "106428", "106429", "106430", "106433", "106434", "106435", "106438", "106442", "106443", "106446", "106448", "106450", "106452", "106454", "106456", "106457", "106458", "106459", "106460", "106463", "106466", "106467", "106469", "106470", "106471", "106472", "106473", "106476", "106477", "106478", "106479", "106480", "106481", "106482", "106484", "106485", "106486", "106487", "106489", "106491", "106492", "106495", "106497", "106498", "106499", "106500", "106505", "106507", "106512", "106516", "106517", "106518", "106519", "106520", "106522", "106525", "106528", "106529", "106530", "106531", "106533", "106536", "106538", "106539", "106540", "106546", "106549", "106550", "106551", "106553", "106554", "106556", "106557", "106558", "106559", "106560", "106561", "106565", "106567", "106568", "106570", "106571", "106572", "106574", "106576", "106577", "106579", "106582", "106583", "106584", "106585", "106589", "106590", "106591", "106593", "106595", "106599", "106600", "106601", "106603", "106608", "106609", "106620", "106623", "106625", "106627", "106629", "106630", "106637", "106638", "106639", "106642", "106643", "106644", "106646", "106655", "106658", "106660", "106661", "106662", "106664", "106665", "106666", "106667", "106668", "106670", "106672", "106673", "106676", "106677", "106678", "106679", "106680", "106681", "106684", "106689", "106691", "106692", "106697", "106698", "106699", "106700", "106701", "106702", "106703", "106707", "106709", "106712", "106715", "106718", "106719", "106720", "106721", "106723", "106724", "106728", "106730", "106733", "106735", "106737", "106738", "106739", "106742", "106743", "106744", "106745", "106746", "106747", "106748", "106750", "106751", "106752", "106754", "106759", "106767", "106770", "106771", "106772", "106774", "106775", "106778", "106780", "106781", "106786", "106789", "106790", "106791", "106792", "106794", "106796", "106798", "106800", "106802", "106805", "106809", "106811", "106816", "106817", "106818", "106821", "106823", "106827", "106830", "106833", "106835", "106837", "106839", "106841", "106842", "106843", "106845", "106847", "106849", "106851", "106852", "106853", "106855", "106856", "106858", "106861", "106862", "106863", "106864", "106866", "106867", "106869", "106870", "106871", "106873", "106875", "106876", "106878", "106883", "106884", "106885", "106886", "106894", "106895", "106897", "106898", "106899", "106900", "106902", "106904", "106906", "106908", "106909", "106910", "106913", "106918", "106919", "106923", "106924", "106926", "106928", "106930", "106931", "106932", "106933", "106935", "106936", "106939", "106940", "106941", "106942", "106943", "106945", "106947", "106949", "106950", "106952", "106958", "106961", "106962", "106964", "106966", "106968", "106970", "106973", "106974", "106975", "106977", "106980", "106981", "106983", "106985", "106988", "106989", "106992", "106994", "106998", "106999", "107001", "107003", "107004", "107005", "107006", "107007", "107008", "107012", "107016", "107017", "107018", "107020", "107022", "107026", "107028", "107030", "107032", "107035", "107036", "107038", "107039", "107040", "107041", "107047", "107048", "107049", "107053", "107066", "107067", "107068", "107069", "107071", "107075", "107077", "107078", "107080", "107085", "107086", "107088", "107089", "107094", "107095", "107099", "107101", "107104", "107105", "107108", "107113", "107114", "107115", "107118", "107121", "107122", "107126", "107127", "107128", "107129", "107130", "107132", "107133", "107136", "107139", "107140", "107141", "107144", "107146", "107147", "107148", "107150", "107154", "107155", "107156", "107157", "107158", "107159", "107161", "107165", "107168", "107169", "107171", "107178", "107180", "107183", "107185", "107186", "107193", "107195", "107197", "107199", "107202", "107203", "107204", "107205", "107207", "107208", "107211", "107214", "107215", "107216", "107219", "107222", "107223", "107224", "107225", "107226", "107227", "107228", "107231", "107232", "107233", "107234", "107236", "107240", "107241", "107242", "107245", "107248", "107249", "107251", "107252", "107253", "107255", "107259", "107260", "107263", "107267", "107268", "107269", "107272", "107273", "107274", "107276", "107278", "107281", "107283", "107285", "107286", "107287", "107289", "107291", "107293", "107297", "107298", "107300", "107302", "107303", "107304", "107307", "107308", "107309", "107310", "107311", "107312", "107313", "107315", "107316", "107317", "107318", "107319", "107320", "107321", "107323", "107326", "107329", "107330", "107331", "107332", "107338", "107342", "107343", "107344", "107345", "107346", "107349", "107353", "107354", "107358", "107360", "107361", "107362", "107363", "107365", "107366", "107372", "107373", "107375", "107376", "107377", "107380", "107383", "107385", "107386", "107387", "107388", "107390", "107395", "107396", "107399", "107401", "107404", "107405", "107409", "107412", "107416", "107419", "107420", "107421", "107422", "107423", "107424", "107425", "107428", "107431", "107433", "107435", "107436", "107437", "107438", "107440", "107441", "107442", "107444", "107445", "107446", "107447", "107448", "107451", "107452", "107453", "107455", "107456", "107457", "107458", "107459", "107460", "107461", "107463", "107464", "107467", "107468", "107471", "107472", "107473", "107475", "107476", "107477", "107478", "107479", "107480", "107481", "107482", "107483", "107484", "107486", "107488", "107489", "107490", "107491", "107493", "107495", "107497", "107498", "107500", "107501", "107502", "107503", "107504", "107505", "107507", "107508", "107510", "107511", "107512", "107513", "107516", "107518", "107520", "107524", "107525", "107531", "107533", "107536", "107538", "107539", "107540", "107541", "107542", "107544", "107546", "107548", "107551", "107552", "107553", "107558", "107559", "107561", "107562", "107563", "107564", "107565", "107566", "107567", "107568", "107569", "107571", "107573", "107574", "107575", "107577", "107578", "107579", "107582", "107583", "107585", "107586", "107587", "107593", "107595", "107596", "107597", "107599", "107600", "107603", "107604", "107605", "107607", "107608", "107610", "107611", "107613", "107614", "107615", "107618", "107620", "107621", "107622", "107623", "107624", "107627", "107628", "107629", "107635", "107636", "107637", "107638", "107640", "107641", "107644", "107646", "107647", "107649", "107652", "107655", "107656", "107659", "107661", "107664", "107665", "107666", "107671", "107672", "107675", "107676", "107678", "107679", "107680", "107681", "107684", "107685", "107690", "107695", "107696", "107698", "107704", "107705", "107709", "107710", "107711", "107712", "107713", "107714", "107715", "107717", "107719", "107721", "107724", "107726", "107727", "107730", "107731", "107734", "107735", "107736", "107737", "107742", "107745", "107746", "107750", "107754", "107755", "107758", "107759", "107760", "107761", "107765", "107767", "107770", "107771", "107773", "107774", "107775", "107776", "107778", "107779", "107787", "107788", "107791", "107793", "107796", "107797", "107798", "107799", "107805", "107806", "107807", "107809", "107811", "107812", "107813", "107816", "107817", "107818", "107820", "107821", "107826", "107827", "107829", "107831", "107832", "107833", "107834", "107835", "107836", "107837", "107838", "107843", "107844", "107846", "107847", "107848", "107852", "107853", "107854", "107855", "107857", "107859", "107861", "107862", "107863", "107865", "107866", "107867", "107868", "107869", "107872", "107875", "107876", "107877", "107882", "107883", "107885", "107886", "107888", "107889", "107890", "107891", "107892", "107894", "107895", "107899", "107900", "107902", "107905", "107907", "107908", "107909", "107910", "107913", "107915", "107916", "107917", "107919", "107922", "107926", "107927", "107928", "107929", "107931", "107934", "107936", "107937", "107940", "107941", "107942", "107944", "107951", "107952", "107955", "107956", "107957", "107962", "107964", "107965", "107972", "107975", "107977", "107978", "107979", "107980", "107981", "107982", "107984", "107985", "107986", "107987", "107988", "107989", "107992", "107996", "107997", "107998", "108003", "108004", "108005", "108007", "108008", "108014", "108015", "108017", "108018", "108019", "108024", "108026", "108027", "108030", "108031", "108034", "108035", "108036", "108038", "108042", "108045", "108047", "108049", "108051", "108052", "108053", "108054", "108055", "108057", "108059", "108060", "108061", "108063", "108065", "108069", "108074", "108076", "108077", "108078", "108079", "108081", "108082", "108083", "108085", "108087", "108091", "108095", "108099", "108100", "108102", "108105", "108107", "108108", "108111", "108112", "108114", "108116", "108118", "108119", "108120", "108121", "108123", "108127", "108130", "108133", "108135", "108139", "108140", "108141", "108142", "108143", "108146", "108149", "108151", "108152", "108153", "108154", "108156", "108165", "108166", "108167", "108169", "108171", "108172", "108173", "108175", "108176", "108177", "108180", "108184", "108185", "108186", "108192", "108193", "108194", "108196", "108197", "108198", "108200", "108201", "108202", "108205", "108206", "108207", "108208", "108209", "108212", "108213", "108214", "108215", "108217", "108218", "108219", "108220", "108228", "108231", "108232", "108233", "108237", "108238", "108240", "108241", "108243", "108245", "108246", "108249", "108250", "108251", "108253", "108254", "108258", "108260", "108263", "108264", "108265", "108268", "108270", "108271", "108273", "108277", "108279", "108283", "108285", "108287", "108291", "108294", "108296", "108297", "108298", "108299", "108301", "108302", "108305", "108306", "108307", "108308", "108313", "108315", "108317", "108319", "108321", "108322", "108323", "108324", "108327", "108328", "108331", "108334", "108335", "108336", "108339", "108341", "108342", "108343", "108345", "108350", "108351", "108352", "108353", "108354", "108355", "108356", "108357", "108358", "108359", "108361", "108362", "108364", "108365", "108367", "108369", "108371", "108373", "108375", "108376", "108379", "108382", "108384", "108386", "108388", "108395", "108397", "108398", "108400", "108401", "108404", "108405", "108406", "108407", "108410", "108414", "108415", "108416", "108418", "108419", "108421", "108422", "108423", "108424", "108425", "108426", "108428", "108430", "108436", "108441", "108442", "108443", "108444", "108448", "108451", "108454", "108457", "108458", "108463", "108464", "108465", "108466", "108470", "108473", "108476", "108477", "108478", "108481", "108483", "108485", "108486", "108487", "108493", "108494", "108497", "108500", "108501", "108503", "108504", "108506", "108510", "108511", "108512", "108513", "108516", "108517", "108518", "108520", "108525", "108526", "108527", "108528", "108530", "108534", "108535", "108536", "108537", "108538", "108539", "108541", "108543", "108547", "108549", "108550", "108551", "108553", "108554", "108556", "108557", "108558", "108559", "108560", "108561", "108565", "108569", "108573", "108574", "108577", "108583", "108585", "108586", "108587", "108588", "108589", "108590", "108591", "108592", "108593", "108597", "108598", "108599", "108601", "108602", "108603", "108607", "108608", "108610", "108611", "108612", "108613", "108614", "108617", "108618", "108620", "108621", "108623", "108624", "108625", "108626", "108627", "108629", "108631", "108632", "108634", "108635", "108636", "108637", "108640", "108641", "108642", "108644", "108646", "108647", "108649", "108650", "108651", "108652", "108653", "108657", "108658", "108662", "108666", "108669", "108670", "108673", "108675", "108676", "108678", "108679", "108680", "108681", "108683", "108684", "108686", "108687", "108689", "108691", "108692", "108693", "108694", "108695", "108696", "108700", "108702", "108705", "108708", "108710", "108711", "108712", "108714", "108720", "108721", "108722", "108724", "108725", "108729", "108734", "108740", "108741", "108743", "108749", "108750", "108751", "108754", "108759", "108764", "108766", "108767", "108768", "108769", "108770", "108771", "108774", "108776", "108777", "108778", "108779", "108780", "108783", "108784", "108785", "108791", "108793", "108794", "108796", "108797", "108798", "108800", "108803", "108806", "108807", "108808", "108809", "108811", "108813", "108814", "108816", "108817", "108818", "108819", "108820", "108821", "108828", "108831", "108833", "108834", "108838", "108839", "108840", "108845", "108847", "108850", "108851", "108856", "108857", "108858", "108862", "108864", "108868", "108869", "108870", "108874", "108876", "108878", "108880", "108883", "108887", "108889", "108890", "108891", "108894", "108896", "108902", "108903", "108908", "108911", "108912", "108914", "108915", "108917", "108918", "108919", "108921", "108927", "108929", "108932", "108933", "108934", "108936", "108937", "108938", "108939", "108942", "108943", "108945", "108946", "108947", "108948", "108950", "108959", "108960", "108963", "108964", "108971", "108972", "108973", "108974", "108977", "108978", "108980", "108982", "108985", "108986", "108987", "108993", "108994", "108997", "108998", "109001", "109003", "109004", "109006", "109007", "109010", "109013", "109014", "109017", "109019", "109020", "109021", "109024", "109025", "109026", "109027", "109030", "109031", "109035", "109037", "109040", "109041", "109043", "109048", "109049", "109051", "109055", "109059", "109060", "109062", "109067", "109068", "109069", "109070", "109071", "109074", "109076", "109077", "109078", "109081", "109082", "109085", "109086", "109087", "109091", "109092", "109093", "109094", "109096", "109097", "109098", "109102", "109103", "109108", "109110", "109111", "109114", "109116", "109117", "109119", "109122", "109123", "109125", "109126", "109128", "109131", "109132", "109135", "109137", "109138", "109140", "109141", "109146", "109147", "109148", "109151", "109152", "109153", "109154", "109155", "109156", "109157", "109159", "109161", "109162", "109167", "109169", "109171", "109173", "109177", "109178", "109179", "109181", "109182", "109183", "109184", "109185", "109186", "109187", "109190", "109192", "109193", "109195", "109198", "109199", "109200", "109203", "109207", "109209", "109211", "109215", "109217", "109220", "109221", "109223", "109225", "109227", "109228", "109230", "109231", "109233", "109235", "109236", "109238", "109239", "109240", "109241", "109243", "109249", "109253", "109258", "109259", "109261", "109262", "109263", "109267", "109270", "109272", "109274", "109275", "109279", "109281", "109282", "109283", "109284", "109287", "109290", "109291", "109293", "109294", "109295", "109296", "109298", "109301", "109302", "109303", "109307", "109308", "109309", "109310", "109312", "109315", "109316", "109317", "109320", "109321", "109327", "109329", "109330", "109333", "109335", "109337", "109339", "109341", "109343", "109344", "109347", "109348", "109349", "109351", "109353", "109354", "109356", "109358", "109360", "109361", "109362", "109363", "109366", "109368", "109369", "109371", "109373", "109374", "109375", "109377", "109378", "109381", "109382", "109383", "109387", "109388", "109389", "109391", "109394", "109396", "109397", "109404", "109405", "109406", "109408", "109410", "109411", "109412", "109417", "109418", "109421", "109423", "109426", "109427", "109429", "109430", "109437", "109438", "109440", "109442", "109444", "109446", "109447", "109448", "109452", "109457", "109459", "109461", "109462", "109463", "109465", "109467", "109471", "109474", "109475", "109476", "109477", "109480", "109486", "109490", "109491", "109494", "109495", "109496", "109498", "109499", "109500", "109501", "109502", "109503", "109504", "109506", "109510", "109511", "109512", "109513", "109514", "109516", "109517", "109519", "109521", "109524", "109526", "109529", "109530", "109531", "109533", "109536", "109539", "109541", "109545", "109548", "109549", "109553", "109556", "109560", "109564", "109567", "109569", "109570", "109571", "109572", "109573", "109575", "109576", "109577", "109578", "109579", "109582", "109583", "109584", "109586", "109588", "109589", "109592", "109593", "109594", "109595", "109600", "109602", "109603", "109609", "109610", "109615", "109616", "109618", "109620", "109621", "109622", "109624", "109630", "109632", "109633", "109634", "109637", "109638", "109639", "109640", "109641", "109643", "109644", "109650", "109655", "109657", "109658", "109662", "109664", "109665", "109672", "109675", "109677", "109678", "109679", "109680", "109681", "109683", "109684", "109685", "109686", "109687", "109688", "109689", "109691", "109693", "109694", "109698", "109701", "109702", "109703", "109704", "109705", "109709", "109710", "109712", "109715", "109722", "109724", "109725", "109727", "109729", "109730", "109732", "109733", "109734", "109735", "109736", "109737", "109738", "109739", "109740", "109743", "109745", "109747", "109748", "109751", "109752", "109753", "109755", "109759", "109760", "109761", "109762", "109763", "109765", "109766", "109767", "109768", "109771", "109774", "109776", "109777", "109778", "109779", "109780", "109783", "109784", "109786", "109795", "109799", "109804", "109805", "109808", "109809", "109810", "109813", "109814", "109817", "109818", "109820", "109822", "109825", "109827", "109828", "109829", "109831", "109832", "109833", "109834", "109836", "109837", "109838", "109839", "109840", "109841", "109843", "109844", "109845", "109846", "109847", "109849", "109850", "109852", "109855", "109856", "109857", "109859", "109862", "109863", "109865", "109866", "109867", "109869", "109870", "109872", "109876", "109879", "109881", "109883", "109884", "109885", "109886", "109887", "109888", "109889", "109890", "109892", "109895", "109897", "109899", "109904", "109905", "109910", "109913", "109914", "109915", "109916", "109917", "109918", "109919", "109921", "109923", "109925", "109927", "109928", "109929", "109930", "109931", "109932", "109936", "109937", "109939", "109940", "109941", "109944", "109949", "109952", "109954", "109955", "109958", "109960", "109961", "109962", "109963", "109966", "109967", "109970", "109971", "109972", "109973", "109974", "109976", "109978", "109980", "109981", "109982", "109986", "109996", "109997", "109998", "109999", "110000", "110002", "110003", "110005", "110007", "110009", "110011", "110012", "110013", "110016", "110017", "110020", "110023", "110025", "110027", "110028", "110033", "110034", "110035", "110039", "110040", "110046", "110048", "110049", "110050", "110051", "110052", "110056", "110057", "110059", "110060", "110061", "110063", "110064", "110067", "110070", "110074", "110078", "110080", "110084", "110086", "110090", "110091", "110094", "110096", "110097", "110098", "110100", "110101", "110102", "110103", "110105", "110107", "110110", "110111", "110119", "110120", "110121", "110123", "110124", "110125", "110126", "110127", "110129", "110130", "110131", "110132", "110133", "110135", "110136", "110141", "110143", "110145", "110148", "110151", "110152", "110156", "110158", "110161", "110164", "110167", "110168", "110172", "110175", "110177", "110184", "110188", "110189", "110193", "110195", "110196", "110198", "110200", "110202", "110206", "110207", "110209", "110211", "110213", "110214", "110217", "110218", "110220", "110221", "110222", "110223", "110224", "110225", "110226", "110231", "110236", "110239", "110240", "110241", "110245", "110247", "110248", "110251", "110255", "110256", "110259", "110261", "110265", "110270", "110273", "110274", "110275", "110276", "110277", "110281", "110282", "110284", "110287", "110290", "110293", "110294", "110296", "110300", "110301", "110305", "110309", "110310", "110315", "110316", "110317", "110319", "110322", "110327", "110330", "110332", "110333", "110335", "110336", "110337", "110338", "110339", "110340", "110341", "110343", "110344", "110346", "110348", "110350", "110353", "110354", "110355", "110357", "110362", "110364", "110367", "110368", "110369", "110370", "110373", "110375", "110376", "110377", "110378", "110382", "110383", "110384", "110385", "110386", "110396", "110399", "110400", "110403", "110407", "110408", "110409", "110410", "110413", "110415", "110416", "110417", "110419", "110420", "110424", "110425", "110426", "110427", "110428", "110429", "110430", "110432", "110434", "110435", "110439", "110441", "110442", "110443", "110445", "110446", "110447", "110448", "110449", "110450", "110452", "110453", "110455", "110457", "110461", "110464", "110469", "110470", "110472", "110476", "110481", "110482", "110483", "110485", "110490", "110493", "110494", "110496", "110497", "110498", "110499", "110500", "110501", "110503", "110504", "110505", "110506", "110508", "110511", "110513", "110516", "110519", "110520", "110522", "110525", "110526", "110527", "110528", "110532", "110533", "110534", "110535", "110536", "110537", "110538", "110539", "110541", "110542", "110546", "110547", "110548", "110551", "110552", "110553", "110554", "110557", "110561", "110564", "110565", "110568", "110569", "110571", "110572", "110573", "110577", "110578", "110581", "110582", "110585", "110588", "110589", "110592", "110593", "110595", "110598", "110599", "110601", "110605", "110607", "110608", "110610", "110611", "110613", "110619", "110622", "110623", "110628", "110629", "110630", "110631", "110633", "110634", "110635", "110641", "110642", "110644", "110645", "110647", "110651", "110653", "110654", "110656", "110659", "110660", "110661", "110662", "110664", "110667", "110668", "110670", "110672", "110673", "110674", "110675", "110676", "110677", "110678", "110680", "110681", "110683", "110684", "110687", "110692", "110693", "110694", "110697", "110698", "110699", "110702", "110703", "110704", "110705", "110706", "110707", "110708", "110711", "110714", "110718", "110721", "110723", "110725", "110726", "110728", "110730", "110731", "110734", "110735", "110739", "110740", "110741", "110742", "110743", "110746", "110747", "110748", "110752", "110755", "110760", "110762", "110763", "110766", "110768", "110769", "110771", "110775", "110776", "110777", "110778", "110780", "110781", "110782", "110785", "110786", "110788", "110789", "110790", "110794", "110795", "110799", "110804", "110805", "110806", "110807", "110808", "110811", "110812", "110813", "110814", "110816", "110818", "110820", "110821", "110822", "110823", "110825", "110828", "110829", "110830", "110833", "110839", "110840", "110841", "110842", "110844", "110845", "110847", "110848", "110849", "110850", "110852", "110854", "110856", "110857", "110858", "110859", "110860", "110862", "110863", "110869", "110870", "110872", "110873", "110875", "110877", "110878", "110880", "110882", "110883", "110887", "110889", "110894", "110895", "110898", "110899", "110902", "110903", "110904", "110911", "110913", "110915", "110918", "110923", "110927", "110930", "110931", "110933", "110934", "110938", "110939", "110940", "110943", "110944", "110945", "110946", "110947", "110948", "110950", "110953", "110954", "110956", "110958", "110959", "110962", "110963", "110964", "110965", "110968", "110970", "110972", "110974", "110978", "110979", "110980", "110984", "110985", "110990", "110993", "110995", "110997", "110998", "110999", "111000", "111001", "111002", "111003", "111004", "111007", "111008", "111010", "111013", "111016", "111017", "111019", "111020", "111022", "111025", "111027", "111029", "111033", "111036", "111038", "111041", "111042", "111044", "111045", "111046", "111048", "111049", "111055", "111058", "111062", "111063", "111066", "111067", "111069", "111070", "111072", "111073", "111075", "111079", "111081", "111084", "111086", "111088", "111091", "111093", "111094", "111096", "111097", "111098", "111099", "111100", "111101", "111104", "111105", "111107", "111111", "111112", "111113", "111114", "111115", "111116", "111120", "111121", "111122", "111126", "111127", "111128", "111130", "111134", "111138", "111139", "111141", "111142", "111143", "111146", "111149", "111150", "111154", "111157", "111158", "111160", "111162", "111164", "111167", "111168", "111172", "111173", "111175", "111176", "111179", "111183", "111187", "111188", "111189", "111190", "111194", "111198", "111201", "111203", "111207", "111208", "111210", "111213", "111214", "111215", "111216", "111218", "111219", "111222", "111225", "111228", "111231", "111232", "111233", "111234", "111236", "111239", "111240", "111241", "111244", "111246", "111247", "111249", "111251", "111252", "111255", "111256", "111257", "111262", "111264", "111267", "111268", "111269", "111270", "111272", "111273", "111274", "111275", "111276", "111278", "111280", "111284", "111286", "111288", "111289", "111290", "111295", "111296", "111297", "111298", "111300", "111301", "111303", "111304", "111311", "111312", "111313", "111314", "111315", "111316", "111317", "111320", "111322", "111323", "111324", "111327", "111328", "111329", "111330", "111334", "111335", "111338", "111342", "111343", "111346", "111347", "111348", "111349", "111350", "111353", "111355", "111356", "111357", "111358", "111359", "111360", "111361", "111362", "111365", "111366", "111368", "111369", "111370", "111372", "111373", "111374", "111375", "111376", "111377", "111378", "111379", "111380", "111382", "111383", "111386", "111387", "111389", "111390", "111392", "111393", "111396", "111400", "111405", "111406", "111407", "111408", "111410", "111411", "111414", "111415", "111418", "111419", "111420", "111424", "111426", "111427", "111428", "111429", "111436", "111438", "111440", "111442", "111446", "111447", "111448", "111449", "111451", "111452", "111453", "111454", "111455", "111456", "111458", "111462", "111466", "111468", "111470", "111471", "111474", "111475", "111476", "111477", "111480", "111481", "111482", "111483", "111484", "111493", "111494", "111495", "111499", "111500", "111502", "111505", "111507", "111508", "111510", "111511", "111512", "111513", "111514", "111515", "111516", "111517", "111519", "111520", "111523", "111524", "111525", "111526", "111531", "111532", "111533", "111534", "111535", "111539", "111541", "111542", "111543", "111544", "111546", "111549", "111551", "111552", "111554", "111555", "111556", "111557", "111558", "111561", "111562", "111564", "111566", "111567", "111568", "111569", "111571", "111573", "111578", "111579", "111581", "111582", "111584", "111585", "111587", "111588", "111589", "111595", "111597", "111598", "111599", "111601", "111602", "111603", "111604", "111608", "111609", "111612", "111613", "111615", "111616", "111617", "111618", "111619", "111621", "111622", "111623", "111627", "111628", "111629", "111630", "111634", "111635", "111637", "111640", "111641", "111642", "111648", "111649", "111650", "111651", "111652", "111653", "111657", "111658", "111663", "111664", "111666", "111667", "111669", "111670", "111673", "111675", "111676", "111677", "111680", "111682", "111683", "111686", "111688", "111689", "111690", "111692", "111693", "111696", "111698", "111700", "111701", "111702", "111708", "111709", "111710", "111712", "111717", "111723", "111724", "111728", "111733", "111734", "111735", "111736", "111737", "111738", "111741", "111742", "111744", "111745", "111752", "111756", "111757", "111758", "111759", "111760", "111762", "111763", "111767", "111769", "111770", "111772", "111774", "111776", "111777", "111778", "111779", "111780", "111781", "111784", "111786", "111787", "111788", "111792", "111797", "111801", "111803", "111804", "111805", "111815", "111818", "111819", "111820", "111821", "111823", "111824", "111825", "111826", "111828", "111829", "111830", "111831", "111838", "111840", "111842", "111844", "111845", "111846", "111847", "111848", "111850", "111853", "111854", "111855", "111856", "111859", "111860", "111862", "111866", "111867", "111868", "111869", "111875", "111876", "111877", "111880", "111881", "111882", "111883", "111885", "111886", "111887", "111889", "111892", "111895", "111897", "111902", "111905", "111908", "111910", "111911", "111912", "111913", "111914", "111918", "111923", "111924", "111928", "111929", "111930", "111939", "111940", "111942", "111944", "111945", "111947", "111948", "111950", "111951", "111961", "111962", "111963", "111965", "111966", "111967", "111968", "111969", "111977", "111979", "111982", "111985", "111987", "111988", "111990", "111992", "111993", "111995", "111998", "112000", "112001", "112004", "112006", "112007", "112009", "112011", "112015", "112016", "112018", "112019", "112020", "112023", "112024", "112026", "112027", "112036", "112037", "112045", "112046", "112052", "112053", "112056", "112057", "112060", "112066", "112067", "112069", "112071", "112072", "112073", "112075", "112076", "112078", "112080", "112082", "112083", "112084", "112085", "112087", "112088", "112092", "112093", "112096", "112098", "112099", "112100", "112102", "112104", "112106", "112109", "112110", "112113", "112114", "112115", "112121", "112123", "112125", "112126", "112128", "112132", "112133", "112135", "112138", "112139", "112141", "112143", "112148", "112150", "112152", "112153", "112154", "112155", "112159", "112160", "112162", "112163", "112164", "112165", "112166", "112167", "112169", "112170", "112172", "112173", "112174", "112175", "112177", "112178", "112179", "112180", "112182", "112187", "112188", "112189", "112192", "112195", "112197", "112199", "112200", "112201", "112202", "112204", "112205", "112206", "112207", "112208", "112213", "112216", "112217", "112218", "112222", "112225", "112227", "112228", "112231", "112233", "112234", "112237", "112238", "112241", "112243", "112244", "112245", "112246", "112248", "112251", "112252", "112254", "112256", "112257", "112258", "112260", "112261", "112262", "112263", "112269", "112271", "112272", "112273", "112274", "112276", "112278", "112280", "112281", "112283", "112292", "112297", "112299", "112300", "112304", "112310", "112312", "112316", "112318", "112320", "112321", "112323", "112327", "112329", "112330", "112331", "112332", "112335", "112339", "112340", "112342", "112343", "112345", "112346", "112352", "112354", "112355", "112357", "112358", "112360", "112361", "112363", "112364", "112365", "112366", "112369", "112376", "112378", "112380", "112381", "112385", "112386", "112388", "112389", "112390", "112392", "112393", "112394", "112396", "112397", "112398", "112401", "112402", "112403", "112405", "112406", "112409", "112410", "112412", "112414", "112416", "112419", "112427", "112429", "112430", "112431", "112432", "112433", "112434", "112435", "112436", "112437", "112438", "112439", "112442", "112443", "112444", "112445", "112449", "112450", "112454", "112457", "112460", "112461", "112462", "112463", "112465", "112468", "112469", "112474", "112489", "112490", "112491", "112492", "112494", "112497", "112499", "112500", "112501", "112503", "112504", "112507", "112508", "112509", "112511", "112513", "112515", "112518", "112520", "112523", "112524", "112528", "112529", "112531", "112532", "112533", "112534", "112535", "112537", "112538", "112539", "112541", "112544", "112546", "112551", "112553", "112554", "112555", "112557", "112560", "112562", "112563", "112564", "112566", "112567", "112568", "112574", "112575", "112577", "112579", "112582", "112583", "112585", "112586", "112587", "112588", "112590", "112591", "112592", "112593", "112594", "112595", "112597", "112598", "112600", "112601", "112604", "112605", "112606", "112608", "112614", "112615", "112616", "112617", "112620", "112622", "112623", "112624", "112625", "112629", "112630", "112632", "112633", "112634", "112636", "112640", "112642", "112645", "112647", "112649", "112650", "112651", "112652", "112655", "112658", "112659", "112662", "112666", "112668", "112675", "112680", "112683", "112684", "112687", "112688", "112690", "112692", "112695", "112697", "112701", "112703", "112705", "112707", "112708", "112711", "112712", "112713", "112715", "112717", "112732", "112733", "112734", "112737", "112741", "112743", "112745", "112746", "112748", "112755", "112759", "112761", "112766", "112768", "112770", "112771", "112772", "112773", "112774", "112778", "112782", "112785", "112788", "112791", "112794", "112796", "112798", "112799", "112800", "112806", "112809", "112810", "112811", "112812", "112813", "112819", "112820", "112821", "112825", "112827", "112829", "112832", "112833", "112834", "112835", "112838", "112841", "112842", "112844", "112845", "112846", "112847", "112850", "112851", "112853", "112854", "112855", "112857", "112858", "112859", "112860", "112863", "112864", "112866", "112868", "112869", "112870", "112872", "112880", "112882", "112885", "112886", "112888", "112889", "112890", "112893", "112895", "112899", "112900", "112901", "112902", "112904", "112905", "112910", "112911", "112912", "112914", "112917", "112919", "112922", "112923", "112924", "112926", "112929", "112930", "112931", "112935", "112937", "112938", "112942", "112944", "112949", "112951", "112952", "112956", "112959", "112961", "112962", "112964", "112966", "112968", "112969", "112970", "112971", "112974", "112975", "112977", "112978", "112981", "112982", "112984", "112985", "112987", "112988", "112991", "112992", "112993", "112994", "112995", "113000", "113004", "113005", "113009", "113010", "113013", "113014", "113015", "113019", "113020", "113023", "113024", "113025", "113026", "113027", "113028", "113029", "113031", "113033", "113034", "113035", "113038", "113039", "113040", "113042", "113043", "113044", "113046", "113048", "113052", "113053", "113054", "113058", "113059", "113060", "113061", "113062", "113063", "113064", "113068", "113070", "113071", "113072", "113079", "113081", "113083", "113088", "113092", "113093", "113094", "113098", "113103", "113104", "113105", "113108", "113113", "113118", "113119", "113120", "113122", "113125", "113127", "113128", "113130", "113131", "113133", "113134", "113135", "113136", "113137", "113138", "113142", "113147", "113148", "113149", "113150", "113151", "113153", "113156", "113157", "113158", "113159", "113165", "113167", "113172", "113174", "113175", "113176", "113177", "113178", "113182", "113186", "113187", "113188", "113189", "113194", "113195", "113198", "113200", "113201", "113202", "113203", "113204", "113205", "113207", "113213", "113214", "113218", "113219", "113228", "113230", "113232", "113236", "113241", "113242", "113243", "113245", "113248", "113249", "113250", "113254", "113256", "113258", "113260", "113261", "113262", "113265", "113267", "113268", "113270", "113271", "113273", "113274", "113275", "113276", "113277", "113278", "113279", "113280", "113282", "113284", "113290", "113292", "113293", "113294", "113297", "113299", "113301", "113304", "113306", "113308", "113309", "113310", "113312", "113313", "113315", "113317", "113319", "113321", "113323", "113325", "113326", "113327", "113328", "113331", "113332", "113333", "113334", "113336", "113337", "113340", "113341", "113342", "113343", "113344", "113345", "113348", "113354", "113355", "113356", "113357", "113358", "113362", "113363", "113364", "113365", "113367", "113368", "113369", "113374", "113376", "113379", "113380", "113383", "113384", "113385", "113389", "113390", "113391", "113393", "113395", "113396", "113397", "113402", "113403", "113407", "113409", "113411", "113412", "113416", "113417", "113419", "113420", "113421", "113422", "113424", "113425", "113426", "113427", "113429", "113431", "113434", "113436", "113437", "113438", "113442", "113447", "113448", "113449", "113450", "113451", "113452", "113453", "113456", "113461", "113462", "113463", "113464", "113465", "113469", "113471", "113472", "113474", "113477", "113478", "113480", "113481", "113485", "113487", "113488", "113493", "113494", "113495", "113497", "113498", "113500", "113503", "113504", "113506", "113507", "113509", "113514", "113517", "113522", "113525", "113528", "113529", "113534", "113536", "113537", "113538", "113540", "113544", "113546", "113548", "113549", "113553", "113556", "113557", "113558", "113559", "113563", "113564", "113565", "113566", "113568", "113570", "113571", "113573", "113574", "113576", "113578", "113580", "113581", "113582", "113584", "113585", "113586", "113587", "113589", "113592", "113593", "113595", "113596", "113598", "113601", "113606", "113607", "113608", "113612", "113614", "113616", "113617", "113618", "113620", "113623", "113624", "113625", "113629", "113632", "113634", "113635", "113636", "113639", "113640", "113641", "113642", "113648", "113652", "113653", "113656", "113661", "113663", "113664", "113665", "113667", "113669", "113672", "113673", "113674", "113676", "113678", "113679", "113680", "113682", "113684", "113685", "113686", "113687", "113688", "113689", "113694", "113696", "113697", "113700", "113706", "113707", "113709", "113710", "113715", "113716", "113719", "113724", "113725", "113727", "113728", "113730", "113731", "113733", "113734", "113737", "113738", "113739", "113740", "113741", "113746", "113747", "113748", "113749", "113750", "113751", "113752", "113754", "113756", "113757", "113759", "113761", "113765", "113767", "113768", "113769", "113770", "113771", "113774", "113776", "113778", "113780", "113781", "113782", "113785", "113787", "113789", "113790", "113793", "113794", "113795", "113798", "113800", "113801", "113804", "113805", "113806", "113810", "113811", "113812", "113813", "113814", "113817", "113822", "113823", "113827", "113829", "113830", "113832", "113833", "113838", "113839", "113840", "113841", "113846", "113848", "113852", "113854", "113860", "113866", "113867", "113871", "113873", "113875", "113877", "113880", "113882", "113886", "113888", "113889", "113892", "113893", "113894", "113895", "113896", "113898", "113900", "113902", "113904", "113906", "113907", "113911", "113912", "113913", "113918", "113921", "113922", "113924", "113928", "113930", "113933", "113934", "113937", "113940", "113942", "113944", "113947", "113948", "113951", "113955", "113956", "113958", "113959", "113960", "113961", "113963", "113965", "113966", "113967", "113968", "113975", "113977", "113978", "113984", "113985", "113986", "113989", "113990", "113992", "113995", "113996", "113998", "113999", "114000", "114002", "114006", "114012", "114013", "114015", "114018", "114019", "114020", "114021", "114023", "114024", "114026", "114027", "114028", "114030", "114031", "114032", "114033", "114036", "114039", "114041", "114042", "114044", "114047", "114052", "114060", "114061", "114062", "114063", "114068", "114070", "114071", "114072", "114073", "114074", "114075", "114076", "114077", "114078", "114080", "114084", "114085", "114087", "114088", "114091", "114092", "114094", "114096", "114097", "114098", "114099", "114100", "114103", "114104", "114105", "114106", "114108", "114115", "114116", "114119", "114120", "114124", "114125", "114127", "114129", "114130", "114131", "114132", "114133", "114134", "114135", "114136", "114138", "114139", "114141", "114143", "114144", "114145", "114147", "114149", "114150", "114154", "114155", "114156", "114157", "114158", "114160", "114164", "114165", "114166", "114167", "114170", "114171", "114172", "114177", "114178", "114179", "114180", "114182", "114185", "114186", "114188", "114191", "114197", "114198", "114199", "114201", "114202", "114203", "114205", "114208", "114209", "114210", "114211", "114213", "114214", "114217", "114218", "114219", "114222", "114225", "114228", "114229", "114230", "114231", "114233", "114235", "114236", "114238", "114239", "114240", "114241", "114242", "114244", "114249", "114250", "114253", "114254", "114259", "114260", "114261", "114262", "114265", "114269", "114277", "114278", "114279", "114283", "114285", "114287", "114288", "114289", "114290", "114295", "114296", "114298", "114299", "114301", "114303", "114304", "114305", "114306", "114308", "114311", "114312", "114317", "114318", "114320", "114323", "114324", "114328", "114329", "114331", "114332", "114333", "114335", "114336", "114337", "114338", "114339", "114340", "114343", "114344", "114346", "114353", "114354", "114355", "114358", "114359", "114360", "114363", "114367", "114368", "114369", "114370", "114371", "114372", "114375", "114376", "114380", "114381", "114385", "114391", "114392", "114394", "114395", "114396", "114397", "114398", "114399", "114400", "114402", "114403", "114405", "114407", "114408", "114409", "114410", "114412", "114413", "114414", "114417", "114418", "114419", "114422", "114425", "114429", "114430", "114431", "114433", "114434", "114436", "114441", "114444", "114445", "114446", "114447", "114449", "114450", "114452", "114456", "114457", "114458", "114462", "114464", "114468", "114469", "114471", "114472", "114473", "114474", "114476", "114478", "114479", "114480", "114482", "114483", "114486", "114489", "114491", "114494", "114496", "114500", "114504", "114509", "114510", "114511", "114513", "114515", "114519", "114522", "114525", "114526", "114527", "114528", "114531", "114534", "114536", "114541", "114542", "114544", "114546", "114550", "114551", "114553", "114554", "114555", "114556", "114560", "114563", "114564", "114565", "114566", "114569", "114570", "114571", "114574", "114575", "114577", "114583", "114586", "114588", "114591", "114597", "114599", "114602", "114604", "114611", "114612", "114613", "114614", "114615", "114616", "114620", "114622", "114623", "114627", "114628", "114630", "114631", "114632", "114633", "114638", "114640", "114641", "114648", "114649", "114652", "114653", "114654", "114655", "114657", "114658", "114659", "114660", "114661", "114663", "114664", "114665", "114666", "114668", "114671", "114672", "114673", "114676", "114677", "114681", "114682", "114683", "114685", "114686", "114690", "114691", "114693", "114694", "114697", "114699", "114702", "114703", "114705", "114709", "114711", "114712", "114713", "114714", "114717", "114718", "114721", "114723", "114724", "114725", "114726", "114727", "114729", "114730", "114731", "114735", "114736", "114738", "114743", "114744", "114745", "114748", "114753", "114755", "114758", "114761", "114762", "114767", "114768", "114770", "114771", "114772", "114773", "114775", "114776", "114778", "114779", "114780", "114781", "114782", "114784", "114786", "114788", "114794", "114795", "114796", "114799", "114800", "114801", "114802", "114804", "114806", "114810", "114813", "114817", "114820", "114822", "114823", "114825", "114828", "114829", "114830", "114831", "114832", "114833", "114834", "114835", "114837", "114839", "114841", "114842", "114844", "114846", "114847", "114849", "114851", "114855", "114857", "114858", "114860", "114861", "114864", "114865", "114866", "114872", "114874", "114876", "114879", "114880", "114881", "114885", "114890", "114897", "114903", "114906", "114912", "114918", "114926", "114927", "114929", "114931", "114932", "114934", "114936", "114937", "114939", "114942", "114947", "114949", "114953", "114960", "114961", "114962", "114963", "114964", "114966", "114967", "114968", "114969", "114970", "114971", "114973", "114980", "114982", "114984", "114986", "114988", "114990", "114991", "114997", "115000", "115002", "115004", "115005", "115006", "115007", "115010", "115012", "115014", "115016", "115018", "115019", "115021", "115023", "115025", "115026", "115031", "115032", "115033", "115035", "115036", "115038", "115040", "115042", "115044", "115046", "115048", "115049", "115050", "115051", "115053", "115054", "115058", "115062", "115063", "115064", "115065", "115071", "115072", "115073", "115074", "115075", "115078", "115079", "115081", "115085", "115090", "115091", "115092", "115094", "115098", "115099", "115101", "115103", "115105", "115108", "115110", "115112", "115113", "115114", "115118", "115119", "115120", "115121", "115122", "115125", "115127", "115131", "115132", "115133", "115134", "115138", "115139", "115140", "115141", "115143", "115144", "115145", "115146", "115148", "115150", "115153", "115154", "115158", "115164", "115165", "115168", "115169", "115170", "115171", "115173", "115175", "115177", "115178", "115181", "115182", "115183", "115187", "115190", "115192", "115193", "115194", "115195", "115196", "115198", "115202", "115204", "115205", "115206", "115213", "115218", "115219", "115221", "115222", "115223", "115224", "115227", "115228", "115230", "115232", "115234", "115235", "115243", "115245", "115246", "115248", "115255", "115260", "115262", "115263", "115266", "115269", "115270", "115271", "115273", "115274", "115275", "115276", "115277", "115278", "115279", "115281", "115282", "115283", "115289", "115290", "115291", "115292", "115293", "115294", "115295", "115296", "115298", "115300", "115301", "115302", "115303", "115304", "115306", "115308", "115309", "115310", "115311", "115312", "115315", "115317", "115318", "115320", "115321", "115322", "115323", "115324", "115325", "115327", "115329", "115330", "115332", "115336", "115337", "115339", "115341", "115344", "115345", "115348", "115349", "115351", "115352", "115353", "115354", "115358", "115360", "115363", "115365", "115366", "115368", "115371", "115376", "115377", "115378", "115380", "115384", "115386", "115388", "115389", "115390", "115391", "115392", "115393", "115402", "115403", "115404", "115405", "115406", "115407", "115408", "115410", "115417", "115418", "115420", "115421", "115423", "115424", "115425", "115426", "115429", "115430", "115432", "115434", "115435", "115437", "115440", "115442", "115444", "115448", "115449", "115451", "115457", "115459", "115460", "115462", "115463", "115464", "115465", "115466", "115467", "115468", "115471", "115472", "115473", "115475", "115476", "115477", "115479", "115482", "115485", "115487", "115488", "115498", "115501", "115502", "115503", "115507", "115508", "115509", "115511", "115512", "115517", "115518", "115520", "115521", "115523", "115527", "115528", "115531", "115533", "115536", "115542", "115548", "115549", "115550", "115551", "115552", "115554", "115555", "115556", "115557", "115558", "115560", "115561", "115562", "115563", "115565", "115566", "115567", "115568", "115571", "115572", "115574", "115576", "115577", "115578", "115579", "115580", "115582", "115584", "115587", "115588", "115590", "115595", "115597", "115599", "115600", "115604", "115606", "115607", "115609", "115610", "115612", "115613", "115615", "115620", "115621", "115622", "115623", "115624", "115625", "115626", "115629", "115630", "115635", "115636", "115639", "115640", "115641", "115642", "115643", "115644", "115646", "115647", "115649", "115650", "115651", "115652", "115653", "115654", "115655", "115658", "115660", "115662", "115664", "115665", "115666", "115667", "115669", "115671", "115672", "115675", "115676", "115678", "115681", "115682", "115683", "115685", "115687", "115688", "115691", "115692", "115693", "115697", "115698", "115699", "115700", "115703", "115706", "115707", "115713", "115716", "115719", "115721", "115725", "115726", "115729", "115730", "115733", "115734", "115735", "115738", "115739", "115742", "115743", "115744", "115747", "115757", "115759", "115760", "115762", "115764", "115766", "115768", "115769", "115772", "115773", "115775", "115776", "115778", "115779", "115780", "115783", "115784", "115785", "115788", "115789", "115792", "115793", "115794", "115795", "115796", "115799", "115802", "115803", "115805", "115806", "115808", "115809", "115812", "115813", "115817", "115818", "115819", "115823", "115826", "115827", "115828", "115829", "115838", "115840", "115841", "115842", "115843", "115847", "115849", "115852", "115853", "115856", "115859", "115860", "115863", "115865", "115868", "115870", "115872", "115874", "115876", "115879", "115881", "115882", "115883", "115884", "115886", "115887", "115888", "115889", "115890", "115894", "115895", "115896", "115897", "115898", "115901", "115904", "115911", "115914", "115915", "115916", "115918", "115919", "115920", "115921", "115922", "115923", "115925", "115926", "115928", "115930", "115931", "115934", "115937", "115938", "115940", "115943", "115949", "115951", "115953", "115954", "115955", "115956", "115959", "115960", "115961", "115964", "115965", "115967", "115968", "115970", "115972", "115975", "115976", "115977", "115978", "115979", "115981", "115982", "115983", "115984", "115985", "115986", "115990", "115991", "115992", "115993", "115996", "115998", "116000", "116001", "116002", "116003", "116004", "116007", "116008", "116010", "116013", "116014", "116016", "116017", "116019", "116020", "116022", "116026", "116027", "116029", "116030", "116031", "116032", "116033", "116034", "116035", "116037", "116038", "116040", "116041", "116042", "116044", "116045", "116048", "116049", "116050", "116052", "116054", "116056", "116057", "116061", "116064", "116066", "116067", "116069", "116070", "116071", "116074", "116075", "116078", "116079", "116082", "116084", "116085", "116088", "116090", "116092", "116093", "116095", "116096", "116097", "116099", "116100", "116102", "116103", "116104", "116105", "116106", "116108", "116109", "116111", "116114", "116115", "116116", "116117", "116118", "116119", "116121", "116122", "116123", "116124", "116125", "116126", "116127", "116129", "116130", "116131", "116132", "116133", "116137", "116139", "116140", "116141", "116142", "116143", "116144", "116146", "116151", "116153", "116154", "116155", "116156", "116157", "116158", "116160", "116161", "116163", "116164", "116165", "116168", "116169", "116172", "116174", "116175", "116176", "116178", "116179", "116180", "116181", "116183", "116186", "116188", "116189", "116190", "116192", "116193", "116200", "116201", "116202", "116205", "116206", "116207", "116209", "116212", "116213", "116214", "116215", "116219", "116221", "116223", "116224", "116225", "116226", "116232", "116233", "116234", "116239", "116240", "116246", "116247", "116248", "116249", "116253", "116254", "116259", "116265", "116266", "116267", "116268", "116269", "116271", "116273", "116276", "116279", "116281", "116286", "116291", "116292", "116293", "116295", "116296", "116297", "116298", "116301", "116302", "116307", "116308", "116310", "116313", "116314", "116315", "116316", "116318", "116319", "116320", "116322", "116323", "116324", "116325", "116326", "116327", "116329", "116331", "116332", "116333", "116334", "116335", "116337", "116339", "116342", "116343", "116345", "116347", "116349", "116350", "116352", "116354", "116356", "116359", "116361", "116362", "116363", "116364", "116371", "116374", "116376", "116377", "116378", "116379", "116380", "116381", "116384", "116387", "116391", "116393", "116395", "116397", "116400", "116403", "116404", "116405", "116407", "116408", "116410", "116411", "116412", "116414", "116416", "116417", "116418", "116419", "116421", "116425", "116426", "116428", "116429", "116432", "116434", "116435", "116438", "116439", "116441", "116443", "116447", "116448", "116449", "116452", "116453", "116454", "116455", "116456", "116457", "116459", "116461", "116463", "116465", "116469", "116470", "116471", "116475", "116476", "116478", "116480", "116481", "116485", "116486", "116487", "116488", "116490", "116494", "116495", "116497", "116500", "116501", "116502", "116504", "116505", "116506", "116509", "116515", "116517", "116519", "116524", "116526", "116528", "116529", "116537", "116540", "116542", "116543", "116544", "116546", "116548", "116550", "116553", "116555", "116556", "116560", "116563", "116564", "116565", "116566", "116569", "116570", "116572", "116573", "116575", "116576", "116579", "116580", "116584", "116585", "116586", "116587", "116588", "116591", "116596", "116597", "116598", "116599", "116600", "116601", "116603", "116604", "116605", "116606", "116607", "116611", "116612", "116613", "116615", "116617", "116619", "116620", "116622", "116624", "116625", "116626", "116627", "116628", "116629", "116630", "116631", "116634", "116635", "116637", "116639", "116642", "116645", "116646", "116647", "116648", "116652", "116653", "116658", "116659", "116660", "116663", "116664", "116669", "116670", "116671", "116673", "116679", "116681", "116682", "116683", "116685", "116687", "116688", "116691", "116692", "116696", "116698", "116699", "116704", "116706", "116707", "116709", "116711", "116712", "116713", "116714", "116717", "116719", "116720", "116721", "116723", "116724", "116726", "116727", "116730", "116731", "116732", "116733", "116735", "116737", "116741", "116742", "116743", "116745", "116746", "116747", "116748", "116751", "116753", "116754", "116755", "116757", "116759", "116760", "116763", "116769", "116776", "116777", "116780", "116782", "116787", "116792", "116794", "116795", "116797", "116801", "116802", "116803", "116810", "116811", "116812", "116813", "116817", "116819", "116820", "116821", "116823", "116826", "116827", "116828", "116832", "116834", "116835", "116838", "116839", "116840", "116842", "116844", "116846", "116849", "116853", "116856", "116857", "116858", "116860", "116862", "116867", "116869", "116872", "116873", "116874", "116875", "116881", "116885", "116886", "116887", "116888", "116890", "116893", "116897", "116898", "116899", "116901", "116902", "116903", "116904", "116905", "116906", "116907", "116908", "116909", "116914", "116916", "116919", "116920", "116922", "116923", "116924", "116926", "116928", "116930", "116931", "116932", "116934", "116936", "116937", "116938", "116939", "116941", "116942", "116943", "116947", "116949", "116950", "116951", "116956", "116958", "116959", "116960", "116962", "116963", "116965", "116967", "116968", "116971", "116972", "116973", "116974", "116975", "116978", "116981", "116982", "116984", "116989", "116994", "116997", "117000", "117002", "117003", "117004", "117006", "117009", "117012", "117014", "117016", "117019", "117020", "117021", "117022", "117023", "117025", "117027", "117030", "117034", "117035", "117037", "117039", "117040", "117041", "117042", "117043", "117044", "117045", "117046", "117053", "117054", "117056", "117057", "117058", "117060", "117061", "117062", "117064", "117065", "117066", "117067", "117069", "117072", "117073", "117074", "117079", "117082", "117083", "117084", "117087", "117094", "117096", "117097", "117099", "117100", "117102", "117103", "117104", "117106", "117108", "117109", "117110", "117111", "117113", "117114", "117116", "117119", "117121", "117124", "117126", "117127", "117129", "117133", "117136", "117137", "117140", "117141", "117143", "117144", "117145", "117148", "117152", "117153", "117155", "117156", "117158", "117159", "117160", "117161", "117162", "117164", "117165", "117166", "117168", "117169", "117170", "117174", "117180", "117181", "117182", "117183", "117185", "117190", "117193", "117199", "117200", "117201", "117203", "117204", "117206", "117207", "117209", "117213", "117214", "117216", "117219", "117220", "117222", "117224", "117226", "117228", "117230", "117235", "117236", "117237", "117240", "117243", "117244", "117245", "117246", "117251", "117253", "117258", "117260", "117266", "117267", "117268", "117269", "117270", "117272", "117274", "117275", "117276", "117285", "117286", "117287", "117289", "117292", "117293", "117297", "117311", "117313", "117314", "117315", "117319", "117320", "117324", "117325", "117326", "117330", "117331", "117335", "117336", "117342", "117343", "117345", "117346", "117347", "117348", "117349", "117352", "117353", "117356", "117357", "117358", "117359", "117360", "117361", "117362", "117363", "117364", "117365", "117366", "117368", "117369", "117370", "117373", "117374", "117376", "117380", "117383", "117384", "117386", "117387", "117388", "117389", "117390", "117392", "117398", "117400", "117404", "117405", "117408", "117410", "117411", "117412", "117413", "117416", "117417", "117420", "117422", "117423", "117424", "117425", "117426", "117429", "117430", "117432", "117433", "117434", "117436", "117439", "117444", "117445", "117446", "117448", "117452", "117456", "117457", "117459", "117461", "117462", "117463", "117466", "117467", "117469", "117472", "117474", "117483", "117485", "117486", "117487", "117494", "117498", "117500", "117501", "117502", "117504", "117507", "117508", "117509", "117510", "117511", "117513", "117517", "117521", "117522", "117524", "117525", "117527", "117528", "117529", "117532", "117534", "117543", "117544", "117547", "117548", "117550", "117551", "117552", "117554", "117558", "117559", "117560", "117561", "117563", "117565", "117566", "117567", "117568", "117570", "117571", "117573", "117574", "117577", "117580", "117581", "117582", "117583", "117584", "117589", "117590", "117594", "117595", "117598", "117608", "117612", "117613", "117615", "117616", "117619", "117622", "117624", "117626", "117627", "117628", "117629", "117630", "117631", "117636", "117637", "117639", "117644", "117646", "117648", "117649", "117650", "117651", "117653", "117654", "117658", "117662", "117664", "117665", "117666", "117670", "117673", "117674", "117675", "117676", "117677", "117679", "117680", "117687", "117689", "117690", "117691", "117692", "117694", "117695", "117696", "117698", "117701", "117702", "117704", "117708", "117709", "117710", "117712", "117713", "117715", "117718", "117721", "117727", "117728", "117730", "117732", "117733", "117734", "117735", "117739", "117740", "117741", "117742", "117746", "117751", "117753", "117755", "117756", "117761", "117762", "117763", "117764", "117767", "117768", "117769", "117770", "117772", "117773", "117774", "117777", "117782", "117784", "117789", "117790", "117792", "117793", "117796", "117800", "117801", "117802", "117803", "117807", "117808", "117811", "117812", "117813", "117814", "117820", "117822", "117823", "117825", "117826", "117828", "117833", "117834", "117836", "117837", "117839", "117842", "117843", "117845", "117846", "117848", "117849", "117850", "117853", "117854", "117855", "117856", "117858", "117859", "117860", "117863", "117864", "117868", "117869", "117870", "117874", "117875", "117876", "117882", "117884", "117885", "117886", "117888", "117889", "117892", "117895", "117898", "117901", "117903", "117904", "117906", "117908", "117910", "117911", "117913", "117914", "117916", "117917", "117918", "117919", "117920", "117921", "117923", "117924", "117926", "117927", "117928", "117930", "117932", "117934", "117936", "117938", "117939", "117940", "117941", "117944", "117946", "117949", "117952", "117957", "117958", "117960", "117962", "117963", "117966", "117967", "117968", "117970", "117974", "117976", "117977", "117978", "117982", "117984", "117987", "117988", "117989", "117991", "117993", "117994", "117998", "117999", "118000", "118001", "118002", "118008", "118009", "118014", "118020", "118024", "118026", "118029", "118031", "118033", "118034", "118036", "118037", "118038", "118039", "118041", "118046", "118048", "118053", "118054", "118057", "118058", "118059", "118060", "118061", "118062", "118063", "118064", "118065", "118067", "118071", "118072", "118074", "118078", "118079", "118080", "118081", "118082", "118083", "118085", "118087", "118088", "118092", "118094", "118095", "118096", "118098", "118100", "118102", "118103", "118104", "118105", "118109", "118111", "118112", "118113", "118114", "118115", "118116", "118119", "118121", "118122", "118124", "118126", "118128", "118129", "118130", "118135", "118136", "118138", "118140", "118141", "118142", "118143", "118144", "118145", "118146", "118147", "118148", "118150", "118151", "118156", "118157", "118160", "118161", "118163", "118164", "118165", "118167", "118168", "118169", "118170", "118171", "118174", "118176", "118181", "118182", "118183", "118185", "118186", "118188", "118189", "118191", "118192", "118194", "118195", "118196", "118197", "118198", "118199", "118200", "118201", "118202", "118203", "118204", "118207", "118209", "118210", "118212", "118214", "118216", "118217", "118220", "118224", "118226", "118227", "118228", "118229", "118230", "118231", "118232", "118234", "118244", "118246", "118250", "118256", "118257", "118259", "118260", "118268", "118271", "118272", "118273", "118275", "118277", "118280", "118281", "118282", "118283", "118284", "118286", "118287", "118289", "118292", "118294", "118295", "118299", "118300", "118302", "118303", "118304", "118306", "118308", "118312", "118313", "118314", "118315", "118316", "118318", "118321", "118324", "118326", "118329", "118335", "118338", "118339", "118342", "118345", "118346", "118347", "118348", "118349", "118351", "118353", "118355", "118358", "118359", "118360", "118364", "118366", "118368", "118369", "118372", "118377", "118379", "118380", "118381", "118382", "118383", "118385", "118386", "118388", "118389", "118391", "118392", "118395", "118396", "118397", "118399", "118400", "118401", "118402", "118404", "118407", "118408", "118409", "118410", "118411", "118412", "118413", "118414", "118415", "118417", "118419", "118421", "118422", "118424", "118425", "118426", "118430", "118432", "118435", "118438", "118439", "118444", "118445", "118448", "118449", "118453", "118455", "118457", "118459", "118462", "118466", "118468", "118470", "118471", "118482", "118485", "118487", "118488", "118489", "118490", "118491", "118492", "118496", "118501", "118502", "118503", "118504", "118506", "118507", "118511", "118512", "118513", "118514", "118519", "118526", "118527", "118530", "118533", "118535", "118537", "118538", "118539", "118540", "118541", "118542", "118546", "118547", "118549", "118551", "118558", "118564", "118570", "118575", "118576", "118578", "118580", "118582", "118585", "118586", "118587", "118591", "118592", "118597", "118598", "118600", "118601", "118604", "118606", "118608", "118615", "118616", "118617", "118619", "118622", "118625", "118626", "118627", "118630", "118631", "118634", "118635", "118636", "118637", "118638", "118639", "118642", "118643", "118647", "118648", "118651", "118656", "118659", "118660", "118663", "118664", "118665", "118666", "118667", "118669", "118670", "118671", "118672", "118673", "118674", "118676", "118679", "118684", "118687", "118690", "118692", "118695", "118697", "118698", "118703", "118704", "118705", "118707", "118709", "118710", "118714", "118717", "118718", "118721", "118722", "118726", "118727", "118730", "118731", "118734", "118736", "118740", "118741", "118742", "118745", "118746", "118748", "118750", "118753", "118754", "118763", "118764", "118767", "118768", "118769", "118776", "118777", "118778", "118782", "118783", "118785", "118786", "118789", "118794", "118796", "118798", "118799", "118800", "118801", "118806", "118808", "118809", "118812", "118814", "118815", "118816", "118817", "118819", "118821", "118823", "118826", "118832", "118834", "118838", "118839", "118840", "118843", "118848", "118850", "118853", "118855", "118857", "118862", "118863", "118865", "118867", "118868", "118869", "118871", "118872", "118874", "118875", "118876", "118877", "118879", "118880", "118881", "118883", "118887", "118892", "118893", "118894", "118895", "118896", "118897", "118898", "118899", "118901", "118903", "118905", "118906", "118909", "118910", "118911", "118912", "118913", "118915", "118918", "118919", "118920", "118922", "118924", "118927", "118928", "118932", "118936", "118937", "118938", "118940", "118941", "118942", "118943", "118945", "118949", "118951", "118952", "118953", "118954", "118956", "118957", "118958", "118961", "118963", "118966", "118969", "118970", "118971", "118972", "118973", "118974", "118978", "118980", "118982", "118986", "118987", "118991", "118993", "118994", "118995", "118996", "119001", "119003", "119004", "119005", "119007", "119009", "119010", "119011", "119017", "119018", "119019", "119020", "119025", "119027", "119028", "119029", "119031", "119033", "119038", "119039", "119040", "119043", "119047", "119049", "119053", "119054", "119055", "119058", "119061", "119062", "119063", "119066", "119068", "119071", "119072", "119073", "119075", "119076", "119079", "119082", "119083", "119086", "119087", "119088", "119089", "119093", "119094", "119095", "119096", "119098", "119099", "119101", "119103", "119104", "119105", "119106", "119107", "119109", "119110", "119112", "119114", "119118", "119119", "119120", "119122", "119123", "119126", "119129", "119130", "119132", "119135", "119136", "119141", "119142", "119143", "119145", "119146", "119151", "119154", "119155", "119156", "119157", "119160", "119161", "119163", "119165", "119171", "119174", "119175", "119176", "119178", "119179", "119182", "119184", "119185", "119186", "119187", "119188", "119192", "119193", "119199", "119201", "119204", "119206", "119209", "119210", "119211", "119213", "119215", "119218", "119220", "119221", "119223", "119225", "119226", "119227", "119228", "119233", "119236", "119239", "119240", "119242", "119243", "119245", "119246", "119247", "119255", "119256", "119257", "119259", "119260", "119263", "119266", "119267", "119268", "119271", "119272", "119275", "119277", "119278", "119279", "119281", "119282", "119286", "119288", "119290", "119292", "119295", "119296", "119301", "119302", "119304", "119308", "119309", "119313", "119314", "119315", "119316", "119317", "119320", "119321", "119323", "119325", "119326", "119330", "119331", "119334", "119336", "119337", "119338", "119339", "119340", "119341", "119344", "119345", "119347", "119348", "119349", "119351", "119352", "119353", "119354", "119355", "119358", "119361", "119362", "119365", "119370", "119372", "119375", "119376", "119381", "119382", "119383", "119391", "119393", "119394", "119399", "119401", "119402", "119403", "119404", "119405", "119407", "119410", "119412", "119415", "119419", "119425", "119427", "119429", "119431", "119434", "119435", "119436", "119437", "119438", "119439", "119441", "119442", "119444", "119445", "119446", "119448", "119451", "119452", "119454", "119455", "119461", "119462", "119463", "119465", "119467", "119468", "119470", "119471", "119474", "119477", "119478", "119480", "119483", "119488", "119489", "119491", "119493", "119495", "119499", "119500", "119501", "119505", "119507", "119510", "119511", "119512", "119514", "119515", "119518", "119519", "119521", "119522", "119525", "119528", "119530", "119531", "119532", "119533", "119534", "119538", "119539", "119541", "119542", "119543", "119545", "119547", "119548", "119549", "119550", "119552", "119555", "119556", "119564", "119565", "119568", "119569", "119572", "119574", "119578", "119579", "119581", "119584", "119585", "119586", "119587", "119590", "119594", "119595", "119598", "119602", "119605", "119608", "119611", "119612", "119613", "119615", "119620", "119621", "119624", "119628", "119629", "119630", "119631", "119632", "119633", "119634", "119636", "119640", "119641", "119642", "119643", "119644", "119646", "119648", "119650", "119652", "119653", "119654", "119655", "119656", "119657", "119658", "119659", "119661", "119663", "119664", "119666", "119667", "119668", "119671", "119674", "119676", "119677", "119680", "119685", "119690", "119692", "119693", "119695", "119699", "119704", "119705", "119706", "119707", "119708", "119712", "119718", "119721", "119722", "119723", "119728", "119729", "119733", "119734", "119736", "119737", "119741", "119744", "119748", "119749", "119751", "119757", "119760", "119763", "119765", "119767", "119770", "119773", "119774", "119776", "119777", "119779", "119780", "119781", "119782", "119790", "119792", "119793", "119797", "119800", "119803", "119804", "119806", "119807", "119809", "119810", "119813", "119815", "119822", "119824", "119825", "119827", "119829", "119831", "119834", "119835", "119837", "119838", "119840", "119843", "119846", "119848", "119849", "119850", "119851", "119854", "119858", "119861", "119863", "119866", "119867", "119870", "119871", "119872", "119876", "119881", "119882", "119883", "119890", "119891", "119894", "119895", "119899", "119900", "119902", "119906", "119907", "119909", "119911", "119915", "119916", "119917", "119919", "119920", "119921", "119924", "119926", "119929", "119932", "119937", "119939", "119940", "119943", "119946", "119947", "119949", "119950", "119952", "119956", "119959", "119960", "119961", "119962", "119963", "119965", "119969", "119973", "119974", "119976", "119977", "119978", "119980", "119982", "119983", "119984", "119985", "119987", "119989", "119991", "119992", "119993", "119994", "119995", "119996", "119997", "119998", "119999", "120000", "120003", "120004", "120007", "120008", "120013", "120014", "120016", "120017", "120020", "120022", "120023", "120027", "120028", "120029", "120031", "120033", "120035", "120036", "120038", "120039", "120041", "120044", "120046", "120047", "120048", "120049", "120053", "120054", "120055", "120059", "120060", "120061", "120062", "120063", "120064", "120065", "120069", "120070", "120071", "120073", "120075", "120077", "120080", "120081", "120082", "120086", "120089", "120090", "120091", "120092", "120093", "120095", "120096", "120098", "120100", "120102", "120103", "120105", "120106", "120108", "120109", "120110", "120113", "120114", "120115", "120116", "120117", "120118", "120119", "120121", "120124", "120125", "120126", "120130", "120131", "120132", "120137", "120144", "120146", "120147", "120148", "120150", "120151", "120156", "120157", "120159", "120164", "120165", "120168", "120169", "120172", "120173", "120175", "120176", "120179", "120180", "120181", "120184", "120185", "120188", "120189", "120191", "120192", "120193", "120197", "120198", "120200", "120202", "120203", "120204", "120205", "120206", "120207", "120216", "120218", "120219", "120220", "120221", "120223", "120225", "120227", "120233", "120234", "120237", "120238", "120239", "120240", "120242", "120243", "120244", "120245", "120246", "120249", "120253", "120254", "120255", "120256", "120260", "120261", "120262", "120265", "120266", "120275", "120277", "120278", "120280", "120281", "120283", "120284", "120286", "120287", "120288", "120289", "120293", "120294", "120296", "120298", "120299", "120303", "120305", "120306", "120309", "120310", "120312", "120315", "120316", "120317", "120320", "120321", "120324", "120325", "120327", "120328", "120329", "120330", "120332", "120333", "120334", "120336", "120339", "120340", "120345", "120346", "120349", "120351", "120352", "120353", "120355", "120356", "120357", "120358", "120359", "120360", "120361", "120364", "120370", "120371", "120372", "120373", "120377", "120378", "120381", "120383", "120386", "120387", "120388", "120390", "120392", "120394", "120395", "120396", "120397", "120399", "120404", "120405", "120406", "120407", "120408", "120412", "120413", "120415", "120418", "120420", "120421", "120422", "120423", "120425", "120428", "120432", "120435", "120438", "120441", "120444", "120445", "120449", "120450", "120453", "120454", "120455", "120456", "120458", "120459", "120461", "120462", "120463", "120464", "120465", "120468", "120469", "120471", "120475", "120477", "120478", "120480", "120484", "120485", "120487", "120488", "120491", "120496", "120497", "120498", "120500", "120502", "120503", "120504", "120508", "120509", "120516", "120517", "120519", "120521", "120522", "120524", "120525", "120526", "120528", "120530", "120533", "120536", "120538", "120539", "120541", "120542", "120543", "120544", "120545", "120547", "120548", "120550", "120551", "120552", "120554", "120556", "120558", "120560", "120562", "120563", "120564", "120566", "120567", "120569", "120571", "120574", "120575", "120579", "120580", "120582", "120584", "120587", "120588", "120592", "120601", "120603", "120604", "120608", "120614", "120616", "120617", "120618", "120620", "120621", "120623", "120624", "120626", "120628", "120630", "120631", "120636", "120643", "120645", "120646", "120647", "120650", "120651", "120652", "120654", "120657", "120658", "120659", "120660", "120661", "120662", "120665", "120671", "120673", "120675", "120676", "120678", "120686", "120687", "120690", "120691", "120696", "120699", "120700", "120701", "120702", "120704", "120705", "120706", "120708", "120710", "120713", "120715", "120717", "120718", "120720", "120722", "120723", "120725", "120726", "120727", "120729", "120731", "120732", "120733", "120734", "120735", "120737", "120738", "120743", "120746", "120749", "120750", "120754", "120757", "120760", "120762", "120764", "120766", "120767", "120773", "120774", "120775", "120779", "120780", "120783", "120785", "120788", "120789", "120790", "120801", "120805", "120807", "120809", "120810", "120813", "120814", "120816", "120817", "120822", "120825", "120826", "120827", "120829", "120833", "120836", "120837", "120839", "120841", "120842", "120843", "120844", "120847", "120848", "120849", "120850", "120851", "120853", "120855", "120856", "120861", "120863", "120867", "120870", "120873", "120874", "120877", "120878", "120881", "120883", "120886", "120887", "120889", "120890", "120891", "120893", "120894", "120895", "120900", "120902", "120904", "120905", "120906", "120907", "120908", "120910", "120911", "120912", "120913", "120914", "120915", "120916", "120917", "120921", "120928", "120929", "120930", "120932", "120933", "120935", "120938", "120941", "120942", "120943", "120944", "120946", "120947", "120950", "120951", "120952", "120954", "120955", "120956", "120958", "120960", "120961", "120962", "120964", "120965", "120973", "120974", "120975", "120976", "120977", "120978", "120980", "120981", "120982", "120983", "120984", "120985", "120986", "120989", "120990", "120993", "120996", "120998", "120999", "121000", "121002", "121004", "121011", "121012", "121015", "121016", "121018", "121021", "121024", "121025", "121026", "121029", "121030", "121031", "121034", "121037", "121039", "121040", "121041", "121042", "121044", "121045", "121046", "121047", "121049", "121051", "121058", "121065", "121066", "121067", "121070", "121071", "121073", "121074", "121083", "121086", "121090", "121091", "121094", "121095", "121097", "121100", "121102", "121108", "121110", "121111", "121113", "121118", "121120", "121122", "121124", "121126", "121127", "121128", "121129", "121132", "121134", "121135", "121136", "121138", "121139", "121140", "121141", "121146", "121149", "121151", "121153", "121154", "121157", "121161", "121163", "121166", "121167", "121168", "121169", "121171", "121172", "121173", "121174", "121176", "121177", "121178", "121179", "121181", "121182", "121185", "121189", "121192", "121193", "121194", "121195", "121196", "121197", "121200", "121205", "121209", "121211", "121212", "121216", "121218", "121220", "121224", "121227", "121229", "121230", "121231", "121232", "121235", "121236", "121238", "121239", "121241", "121243", "121244", "121249", "121250", "121251", "121254", "121256", "121257", "121258", "121260", "121261", "121262", "121263", "121269", "121274", "121275", "121276", "121277", "121278", "121280", "121283", "121284", "121286", "121288", "121290", "121291", "121293", "121295", "121296", "121298", "121299", "121302", "121309", "121312", "121313", "121314", "121315", "121316", "121317", "121318", "121320", "121321", "121325", "121326", "121328", "121329", "121331", "121335", "121336", "121341", "121342", "121344", "121345", "121348", "121351", "121354", "121355", "121356", "121358", "121360", "121362", "121363", "121364", "121369", "121372", "121375", "121379", "121380", "121381", "121382", "121383", "121384", "121385", "121386", "121387", "121388", "121389", "121390", "121392", "121395", "121398", "121399", "121400", "121401", "121403", "121406", "121407", "121408", "121409", "121410", "121414", "121416", "121419", "121420", "121421", "121422", "121424", "121425", "121426", "121427", "121429", "121430", "121431", "121435", "121438", "121442", "121444", "121446", "121452", "121453", "121454", "121457", "121459", "121460", "121461", "121463", "121464", "121467", "121468", "121472", "121476", "121477", "121480", "121482", "121484", "121485", "121488", "121489", "121491", "121492", "121494", "121495", "121498", "121502", "121503", "121505", "121507", "121517", "121518", "121519", "121522", "121524", "121527", "121528", "121531", "121532", "121534", "121535", "121537", "121538", "121539", "121540", "121542", "121543", "121544", "121546", "121548", "121550", "121551", "121552", "121554", "121555", "121557", "121558", "121560", "121561", "121562", "121565", "121566", "121567", "121568", "121571", "121575", "121576", "121577", "121578", "121579", "121580", "121582", "121583", "121584", "121586", "121587", "121588", "121590", "121591", "121592", "121594", "121596", "121597", "121598", "121599", "121600", "121601", "121602", "121604", "121606", "121608", "121609", "121610", "121612", "121613", "121617", "121619", "121622", "121625", "121626", "121627", "121628", "121634", "121635", "121636", "121637", "121638", "121639", "121641", "121644", "121645", "121646", "121650", "121651", "121652", "121656", "121659", "121660", "121662", "121663", "121664", "121665", "121669", "121670", "121671", "121676", "121677", "121678", "121681", "121686", "121687", "121688", "121689", "121691", "121693", "121695", "121696", "121697", "121698", "121699", "121701", "121703", "121705", "121706", "121708", "121709", "121710", "121711", "121712", "121715", "121716", "121717", "121718", "121721", "121722", "121724", "121725", "121728", "121729", "121731", "121732", "121734", "121736", "121738", "121739", "121741", "121742", "121744", "121745", "121750", "121751", "121753", "121756", "121758", "121767", "121768", "121769", "121770", "121772", "121773", "121776", "121777", "121778", "121779", "121783", "121785", "121787", "121789", "121790", "121791", "121793", "121799", "121806", "121808", "121810", "121811", "121813", "121814", "121818", "121819", "121821", "121823", "121826", "121828", "121829", "121833", "121834", "121836", "121837", "121839", "121840", "121842", "121843", "121844", "121848", "121850", "121851", "121852", "121853", "121854", "121856", "121860", "121865", "121873", "121874", "121875", "121876", "121877", "121878", "121880", "121886", "121888", "121890", "121891", "121892", "121894", "121895", "121899", "121901", "121903", "121904", "121906", "121907", "121908", "121909", "121911", "121914", "121915", "121916", "121917", "121918", "121921", "121922", "121930", "121931", "121932", "121935", "121937", "121939", "121942", "121943", "121945", "121953", "121956", "121958", "121961", "121963", "121966", "121968", "121970", "121972", "121973", "121974", "121978", "121979", "121981", "121982", "121989", "121990", "121993", "121995", "122000", "122001", "122003", "122004", "122005", "122007", "122012", "122013", "122014", "122016", "122018", "122020", "122021", "122022", "122023", "122024", "122026", "122030", "122032", "122035", "122036", "122037", "122038", "122040", "122041", "122043", "122045", "122046", "122051", "122052", "122054", "122055", "122056", "122057", "122060", "122061", "122064", "122066", "122068", "122069", "122072", "122074", "122076", "122080", "122082", "122084", "122089", "122090", "122091", "122092", "122096", "122100", "122103", "122104", "122108", "122109", "122110", "122111", "122115", "122116", "122117", "122118", "122124", "122125", "122128", "122131", "122133", "122134", "122136", "122138", "122139", "122140", "122142", "122143", "122145", "122146", "122147", "122148", "122149", "122150", "122151", "122153", "122154", "122156", "122161", "122163", "122165", "122166", "122167", "122168", "122169", "122172", "122175", "122178", "122179", "122181", "122182", "122184", "122187", "122189", "122190", "122191", "122192", "122194", "122197", "122199", "122202", "122203", "122204", "122206", "122207", "122208", "122209", "122210", "122211", "122212", "122214", "122216", "122219", "122221", "122224", "122225", "122227", "122231", "122233", "122234", "122236", "122238", "122241", "122243", "122250", "122251", "122252", "122254", "122255", "122257", "122260", "122262", "122263", "122264", "122265", "122268", "122269", "122270", "122274", "122275", "122278", "122280", "122281", "122283", "122284", "122285", "122286", "122289", "122292", "122294", "122295", "122296", "122297", "122299", "122300", "122302", "122305", "122307", "122310", "122313", "122315", "122318", "122322", "122323", "122324", "122326", "122331", "122333", "122334", "122335", "122336", "122342", "122346", "122347", "122349", "122353", "122355", "122362", "122363", "122364", "122365", "122366", "122367", "122369", "122370", "122373", "122376", "122378", "122379", "122380", "122381", "122383", "122384", "122385", "122386", "122387", "122389", "122390", "122392", "122394", "122395", "122396", "122397", "122398", "122401", "122402", "122404", "122405", "122406", "122407", "122411", "122413", "122417", "122419", "122420", "122421", "122422", "122423", "122424", "122425", "122427", "122428", "122430", "122431", "122433", "122438", "122439", "122441", "122447", "122448", "122450", "122452", "122453", "122454", "122455", "122461", "122463", "122464", "122465", "122468", "122470", "122473", "122477", "122478", "122479", "122481", "122482", "122483", "122484", "122485", "122489", "122491", "122493", "122494", "122496", "122497", "122498", "122499", "122500", "122501", "122504", "122507", "122508", "122509", "122510", "122513", "122514", "122515", "122516", "122517", "122518", "122524", "122526", "122527", "122528", "122530", "122533", "122534", "122536", "122537", "122539", "122541", "122543", "122544", "122545", "122546", "122547", "122548", "122550", "122553", "122554", "122557", "122558", "122560", "122565", "122566", "122567", "122568", "122570", "122572", "122573", "122577", "122578", "122579", "122581", "122583", "122584", "122588", "122590", "122594", "122597", "122599", "122603", "122604", "122606", "122609", "122610", "122611", "122615", "122616", "122617", "122619", "122621", "122624", "122627", "122630", "122631", "122632", "122633", "122634", "122636", "122638", "122640", "122641", "122642", "122643", "122645", "122646", "122647", "122648", "122649", "122650", "122651", "122652", "122655", "122656", "122657", "122658", "122659", "122661", "122662", "122664", "122665", "122666", "122669", "122674", "122676", "122678", "122681", "122684", "122689", "122694", "122697", "122698", "122699", "122701", "122702", "122703", "122705", "122706", "122708", "122711", "122712", "122713", "122714", "122717", "122718", "122719", "122720", "122722", "122724", "122726", "122729", "122731", "122732", "122733", "122734", "122743", "122746", "122747", "122748", "122750", "122753", "122756", "122757", "122759", "122760", "122761", "122763", "122765", "122767", "122771", "122773", "122774", "122775", "122777", "122779", "122788", "122789", "122790", "122791", "122792", "122793", "122796", "122797", "122801", "122806", "122810", "122811", "122812", "122813", "122815", "122817", "122822", "122823", "122824", "122825", "122826", "122828", "122829", "122834", "122835", "122838", "122839", "122840", "122842", "122843", "122844", "122845", "122846", "122852", "122853", "122855", "122857", "122858", "122859", "122860", "122862", "122863", "122864", "122866", "122870", "122871", "122873", "122876", "122882", "122884", "122887", "122889", "122891", "122895", "122896", "122897", "122900", "122901", "122903", "122905", "122906", "122909", "122911", "122913", "122915", "122917", "122921", "122922", "122924", "122926", "122929", "122931", "122934", "122935", "122937", "122938", "122939", "122941", "122942", "122943", "122946", "122947", "122952", "122954", "122955", "122956", "122957", "122958", "122960", "122961", "122967", "122968", "122970", "122971", "122973", "122974", "122978", "122979", "122981", "122983", "122984", "122985", "122987", "122989", "122990", "122991", "122993", "122995", "122996", "122997", "123002", "123003", "123005", "123010", "123013", "123014", "123017", "123020", "123026", "123027", "123028", "123030", "123032", "123034", "123036", "123037", "123041", "123042", "123043", "123046", "123048", "123052", "123053", "123055", "123057", "123061", "123063", "123064", "123065", "123066", "123068", "123073", "123074", "123075", "123076", "123077", "123078", "123086", "123088", "123089", "123090", "123092", "123093", "123094", "123097", "123106", "123107", "123108", "123109", "123111", "123118", "123119", "123120", "123121", "123122", "123123", "123124", "123125", "123130", "123132", "123134", "123135", "123136", "123141", "123144", "123146", "123148", "123149", "123152", "123153", "123157", "123158", "123160", "123161", "123165", "123170", "123171", "123172", "123178", "123179", "123180", "123181", "123183", "123184", "123187", "123191", "123195", "123196", "123199", "123201", "123205", "123206", "123208", "123214", "123215", "123216", "123223", "123224", "123225", "123226", "123227", "123229", "123230", "123238", "123239", "123240", "123241", "123242", "123244", "123245", "123247", "123248", "123254", "123255", "123256", "123257", "123258", "123259", "123261", "123262", "123268", "123269", "123272", "123274", "123275", "123279", "123280", "123282", "123283", "123284", "123285", "123287", "123291", "123292", "123293", "123294", "123300", "123301", "123302", "123304", "123308", "123310", "123312", "123313", "123317", "123318", "123319", "123322", "123324", "123326", "123327", "123329", "123330", "123333", "123334", "123336", "123337", "123341", "123344", "123345", "123346", "123347", "123353", "123356", "123358", "123359", "123360", "123362", "123363", "123364", "123368", "123376", "123377", "123379", "123383", "123384", "123386", "123387", "123389", "123393", "123395", "123396", "123397", "123398", "123399", "123400", "123406", "123408", "123410", "123412", "123414", "123415", "123420", "123421", "123424", "123427", "123428", "123434", "123443", "123448", "123449", "123451", "123453", "123455", "123457", "123459", "123461", "123462", "123464", "123465", "123466", "123468", "123469", "123472", "123473", "123474", "123476", "123477", "123478", "123480", "123482", "123487", "123488", "123489", "123491", "123495", "123500", "123504", "123505", "123507", "123509", "123510", "123512", "123513", "123515", "123518", "123519", "123520", "123523", "123524", "123526", "123528", "123529", "123531", "123532", "123533", "123534", "123535", "123537", "123538", "123539", "123541", "123542", "123543", "123546", "123548", "123549", "123552", "123554", "123562", "123564", "123566", "123567", "123569", "123571", "123572", "123575", "123576", "123578", "123579", "123582", "123583", "123584", "123585", "123587", "123588", "123589", "123599", "123600", "123601", "123603", "123604", "123605", "123609", "123610", "123612", "123613", "123614", "123615", "123616", "123618", "123621", "123622", "123628", "123629", "123633", "123636", "123638", "123641", "123646", "123649", "123650", "123652", "123653", "123657", "123658", "123662", "123664", "123665", "123666", "123667", "123671", "123673", "123674", "123679", "123682", "123683", "123685", "123686", "123687", "123689", "123691", "123692", "123693", "123694", "123695", "123696", "123698", "123700", "123703", "123706", "123708", "123709", "123714", "123716", "123719", "123726", "123730", "123731", "123733", "123739", "123740", "123744", "123745", "123747", "123748", "123750", "123751", "123752", "123753", "123755", "123759", "123762", "123766", "123772", "123773", "123774", "123777", "123779", "123780", "123781", "123782", "123783", "123787", "123788", "123789", "123795", "123796", "123797", "123798", "123801", "123802", "123803", "123805", "123807", "123808", "123809", "123810", "123811", "123813", "123819", "123820", "123821", "123823", "123826", "123828", "123829", "123830", "123831", "123835", "123836", "123839", "123844", "123845", "123846", "123848", "123852", "123853", "123854", "123855", "123858", "123862", "123863", "123864", "123865", "123867", "123869", "123870", "123871", "123873", "123880", "123882", "123883", "123885", "123886", "123890", "123891", "123895", "123897", "123898", "123901", "123907", "123908", "123910", "123912", "123913", "123915", "123919", "123924", "123925", "123926", "123927", "123928", "123930", "123931", "123932", "123933", "123934", "123935", "123937", "123938", "123939", "123941", "123942", "123943", "123944", "123945", "123946", "123948", "123949", "123950", "123951", "123952", "123953", "123954", "123955", "123960", "123964", "123965", "123966", "123967", "123968", "123971", "123972", "123973", "123974", "123976", "123979", "123983", "123984", "123985", "123989", "123991", "123994", "123995", "123998", "124004", "124006", "124007", "124008", "124009", "124011", "124012", "124016", "124019", "124021", "124022", "124023", "124024", "124027", "124028", "124030", "124031", "124034", "124036", "124039", "124040", "124041", "124042", "124044", "124046", "124047", "124052", "124053", "124057", "124059", "124060", "124061", "124062", "124064", "124068", "124071", "124073", "124074", "124075", "124077", "124079", "124080", "124081", "124086", "124089", "124091", "124092", "124095", "124096", "124097", "124098", "124099", "124101", "124103", "124104", "124106", "124107", "124108", "124109", "124110", "124111", "124113", "124116", "124121", "124126", "124127", "124128", "124131", "124134", "124135", "124136", "124138", "124140", "124141", "124145", "124146", "124148", "124149", "124150", "124152", "124153", "124155", "124158", "124159", "124160", "124161", "124162", "124165", "124170", "124172", "124178", "124180", "124181", "124182", "124188", "124190", "124191", "124192", "124197", "124199", "124202", "124203", "124205", "124206", "124208", "124210", "124212", "124213", "124214", "124216", "124217", "124219", "124220", "124221", "124222", "124224", "124229", "124234", "124238", "124240", "124242", "124245", "124246", "124247", "124248", "124254", "124256", "124257", "124258", "124259", "124260", "124261", "124262", "124267", "124270", "124273", "124275", "124276", "124279", "124280", "124281", "124282", "124288", "124290", "124293", "124295", "124296", "124297", "124299", "124302", "124303", "124305", "124307", "124308", "124311", "124314", "124316", "124317", "124319", "124322", "124331", "124334", "124337", "124338", "124339", "124340", "124342", "124344", "124346", "124348", "124349", "124350", "124352", "124355", "124360", "124361", "124362", "124363", "124369", "124373", "124374", "124381", "124384", "124388", "124390", "124392", "124394", "124395", "124403", "124405", "124406", "124407", "124410", "124417", "124419", "124421", "124424", "124425", "124427", "124434", "124435", "124438", "124439", "124440", "124441", "124442", "124443", "124444", "124445", "124448", "124450", "124451", "124452", "124453", "124455", "124457", "124461", "124465", "124466", "124467", "124470", "124471", "124472", "124473", "124474", "124476", "124477", "124480", "124483", "124484", "124485", "124486", "124489", "124495", "124500", "124502", "124503", "124506", "124508", "124511", "124513", "124517", "124521", "124522", "124523", "124524", "124525", "124528", "124529", "124532", "124533", "124538", "124539", "124542", "124543", "124544", "124545", "124546", "124551", "124552", "124554", "124555", "124556", "124558", "124560", "124561", "124563", "124564", "124566", "124567", "124568", "124572", "124575", "124577", "124578", "124580", "124582", "124584", "124588", "124589", "124594", "124596", "124598", "124603", "124604", "124610", "124611", "124612", "124620", "124621", "124623", "124624", "124626", "124627", "124629", "124632", "124633", "124636", "124638", "124639", "124641", "124642", "124643", "124645", "124647", "124648", "124649", "124650", "124651", "124652", "124653", "124654", "124657", "124658", "124659", "124662", "124663", "124664", "124667", "124671", "124672", "124677", "124680", "124682", "124684", "124685", "124686", "124687", "124688", "124691", "124692", "124693", "124694", "124695", "124696", "124699", "124702", "124703", "124706", "124710", "124713", "124714", "124715", "124716", "124717", "124719", "124720", "124722", "124723", "124724", "124725", "124726", "124727", "124728", "124729", "124734", "124736", "124739", "124740", "124747", "124750", "124755", "124760", "124764", "124765", "124766", "124767", "124770", "124772", "124773", "124776", "124779", "124783", "124784", "124786", "124787", "124788", "124789", "124790", "124791", "124793", "124795", "124799", "124805", "124808", "124810", "124813", "124814", "124815", "124817", "124818", "124819", "124820", "124822", "124823", "124824", "124828", "124830", "124832", "124834", "124836", "124844", "124845", "124846", "124847", "124849", "124850", "124852", "124856", "124857", "124860", "124862", "124863", "124864", "124865", "124867", "124868", "124870", "124873", "124876", "124877", "124878", "124887", "124888", "124891", "124894", "124895", "124897", "124902", "124905", "124907", "124910", "124914", "124915", "124916", "124917", "124918", "124922", "124923", "124924", "124926", "124928", "124932", "124935", "124937", "124944", "124947", "124949", "124951", "124952", "124955", "124957", "124958", "124961", "124963", "124964", "124966", "124967", "124970", "124971", "124973", "124974", "124977", "124979", "124980", "124982", "124986", "124987", "124991", "124993", "124996", "124997", "124999", "125000", "125004", "125006", "125008", "125011", "125013", "125016", "125017", "125018", "125022", "125025", "125028", "125029", "125030", "125032", "125033", "125036", "125037", "125041", "125044", "125045", "125047", "125049", "125052", "125054", "125055", "125056", "125057", "125058", "125059", "125060", "125065", "125066", "125067", "125068", "125070", "125071", "125072", "125074", "125075", "125079", "125080", "125082", "125088", "125094", "125097", "125101", "125102", "125105", "125106", "125109", "125111", "125114", "125115", "125118", "125124", "125125", "125128", "125131", "125135", "125137", "125138", "125140", "125143", "125146", "125150", "125153", "125155", "125159", "125160", "125161", "125164", "125166", "125167", "125168", "125169", "125170", "125173", "125174", "125175", "125178", "125179", "125181", "125182", "125183", "125188", "125190", "125191", "125192", "125193", "125197", "125198", "125199", "125202", "125205", "125208", "125209", "125211", "125218", "125219", "125220", "125222", "125223", "125224", "125225", "125227", "125228", "125229", "125230", "125231", "125232", "125238", "125243", "125244", "125248", "125250", "125251", "125254", "125255", "125259", "125262", "125263", "125268", "125271", "125274", "125277", "125281", "125282", "125283", "125285", "125286", "125288", "125290", "125291", "125292", "125295", "125296", "125297", "125298", "125299", "125302", "125303", "125304", "125305", "125306", "125307", "125312", "125313", "125314", "125315", "125319", "125320", "125322", "125323", "125324", "125325", "125328", "125329", "125332", "125338", "125342", "125344", "125345", "125346", "125348", "125349", "125352", "125354", "125355", "125356", "125357", "125358", "125360", "125362", "125363", "125364", "125366", "125367", "125368", "125369", "125370", "125372", "125373", "125376", "125378", "125381", "125383", "125385", "125388", "125391", "125392", "125394", "125395", "125396", "125398", "125400", "125401", "125405", "125409", "125410", "125411", "125412", "125413", "125414", "125415", "125417", "125418", "125419", "125420", "125423", "125424", "125425", "125426", "125430", "125431", "125432", "125433", "125434", "125435", "125436", "125437", "125439", "125442", "125449", "125450", "125451", "125453", "125454", "125459", "125460", "125461", "125462", "125464", "125467", "125468", "125470", "125471", "125473", "125474", "125475", "125476", "125477", "125478", "125480", "125481", "125486", "125488", "125489", "125498", "125500", "125503", "125506", "125508", "125509", "125511", "125512", "125513", "125514", "125517", "125519", "125521", "125526", "125529", "125532", "125533", "125535", "125542", "125544", "125545", "125546", "125547", "125550", "125551", "125553", "125554", "125557", "125558", "125561", "125563", "125564", "125565", "125566", "125569", "125572", "125573", "125576", "125578", "125579", "125581", "125582", "125587", "125588", "125589", "125590", "125591", "125593", "125594", "125597", "125598", "125599", "125601", "125602", "125604", "125605", "125606", "125608", "125609", "125610", "125617", "125619", "125621", "125622", "125623", "125625", "125626", "125627", "125629", "125633", "125637", "125638", "125639", "125640", "125642", "125643", "125644", "125646", "125650", "125652", "125654", "125657", "125659", "125660", "125661", "125663", "125664", "125666", "125668", "125671", "125672", "125673", "125675", "125678", "125680", "125683", "125684", "125687", "125689", "125690", "125694", "125695", "125696", "125697", "125700", "125701", "125703", "125706", "125711", "125712", "125714", "125715", "125717", "125718", "125719", "125720", "125721", "125722", "125725", "125729", "125731", "125732", "125733", "125739", "125740", "125741", "125746", "125747", "125749", "125753", "125755", "125757", "125760", "125761", "125765", "125768", "125769", "125772", "125774", "125775", "125777", "125778", "125779", "125780", "125783", "125784", "125785", "125786", "125788", "125790", "125791", "125794", "125795", "125797", "125798", "125800", "125802", "125803", "125805", "125806", "125808", "125809", "125811", "125814", "125815", "125816", "125817", "125824", "125825", "125826", "125828", "125831", "125833", "125836", "125837", "125839", "125841", "125842", "125843", "125844", "125845", "125847", "125848", "125851", "125855", "125856", "125858", "125860", "125863", "125866", "125867", "125868", "125870", "125871", "125873", "125876", "125877", "125878", "125880", "125882", "125884", "125887", "125888", "125890", "125893", "125895", "125896", "125898", "125900", "125901", "125904", "125905", "125907", "125908", "125910", "125912", "125916", "125917", "125921", "125923", "125925", "125926", "125927", "125929", "125930", "125931", "125932", "125933", "125938", "125940", "125941", "125942", "125944", "125949", "125950", "125953", "125955", "125956", "125961", "125962", "125963", "125965", "125968", "125969", "125970", "125978", "125980", "125982", "125984", "125985", "125986", "125988", "125989", "125992", "125993", "125994", "125995", "125998", "126001", "126002", "126003", "126004", "126005", "126008", "126009", "126010", "126011", "126012", "126013", "126016", "126017", "126018", "126019", "126020", "126021", "126028", "126029", "126030", "126033", "126034", "126036", "126039", "126044", "126046", "126047", "126048", "126049", "126053", "126054", "126057", "126058", "126059", "126064", "126066", "126073", "126076", "126078", "126079", "126080", "126081", "126082", "126084", "126085", "126086", "126088", "126089", "126090", "126092", "126096", "126097", "126100", "126102", "126104", "126107", "126113", "126116", "126118", "126120", "126122", "126123", "126124", "126125", "126127", "126128", "126133", "126135", "126136", "126137", "126139", "126141", "126144", "126145", "126147", "126150", "126151", "126153", "126154", "126158", "126160", "126162", "126163", "126164", "126165", "126166", "126168", "126169", "126172", "126174", "126178", "126179", "126181", "126182", "126184", "126185", "126186", "126190", "126191", "126194", "126195", "126196", "126198", "126203", "126206", "126207", "126209", "126210", "126213", "126215", "126220", "126226", "126230", "126232", "126237", "126238", "126239", "126243", "126247", "126251", "126256", "126258", "126259", "126261", "126262", "126265", "126270", "126271", "126275", "126278", "126279", "126280", "126283", "126284", "126285", "126288", "126289", "126291", "126295", "126296", "126300", "126302", "126303", "126306", "126311", "126312", "126315", "126316", "126318", "126319", "126322", "126323", "126324", "126325", "126327", "126330", "126332", "126333", "126334", "126335", "126337", "126338", "126339", "126340", "126341", "126342", "126343", "126344", "126345", "126346", "126349", "126350", "126353", "126359", "126363", "126364", "126367", "126370", "126371", "126372", "126376", "126377", "126383", "126384", "126386", "126389", "126390", "126392", "126393", "126395", "126396", "126397", "126398", "126401", "126402", "126404", "126407", "126409", "126410", "126412", "126414", "126417", "126418", "126419", "126420", "126421", "126422", "126424", "126427", "126428", "126429", "126430", "126431", "126432", "126435", "126436", "126440", "126441", "126444", "126445", "126450", "126452", "126453", "126454", "126458", "126459", "126461", "126465", "126468", "126469", "126474", "126477", "126478", "126488", "126489", "126490", "126494", "126499", "126502", "126504", "126505", "126506", "126508", "126509", "126510", "126512", "126513", "126514", "126517", "126520", "126523", "126524", "126526", "126528", "126529", "126530", "126531", "126534", "126535", "126536", "126537", "126539", "126540", "126541", "126542", "126543", "126546", "126547", "126550", "126552", "126555", "126556", "126560", "126561", "126563", "126565", "126566", "126568", "126571", "126575", "126576", "126577", "126578", "126579", "126584", "126585", "126587", "126589", "126590", "126593", "126597", "126598", "126601", "126602", "126603", "126604", "126606", "126607", "126610", "126615", "126617", "126622", "126623", "126627", "126628", "126631", "126633", "126634", "126635", "126637", "126640", "126646", "126647", "126650", "126655", "126656", "126657", "126660", "126662", "126663", "126664", "126666", "126667", "126669", "126670", "126673", "126674", "126676", "126677", "126680", "126687", "126688", "126694", "126697", "126700", "126701", "126702", "126703", "126704", "126708", "126709", "126712", "126715", "126716", "126719", "126721", "126722", "126723", "126730", "126733", "126734", "126735", "126741", "126743", "126744", "126749", "126750", "126753", "126754", "126757", "126759", "126760", "126761", "126763", "126764", "126766", "126768", "126769", "126770", "126771", "126774", "126777", "126780", "126782", "126784", "126788", "126790", "126793", "126796", "126797", "126800", "126802", "126803", "126805", "126807", "126809", "126810", "126812", "126813", "126817", "126820", "126823", "126830", "126832", "126833", "126834", "126837", "126838", "126840", "126842", "126846", "126847", "126848", "126852", "126853", "126854", "126857", "126858", "126860", "126862", "126863", "126864", "126866", "126867", "126868", "126871", "126872", "126873", "126874", "126875", "126877", "126878", "126880", "126881", "126885", "126888", "126891", "126892", "126894", "126896", "126900", "126902", "126903", "126904", "126906", "126907", "126910", "126911", "126913", "126917", "126924", "126925", "126929", "126931", "126934", "126937", "126940", "126941", "126942", "126944", "126946", "126948", "126954", "126955", "126959", "126960", "126961", "126962", "126963", "126966", "126967", "126968", "126969", "126970", "126971", "126972", "126973", "126975", "126977", "126978", "126979", "126983", "126984", "126985", "126986", "126987", "126990", "126993", "126994", "126995", "126998", "127000", "127005", "127008", "127009", "127010", "127011", "127012", "127013", "127014", "127018", "127019", "127020", "127022", "127026", "127027", "127028", "127030", "127031", "127033", "127034", "127035", "127036", "127037", "127039", "127040", "127042", "127045", "127046", "127049", "127050", "127054", "127055", "127057", "127058", "127060", "127062", "127063", "127064", "127065", "127068", "127071", "127072", "127073", "127074", "127076", "127077", "127078", "127079", "127080", "127081", "127082", "127093", "127095", "127096", "127105", "127106", "127107", "127108", "127109", "127110", "127111", "127112", "127114", "127115", "127119", "127120", "127123", "127129", "127130", "127131", "127134", "127135", "127136", "127138", "127140", "127141", "127142", "127143", "127145", "127146", "127147", "127150", "127152", "127156", "127159", "127161", "127162", "127165", "127170", "127171", "127174", "127175", "127178", "127183", "127184", "127185", "127187", "127190", "127191", "127192", "127195", "127196", "127198", "127200", "127201", "127204", "127205", "127206", "127209", "127210", "127212", "127214", "127215", "127218", "127224", "127228", "127229", "127231", "127235", "127236", "127238", "127239", "127240", "127241", "127248", "127251", "127252", "127253", "127257", "127261", "127262", "127265", "127267", "127272", "127273", "127274", "127275", "127276", "127277", "127281", "127284", "127285", "127286", "127287", "127288", "127290", "127291", "127293", "127295", "127296", "127298", "127299", "127300", "127303", "127304", "127305", "127306", "127307", "127308", "127310", "127311", "127312", "127313", "127314", "127315", "127316", "127318", "127320", "127321", "127324", "127325", "127327", "127328", "127329", "127333", "127335", "127336", "127341", "127342", "127343", "127344", "127345", "127346", "127347", "127348", "127349", "127351", "127352", "127353", "127354", "127359", "127360", "127367", "127368", "127371", "127372", "127373", "127374", "127378", "127379", "127380", "127382", "127383", "127386", "127387", "127390", "127391", "127396", "127398", "127399", "127400", "127401", "127403", "127404", "127405", "127406", "127409", "127411", "127412", "127413", "127414", "127415", "127416", "127417", "127420", "127421", "127423", "127427", "127428", "127430", "127432", "127434", "127436", "127438", "127439", "127442", "127443", "127444", "127448", "127449", "127450", "127451", "127452", "127457", "127458", "127459", "127461", "127462", "127463", "127466", "127468", "127475", "127478", "127480", "127489", "127490", "127491", "127492", "127493", "127495", "127496", "127500", "127504", "127505", "127511", "127512", "127513", "127514", "127516", "127522", "127523", "127524", "127525", "127527", "127529", "127530", "127531", "127532", "127533", "127534", "127538", "127540", "127541", "127542", "127545", "127548", "127549", "127551", "127553", "127556", "127561", "127563", "127564", "127565", "127567", "127568", "127569", "127574", "127577", "127578", "127579", "127580", "127581", "127582", "127583", "127588", "127590", "127591", "127592", "127593", "127595", "127596", "127598", "127601", "127604", "127607", "127608", "127609", "127610", "127614", "127617", "127620", "127622", "127623", "127624", "127629", "127630", "127632", "127634", "127636", "127638", "127640", "127641", "127642", "127646", "127647", "127649", "127651", "127652", "127653", "127654", "127655", "127656", "127657", "127660", "127662", "127663", "127665", "127666", "127670", "127673", "127676", "127677", "127682", "127683", "127684", "127686", "127693", "127695", "127698", "127700", "127702", "127703", "127705", "127706", "127707", "127708", "127709", "127711", "127712", "127714", "127716", "127722", "127723", "127725", "127730", "127731", "127732", "127733", "127735", "127744", "127747", "127750", "127751", "127752", "127754", "127757", "127758", "127759", "127760", "127761", "127762", "127763", "127765", "127766", "127768", "127770", "127771", "127773", "127774", "127775", "127776", "127778", "127780", "127781", "127782", "127787", "127789", "127790", "127792", "127793", "127795", "127799", "127800", "127801", "127805", "127806", "127807", "127808", "127810", "127812", "127814", "127817", "127821", "127822", "127823", "127834", "127837", "127840", "127842", "127843", "127846", "127847", "127851", "127852", "127855", "127856", "127859", "127860", "127861", "127862", "127865", "127866", "127867", "127868", "127869", "127870", "127873", "127875", "127877", "127879", "127880", "127882", "127884", "127885", "127886", "127887", "127888", "127889", "127890", "127893", "127896", "127900", "127903", "127905", "127909", "127911", "127915", "127916", "127917", "127918", "127919", "127923", "127926", "127927", "127929", "127931", "127939", "127940", "127941", "127943", "127948", "127949", "127951", "127953", "127958", "127964", "127965", "127967", "127968", "127970", "127973", "127974", "127976", "127977", "127979", "127980", "127981", "127982", "127984", "127985", "127986", "127988", "127991", "127994", "127996", "127999", "128000", "128002", "128003", "128004", "128005", "128006", "128007", "128010", "128012", "128014", "128015", "128016", "128017", "128018", "128020", "128022", "128024", "128029", "128032", "128037", "128040", "128041", "128043", "128046", "128048", "128049", "128050", "128052", "128053", "128056", "128058", "128059", "128060", "128061", "128063", "128064", "128065", "128066", "128067", "128069", "128070", "128071", "128072", "128075", "128076", "128079", "128080", "128081", "128082", "128084", "128085", "128089", "128091", "128095", "128096", "128103", "128105", "128108", "128109", "128115", "128116", "128121", "128122", "128126", "128127", "128130", "128133", "128137", "128138", "128141", "128144", "128147", "128148", "128156", "128157", "128159", "128163", "128164", "128168", "128171", "128173", "128179", "128180", "128181", "128182", "128183", "128185", "128187", "128189", "128191", "128194", "128195", "128198", "128200", "128201", "128203", "128205", "128206", "128208", "128211", "128212", "128213", "128214", "128215", "128218", "128221", "128224", "128225", "128226", "128227", "128233", "128235", "128238", "128240", "128243", "128250", "128252", "128253", "128256", "128257", "128261", "128262", "128266", "128269", "128272", "128273", "128278", "128279", "128281", "128282", "128284", "128287", "128293", "128295", "128298", "128299", "128301", "128306", "128307", "128308", "128309", "128310", "128312", "128313", "128315", "128316", "128317", "128319", "128321", "128322", "128324", "128327", "128329", "128331", "128332", "128333", "128338", "128341", "128346", "128349", "128351", "128353", "128354", "128356", "128357", "128360", "128362", "128363", "128364", "128366", "128368", "128369", "128372", "128374", "128375", "128377", "128379", "128381", "128382", "128384", "128386", "128388", "128391", "128395", "128398", "128399", "128400", "128403", "128406", "128407", "128408", "128412", "128415", "128418", "128419", "128420", "128423", "128424", "128425", "128426", "128427", "128431", "128432", "128437", "128438", "128444", "128445", "128448", "128449", "128454", "128455", "128456", "128461", "128462", "128463", "128467", "128471", "128474", "128477", "128479", "128482", "128483", "128484", "128486", "128488", "128492", "128493", "128496", "128498", "128500", "128501", "128506", "128507", "128508", "128510", "128512", "128514", "128516", "128519", "128521", "128523", "128524", "128526", "128527", "128528", "128529", "128531", "128532", "128533", "128535", "128539", "128541", "128542", "128545", "128547", "128548", "128553", "128554", "128555", "128559", "128561", "128569", "128570", "128574", "128576", "128577", "128579", "128580", "128582", "128583", "128585", "128587", "128588", "128589", "128590", "128591", "128592", "128593", "128596", "128599", "128600", "128601", "128605", "128606", "128607", "128608", "128609", "128610", "128611", "128613", "128615", "128616", "128618", "128621", "128624", "128625", "128626", "128627", "128629", "128631", "128633", "128640", "128643", "128645", "128647", "128651", "128652", "128653", "128654", "128655", "128656", "128657", "128659", "128662", "128663", "128664", "128669", "128671", "128672", "128676", "128677", "128679", "128680", "128682", "128684", "128685", "128687", "128694", "128695", "128698", "128702", "128703", "128704", "128708", "128709", "128711", "128715", "128716", "128717", "128719", "128720", "128722", "128724", "128729", "128730", "128733", "128741", "128743", "128744", "128749", "128753", "128754", "128757", "128758", "128760", "128762", "128764", "128767", "128771", "128774", "128775", "128777", "128778", "128780", "128783", "128788", "128789", "128792", "128794", "128795", "128797", "128798", "128799", "128804", "128806", "128807", "128809", "128810", "128811", "128813", "128814", "128815", "128817", "128818", "128820", "128821", "128822", "128823", "128827", "128829", "128832", "128833", "128835", "128836", "128838", "128839", "128843", "128844", "128845", "128846", "128850", "128851", "128853", "128854", "128861", "128862", "128863", "128864", "128865", "128868", "128869", "128870", "128875", "128877", "128878", "128880", "128883", "128884", "128886", "128889", "128890", "128893", "128895", "128896", "128897", "128899", "128900", "128902", "128904", "128905", "128907", "128908", "128910", "128911", "128912", "128913", "128916", "128918", "128919", "128920", "128921", "128922", "128924", "128929", "128930", "128933", "128934", "128938", "128939", "128941", "128942", "128944", "128946", "128947", "128948", "128949", "128951", "128952", "128953", "128954", "128957", "128959", "128960", "128961", "128963", "128964", "128969", "128970", "128972", "128973", "128974", "128975", "128976", "128977", "128979", "128980", "128981", "128983", "128985", "128988", "128989", "128992", "128993", "128994", "128995", "128998", "128999", "129001", "129002", "129008", "129010", "129011", "129012", "129013", "129014", "129015", "129017", "129019", "129023", "129025", "129026", "129027", "129028", "129030", "129035", "129036", "129037", "129038", "129039", "129042", "129043", "129046", "129048", "129049", "129051", "129053", "129056", "129057", "129059", "129060", "129061", "129063", "129065", "129066", "129067", "129068", "129069", "129070", "129071", "129075", "129077", "129078", "129085", "129086", "129088", "129089", "129090", "129096", "129097", "129101", "129103", "129104", "129105", "129108", "129110", "129116", "129119", "129120", "129121", "129122", "129123", "129124", "129127", "129128", "129131", "129134", "129136", "129138", "129139", "129141", "129143", "129146", "129147", "129148", "129152", "129154", "129155", "129156", "129163", "129164", "129165", "129166", "129168", "129172", "129176", "129178", "129179", "129180", "129182", "129185", "129186", "129189", "129190", "129195", "129198", "129200", "129201", "129206", "129207", "129209", "129210", "129211", "129213", "129214", "129215", "129219", "129221", "129222", "129224", "129228", "129229", "129231", "129234", "129236", "129237", "129238", "129239", "129240", "129241", "129244", "129246", "129247", "129248", "129249", "129250", "129251", "129252", "129253", "129257", "129258", "129259", "129260", "129262", "129263", "129264", "129265", "129268", "129270", "129272", "129277", "129280", "129281", "129282", "129284", "129286", "129287", "129290", "129295", "129296", "129297", "129298", "129299", "129300", "129302", "129304", "129307", "129309", "129310", "129313", "129314", "129315", "129319", "129321", "129324", "129326", "129329", "129330", "129331", "129333", "129337", "129338", "129339", "129340", "129341", "129343", "129346", "129347", "129349", "129351", "129352", "129353", "129354", "129355", "129359", "129361", "129363", "129364", "129365", "129367", "129368", "129370", "129371", "129372", "129373", "129374", "129376", "129377", "129379", "129388", "129389", "129394", "129399", "129401", "129407", "129408", "129410", "129412", "129414", "129415", "129416", "129418", "129419", "129421", "129422", "129423", "129426", "129427", "129429", "129430", "129432", "129434", "129435", "129436", "129438", "129439", "129440", "129441", "129443", "129444", "129445", "129446", "129447", "129450", "129451", "129452", "129453", "129454", "129456", "129457", "129459", "129462", "129464", "129466", "129468", "129469", "129470", "129472", "129473", "129474", "129475", "129479", "129483", "129485", "129490", "129491", "129493", "129495", "129498", "129499", "129500", "129501", "129502", "129503", "129504", "129505", "129506", "129508", "129509", "129510", "129511", "129513", "129515", "129517", "129521", "129522", "129524", "129526", "129527", "129530", "129531", "129532", "129533", "129534", "129535", "129540", "129543", "129544", "129548", "129549", "129560", "129561", "129562", "129563", "129564", "129569", "129571", "129572", "129573", "129574", "129576", "129578", "129584", "129585", "129586", "129587", "129592", "129594", "129595", "129596", "129598", "129599", "129600", "129603", "129608", "129609", "129611", "129612", "129613", "129614", "129615", "129620", "129621", "129624", "129631", "129635", "129637", "129640", "129641", "129642", "129646", "129651", "129654", "129655", "129660", "129663", "129666", "129668", "129670", "129671", "129674", "129676", "129679", "129682", "129684", "129686", "129690", "129694", "129695", "129696", "129702", "129704", "129705", "129706", "129709", "129712", "129713", "129715", "129716", "129717", "129718", "129719", "129720", "129722", "129723", "129724", "129725", "129727", "129730", "129731", "129733", "129735", "129738", "129739", "129740", "129741", "129746", "129747", "129748", "129750", "129751", "129753", "129754", "129755", "129757", "129760", "129762", "129764", "129765", "129766", "129767", "129768", "129769", "129770", "129771", "129772", "129774", "129776", "129779", "129780", "129781", "129784", "129785", "129786", "129787", "129790", "129791", "129794", "129795", "129796", "129798", "129801", "129804", "129806", "129807", "129809", "129810", "129812", "129813", "129818", "129820", "129821", "129823", "129824", "129825", "129827", "129831", "129833", "129835", "129836", "129837", "129838", "129839", "129841", "129843", "129845", "129846", "129847", "129848", "129849", "129850", "129851", "129852", "129853", "129855", "129857", "129859", "129861", "129875", "129876", "129877", "129879", "129880", "129881", "129882", "129885", "129886", "129887", "129889", "129890", "129892", "129893", "129895", "129897", "129898", "129900", "129902", "129905", "129906", "129907", "129910", "129911", "129913", "129914", "129915", "129916", "129917", "129928", "129933", "129934", "129935", "129937", "129940", "129941", "129944", "129946", "129947", "129948", "129949", "129950", "129951", "129953", "129954", "129957", "129960", "129964", "129965", "129966", "129968", "129970", "129971", "129977", "129978", "129980", "129984", "129986", "129988", "129989", "129992", "129993", "129994", "129997", "130001", "130003", "130006", "130007", "130008", "130010", "130011", "130012", "130013", "130016", "130017", "130021", "130023", "130025", "130026", "130027", "130028", "130030", "130032", "130033", "130038", "130047", "130048", "130049", "130050", "130053", "130054", "130055", "130056", "130057", "130058", "130061", "130062", "130063", "130065", "130068", "130073", "130074", "130076", "130077", "130078", "130081", "130082", "130083", "130085", "130086", "130089", "130091", "130092", "130093", "130095", "130096", "130097", "130098", "130102", "130104", "130107", "130108", "130110", "130112", "130113", "130116", "130118", "130125", "130127", "130128", "130129", "130130", "130134", "130136", "130138", "130139", "130140", "130143", "130145", "130148", "130152", "130154", "130155", "130157", "130158", "130159", "130162", "130165", "130167", "130168", "130172", "130173", "130174", "130177", "130178", "130179", "130180", "130181", "130182", "130183", "130184", "130187", "130188", "130190", "130192", "130196", "130199", "130200", "130201", "130202", "130203", "130204", "130205", "130208", "130209", "130210", "130211", "130213", "130215", "130216", "130221", "130227", "130229", "130230", "130236", "130237", "130239", "130240", "130243", "130244", "130245", "130246", "130247", "130248", "130249", "130251", "130252", "130253", "130254", "130258", "130259", "130261", "130262", "130267", "130269", "130270", "130271", "130272", "130275", "130278", "130279", "130282", "130286", "130287", "130291", "130294", "130296", "130297", "130298", "130301", "130302", "130304", "130307", "130309", "130311", "130316", "130318", "130319", "130320", "130321", "130324", "130327", "130328", "130331", "130334", "130335", "130337", "130338", "130345", "130346", "130347", "130348", "130350", "130351", "130352", "130354", "130355", "130357", "130360", "130361", "130362", "130363", "130365", "130369", "130370", "130373", "130374", "130377", "130379", "130380", "130384", "130385", "130388", "130389", "130392", "130393", "130394", "130395", "130396", "130397", "130399", "130401", "130403", "130404", "130405", "130411", "130414", "130418", "130419", "130420", "130421", "130423", "130425", "130426", "130429", "130430", "130438", "130439", "130442", "130448", "130449", "130450", "130451", "130453", "130456", "130458", "130461", "130464", "130465", "130466", "130469", "130471", "130472", "130475", "130478", "130480", "130483", "130486", "130487", "130488", "130489", "130490", "130493", "130495", "130497", "130498", "130499", "130500", "130501", "130502", "130503", "130507", "130510", "130511", "130512", "130513", "130515", "130518", "130520", "130521", "130522", "130523", "130527", "130528", "130531", "130532", "130533", "130534", "130535", "130538", "130539", "130540", "130542", "130544", "130545", "130550", "130551", "130552", "130555", "130556", "130557", "130559", "130561", "130562", "130563", "130564", "130565", "130566", "130567", "130571", "130574", "130577", "130578", "130579", "130580", "130582", "130587", "130589", "130590", "130593", "130594", "130595", "130600", "130601", "130603", "130604", "130605", "130606", "130607", "130609", "130610", "130611", "130614", "130615", "130616", "130617", "130619", "130621", "130622", "130623", "130628", "130629", "130630", "130631", "130635", "130636", "130638", "130639", "130640", "130644", "130645", "130648", "130656", "130657", "130658", "130662", "130663", "130665", "130668", "130670", "130672", "130673", "130676", "130679", "130682", "130683", "130684", "130686", "130687", "130690", "130691", "130692", "130693", "130695", "130697", "130699", "130700", "130701", "130704", "130709", "130710", "130711", "130713", "130714", "130716", "130717", "130719", "130720", "130721", "130723", "130724", "130728", "130730", "130737", "130738", "130739", "130743", "130746", "130747", "130751", "130752", "130755", "130756", "130757", "130760", "130761", "130762", "130763", "130765", "130766", "130767", "130769", "130771", "130773", "130775", "130777", "130778", "130780", "130782", "130785", "130786", "130790", "130795", "130799", "130800", "130812", "130817", "130818", "130819", "130822", "130825", "130826", "130829", "130830", "130833", "130835", "130836", "130837", "130838", "130839", "130840", "130841", "130843", "130847", "130848", "130850", "130851", "130853", "130854", "130856", "130857", "130859", "130860", "130861", "130863", "130866", "130867", "130868", "130871", "130872", "130874", "130876", "130879", "130881", "130882", "130884", "130885", "130892", "130895", "130899", "130904", "130905", "130907", "130909", "130910", "130913", "130917", "130922", "130925", "130927", "130928", "130930", "130935", "130936", "130939", "130944", "130945", "130946", "130947", "130951", "130952", "130953", "130957", "130961", "130962", "130963", "130964", "130965", "130967", "130969", "130971", "130978", "130981", "130985", "130988", "130990", "130991", "130992", "130993", "130994", "130996", "130997", "131000", "131002", "131004", "131006", "131007", "131008", "131011", "131013", "131015", "131017", "131020", "131021", "131022", "131024", "131025", "131027", "131029", "131036", "131041", "131042", "131043", "131044", "131045", "131046", "131047", "131056", "131057", "131058", "131061", "131062", "131063", "131066", "131067", "131072", "131073", "131075", "131078", "131082", "131083", "131084", "131091", "131093", "131095", "131098", "131099", "131107", "131109", "131111", "131113", "131115", "131116", "131117", "131118", "131120", "131121", "131123", "131124", "131125", "131128", "131129", "131130", "131132", "131135", "131136", "131137", "131138", "131139", "131140", "131141", "131142", "131144", "131147", "131149", "131151", "131153", "131154", "131155", "131158", "131163", "131165", "131166", "131167", "131168", "131170", "131173", "131178", "131179", "131182", "131183", "131185", "131188", "131189", "131190", "131191", "131192", "131193", "131194", "131197", "131198", "131199", "131201", "131203", "131204", "131207", "131209", "131212", "131213", "131215", "131217", "131219", "131223", "131226", "131228", "131233", "131234", "131235", "131236", "131237", "131239", "131240", "131242", "131243", "131248", "131249", "131251", "131252", "131253", "131254", "131256", "131257", "131258", "131259", "131261", "131265", "131266", "131271", "131272", "131273", "131274", "131275", "131277", "131280", "131281", "131282", "131285", "131287", "131288", "131289", "131293", "131297", "131298", "131299", "131304", "131305", "131307", "131315", "131316", "131318", "131319", "131327", "131329", "131330", "131331", "131334", "131335", "131336", "131337", "131338", "131339", "131340", "131342", "131344", "131345", "131346", "131347", "131349", "131350", "131351", "131353", "131355", "131358", "131359", "131360", "131361", "131362", "131363", "131364", "131367", "131368", "131369", "131371", "131373", "131374", "131376", "131378", "131381", "131386", "131391", "131397", "131399", "131400", "131401", "131403", "131406", "131409", "131410", "131412", "131413", "131414", "131415", "131416", "131417", "131421", "131423", "131425", "131426", "131427", "131430", "131431", "131432", "131434", "131435", "131437", "131440", "131442", "131444", "131445", "131446", "131447", "131448", "131450", "131452", "131453", "131456", "131457", "131458", "131460", "131463", "131465", "131466", "131468", "131469", "131470", "131472", "131477", "131478", "131479", "131480", "131481", "131484", "131485", "131486", "131490", "131492", "131495", "131496", "131497", "131498", "131501", "131502", "131504", "131506", "131508", "131509", "131510", "131511", "131517", "131522", "131523", "131525", "131527", "131528", "131531", "131532", "131533", "131535", "131536", "131539", "131541", "131546", "131549", "131550", "131552", "131554", "131557", "131558", "131560", "131570", "131571", "131572", "131573", "131574", "131575", "131578", "131579", "131581", "131587", "131591", "131592", "131593", "131595", "131598", "131602", "131603", "131604", "131605", "131606", "131609", "131611", "131612", "131613", "131614", "131616", "131619", "131620", "131624", "131626", "131627", "131632", "131633", "131635", "131637", "131640", "131647", "131648", "131650", "131653", "131657", "131659", "131662", "131663", "131664", "131666", "131670", "131671", "131674", "131677", "131678", "131682", "131683", "131684", "131686", "131687", "131688", "131691", "131693", "131694", "131696", "131698", "131701", "131702", "131704", "131706", "131707", "131709", "131711", "131714", "131715", "131718", "131719", "131721", "131725", "131728", "131729", "131731", "131732", "131733", "131734", "131735", "131736", "131737", "131738", "131740", "131742", "131744", "131746", "131750", "131751", "131753", "131754", "131756", "131758", "131760", "131761", "131762", "131763", "131765", "131766", "131767", "131768", "131769", "131770", "131772", "131773", "131774", "131777", "131779", "131783", "131789", "131790", "131791", "131792", "131793", "131795", "131797", "131798", "131799", "131802", "131804", "131805", "131806", "131809", "131812", "131813", "131816", "131817", "131820", "131821", "131825", "131826", "131828", "131830", "131831", "131832", "131833", "131834", "131835", "131836", "131841", "131842", "131843", "131846", "131847", "131849", "131850", "131851", "131855", "131860", "131863", "131864", "131865", "131866", "131867", "131868", "131871", "131873", "131875", "131876", "131878", "131879", "131880", "131883", "131884", "131886", "131887", "131888", "131891", "131893", "131894", "131895", "131897", "131898", "131904", "131905", "131907", "131908", "131909", "131913", "131915", "131916", "131917", "131918", "131920", "131921", "131923", "131924", "131926", "131927", "131928", "131929", "131931", "131932", "131933", "131937", "131939", "131940", "131941", "131944", "131946", "131948", "131951", "131957", "131958", "131961", "131962", "131963", "131969", "131970", "131971", "131972", "131974", "131978", "131981", "131982", "131986", "131987", "131988", "131989", "131991", "131992", "131993", "131994", "131995", "131996", "131997", "131998", "132000", "132002", "132004", "132005", "132006", "132010", "132011", "132016", "132018", "132021", "132023", "132024", "132025", "132026", "132027", "132028", "132029", "132031", "132032", "132034", "132037", "132039", "132042", "132046", "132047", "132049", "132050", "132051", "132053", "132054", "132055", "132059", "132061", "132063", "132064", "132065", "132067", "132070", "132071", "132072", "132073", "132075", "132077", "132081", "132083", "132086", "132088", "132090", "132092", "132093", "132097", "132100", "132102", "132104", "132105", "132106", "132107", "132109", "132111", "132115", "132116", "132121", "132124", "132126", "132129", "132131", "132132", "132134", "132140", "132143", "132145", "132146", "132147", "132148", "132149", "132154", "132155", "132158", "132160", "132161", "132163", "132175", "132176", "132177", "132179", "132181", "132183", "132188", "132191", "132192", "132195", "132197", "132199", "132200", "132202", "132203", "132204", "132206", "132210", "132211", "132212", "132213", "132220", "132223", "132225", "132227", "132230", "132233", "132235", "132236", "132237", "132238", "132239", "132241", "132244", "132246", "132250", "132251", "132254", "132259", "132261", "132262", "132263", "132264", "132268", "132270", "132271", "132272", "132274", "132275", "132276", "132278", "132280", "132283", "132284", "132286", "132287", "132290", "132291", "132293", "132295", "132299", "132304", "132305", "132306", "132307", "132313", "132314", "132318", "132319", "132320", "132323", "132324", "132328", "132330", "132332", "132333", "132335", "132336", "132337", "132338", "132339", "132341", "132342", "132344", "132346", "132350", "132351", "132353", "132355", "132356", "132358", "132360", "132362", "132365", "132366", "132369", "132374", "132375", "132378", "132380", "132382", "132385", "132386", "132387", "132395", "132397", "132399", "132401", "132403", "132404", "132405", "132406", "132407", "132408", "132409", "132411", "132412", "132414", "132415", "132416", "132418", "132419", "132420", "132422", "132424", "132426", "132428", "132430", "132432", "132433", "132434", "132435", "132437", "132439", "132441", "132442", "132443", "132445", "132448", "132449", "132452", "132453", "132455", "132457", "132458", "132459", "132460", "132461", "132462", "132463", "132465", "132470", "132471", "132472", "132473", "132477", "132478", "132481", "132482", "132484", "132486", "132488", "132491", "132493", "132496", "132497", "132498", "132499", "132504", "132506", "132507", "132508", "132509", "132510", "132511", "132512", "132515", "132520", "132521", "132525", "132526", "132527", "132529", "132530", "132531", "132533", "132535", "132536", "132539", "132540", "132541", "132542", "132544", "132546", "132548", "132549", "132551", "132552", "132554", "132558", "132560", "132563", "132566", "132567", "132568", "132569", "132571", "132573", "132575", "132577", "132579", "132581", "132584", "132587", "132589", "132590", "132592", "132593", "132595", "132596", "132601", "132603", "132604", "132606", "132607", "132609", "132610", "132612", "132616", "132617", "132620", "132623", "132624", "132629", "132630", "132632", "132633", "132635", "132638", "132640", "132641", "132642", "132643", "132644", "132648", "132650", "132652", "132655", "132659", "132660", "132662", "132663", "132664", "132665", "132670", "132672", "132673", "132674", "132676", "132677", "132684", "132685", "132686", "132687", "132689", "132691", "132692", "132693", "132694", "132698", "132699", "132704", "132705", "132706", "132707", "132710", "132712", "132715", "132717", "132719", "132721", "132725", "132730", "132734", "132737", "132738", "132739", "132740", "132745", "132749", "132752", "132754", "132756", "132757", "132759", "132760", "132761", "132763", "132766", "132767", "132768", "132771", "132777", "132779", "132780", "132782", "132783", "132785", "132786", "132788", "132789", "132792", "132793", "132794", "132795", "132798", "132799", "132802", "132804", "132805", "132806", "132809", "132810", "132813", "132815", "132818", "132819", "132822", "132823", "132825", "132827", "132828", "132831", "132832", "132835", "132836", "132837", "132838", "132840", "132841", "132843", "132848", "132852", "132854", "132855", "132857", "132858", "132859", "132863", "132864", "132867", "132869", "132874", "132875", "132876", "132877", "132878", "132879", "132880", "132883", "132885", "132886", "132888", "132894", "132895", "132898", "132901", "132902", "132903", "132905", "132907", "132908", "132911", "132914", "132915", "132917", "132919", "132920", "132923", "132924", "132929", "132930", "132932", "132933", "132934", "132937", "132939", "132940", "132942", "132945", "132949", "132950", "132954", "132957", "132958", "132959", "132962", "132966", "132967", "132968", "132969", "132971", "132972", "132973", "132975", "132977", "132980", "132982", "132984", "132985", "132986", "132989", "132993", "132998", "133000", "133003", "133007", "133009", "133011", "133012", "133013", "133016", "133018", "133019", "133021", "133022", "133023", "133024", "133027", "133028", "133029", "133030", "133033", "133037", "133038", "133039", "133041", "133042", "133044", "133045", "133046", "133048", "133049", "133051", "133052", "133055", "133056", "133059", "133062", "133063", "133065", "133070", "133071", "133073", "133077", "133083", "133084", "133085", "133086", "133087", "133091", "133092", "133094", "133095", "133096", "133099", "133101", "133102", "133103", "133104", "133106", "133107", "133108", "133109", "133111", "133112", "133113", "133116", "133117", "133118", "133119", "133122", "133123", "133127", "133130", "133131", "133133", "133137", "133140", "133141", "133143", "133146", "133149", "133150", "133151", "133153", "133155", "133158", "133159", "133160", "133161", "133165", "133166", "133169", "133170", "133171", "133172", "133175", "133178", "133179", "133183", "133187", "133188", "133190", "133195", "133196", "133197", "133198", "133201", "133206", "133207", "133208", "133209", "133211", "133214", "133216", "133217", "133220", "133221", "133224", "133225", "133226", "133230", "133231", "133234", "133235", "133236", "133237", "133238", "133239", "133240", "133241", "133244", "133245", "133246", "133248", "133249", "133255", "133258", "133259", "133261", "133262", "133264", "133266", "133267", "133271", "133273", "133277", "133278", "133280", "133281", "133283", "133288", "133292", "133293", "133294", "133295", "133297", "133298", "133299", "133301", "133305", "133306", "133309", "133315", "133316", "133317", "133318", "133321", "133322", "133323", "133325", "133327", "133330", "133331", "133332", "133333", "133335", "133336", "133338", "133339", "133340", "133341", "133342", "133344", "133347", "133348", "133349", "133350", "133351", "133352", "133353", "133357", "133359", "133363", "133364", "133367", "133369", "133370", "133373", "133375", "133377", "133379", "133380", "133382", "133384", "133391", "133392", "133395", "133396", "133398", "133400", "133401", "133402", "133403", "133406", "133407", "133410", "133411", "133412", "133415", "133418", "133423", "133424", "133425", "133429", "133431", "133432", "133433", "133439", "133441", "133445", "133446", "133447", "133448", "133449", "133450", "133452", "133453", "133454", "133455", "133458", "133459", "133462", "133465", "133466", "133467", "133469", "133474", "133476", "133483", "133484", "133486", "133489", "133490", "133493", "133494", "133495", "133496", "133498", "133499", "133500", "133502", "133503", "133505", "133506", "133508", "133509", "133511", "133512", "133515", "133517", "133519", "133524", "133527", "133533", "133534", "133536", "133538", "133540", "133541", "133542", "133543", "133550", "133551", "133556", "133560", "133561", "133565", "133568", "133573", "133574", "133579", "133580", "133582", "133587", "133588", "133590", "133592", "133594", "133595", "133596", "133598", "133599", "133603", "133604", "133605", "133606", "133607", "133608", "133612", "133613", "133618", "133619", "133620", "133622", "133623", "133624", "133630", "133632", "133637", "133642", "133644", "133646", "133648", "133649", "133650", "133651", "133652", "133653", "133654", "133655", "133656", "133657", "133658", "133660", "133663", "133664", "133666", "133667", "133668", "133670", "133673", "133675", "133678", "133680", "133686", "133688", "133693", "133696", "133697", "133698", "133700", "133702", "133707", "133710", "133712", "133714", "133716", "133718", "133719", "133720", "133721", "133722", "133723", "133724", "133725", "133726", "133728", "133732", "133733", "133738", "133739", "133741", "133742", "133743", "133744", "133746", "133747", "133752", "133753", "133754", "133757", "133758", "133762", "133763", "133764", "133765", "133767", "133771", "133774", "133777", "133780", "133782", "133789", "133794", "133795", "133797", "133798", "133802", "133804", "133806", "133812", "133813", "133815", "133816", "133817", "133818", "133819", "133820", "133821", "133824", "133827", "133828", "133829", "133833", "133834", "133836", "133837", "133842", "133844", "133845", "133847", "133848", "133850", "133852", "133859", "133862", "133863", "133864", "133865", "133866", "133867", "133870", "133873", "133874", "133877", "133878", "133880", "133883", "133884", "133887", "133888", "133893", "133895", "133897", "133898", "133899", "133900", "133902", "133903", "133905", "133911", "133912", "133914", "133919", "133921", "133923", "133927", "133930", "133931", "133933", "133934", "133935", "133937", "133938", "133940", "133942", "133943", "133944", "133945", "133947", "133948", "133950", "133951", "133952", "133953", "133961", "133963", "133964", "133965", "133967", "133969", "133970", "133971", "133972", "133973", "133974", "133982", "133983", "133984", "133985", "133986", "133988", "133989", "133991", "133992", "133999", "134001", "134002", "134005", "134007", "134008", "134010", "134011", "134012", "134014", "134017", "134018", "134019", "134020", "134021", "134022", "134024", "134025", "134030", "134031", "134033", "134036", "134037", "134039", "134041", "134043", "134044", "134045", "134047", "134049", "134050", "134053", "134054", "134055", "134058", "134059", "134060", "134063", "134065", "134066", "134067", "134068", "134070", "134071", "134074", "134075", "134076", "134077", "134078", "134079", "134080", "134083", "134084", "134085", "134087", "134090", "134091", "134093", "134094", "134096", "134097", "134099", "134101", "134102", "134103", "134108", "134112", "134114", "134117", "134121", "134122", "134123", "134124", "134127", "134128", "134129", "134135", "134137", "134138", "134139", "134140", "134143", "134145", "134146", "134148", "134149", "134150", "134151", "134153", "134160", "134163", "134166", "134168", "134169", "134170", "134171", "134172", "134175", "134177", "134178", "134179", "134180", "134182", "134184", "134185", "134187", "134190", "134191", "134192", "134199", "134200", "134204", "134208", "134209", "134210", "134212", "134213", "134214", "134215", "134217", "134219", "134221", "134223", "134224", "134225", "134227", "134228", "134229", "134233", "134234", "134241", "134242", "134243", "134244", "134246", "134248", "134251", "134253", "134255", "134257", "134260", "134261", "134262", "134263", "134264", "134269", "134270", "134272", "134273", "134275", "134276", "134278", "134279", "134281", "134284", "134286", "134288", "134289", "134290", "134291", "134292", "134295", "134299", "134300", "134301", "134302", "134303", "134305", "134306", "134310", "134312", "134317", "134319", "134322", "134323", "134325", "134326", "134330", "134332", "134335", "134336", "134338", "134341", "134342", "134345", "134349", "134350", "134353", "134359", "134360", "134361", "134363", "134364", "134365", "134366", "134370", "134372", "134373", "134374", "134376", "134377", "134380", "134381", "134382", "134384", "134386", "134388", "134390", "134402", "134403", "134405", "134406", "134407", "134408", "134413", "134414", "134415", "134416", "134417", "134419", "134421", "134422", "134423", "134424", "134427", "134429", "134433", "134434", "134441", "134443", "134445", "134446", "134447", "134448", "134450", "134453", "134458", "134459", "134461", "134463", "134465", "134468", "134469", "134472", "134475", "134480", "134483", "134485", "134487", "134488", "134489", "134490", "134492", "134493", "134496", "134497", "134500", "134502", "134504", "134506", "134507", "134508", "134510", "134511", "134518", "134519", "134522", "134524", "134525", "134527", "134530", "134533", "134534", "134535", "134536", "134538", "134539", "134541", "134542", "134545", "134547", "134549", "134551", "134552", "134553", "134555", "134556", "134561", "134562", "134563", "134567", "134572", "134573", "134575", "134577", "134579", "134580", "134581", "134585", "134589", "134591", "134592", "134594", "134602", "134604", "134605", "134608", "134611", "134612", "134613", "134614", "134621", "134622", "134623", "134625", "134627", "134628", "134630", "134631", "134632", "134633", "134634", "134635", "134636", "134639", "134640", "134641", "134642", "134643", "134646", "134649", "134650", "134651", "134652", "134653", "134654", "134655", "134658", "134661", "134664", "134666", "134668", "134670", "134671", "134674", "134677", "134679", "134682", "134685", "134686", "134692", "134693", "134695", "134696", "134700", "134701", "134703", "134704", "134706", "134709", "134713", "134714", "134717", "134718", "134721", "134723", "134724", "134730", "134731", "134732", "134734", "134738", "134742", "134745", "134755", "134756", "134757", "134758", "134759", "134760", "134762", "134764", "134767", "134768", "134770", "134771", "134775", "134781", "134782", "134784", "134785", "134786", "134787", "134788", "134789", "134790", "134791", "134792", "134794", "134795", "134796", "134797", "134799", "134800", "134801", "134802", "134803", "134804", "134806", "134807", "134810", "134812", "134813", "134814", "134819", "134824", "134825", "134828", "134830", "134834", "134838", "134840", "134844", "134845", "134849", "134850", "134852", "134853", "134854", "134856", "134857", "134858", "134859", "134860", "134865", "134867", "134868", "134871", "134872", "134874", "134876", "134877", "134879", "134881", "134882", "134887", "134888", "134894", "134895", "134899", "134903", "134904", "134906", "134908", "134909", "134913", "134914", "134917", "134923", "134924", "134925", "134926", "134927", "134929", "134930", "134931", "134932", "134934", "134936", "134937", "134939", "134944", "134947", "134949", "134950", "134951", "134952", "134955", "134956", "134958", "134959", "134960", "134961", "134963", "134965", "134967", "134969", "134971", "134972", "134973", "134975", "134978", "134979", "134980", "134982", "134985", "134987", "134988", "134989", "134991", "134992", "134993", "134995", "134996", "134999", "135001", "135002", "135005", "135011", "135012", "135014", "135015", "135016", "135019", "135020", "135021", "135024", "135028", "135029", "135030", "135031", "135034", "135036", "135037", "135038", "135040", "135042", "135044", "135045", "135046", "135048", "135049", "135053", "135058", "135064", "135067", "135068", "135074", "135075", "135077", "135079", "135081", "135083", "135084", "135085", "135086", "135088", "135089", "135090", "135092", "135095", "135097", "135100", "135102", "135104", "135105", "135108", "135109", "135111", "135112", "135114", "135115", "135116", "135118", "135121", "135124", "135126", "135127", "135128", "135130", "135131", "135132", "135134", "135136", "135138", "135139", "135141", "135144", "135146", "135147", "135148", "135149", "135150", "135152", "135153", "135154", "135155", "135156", "135157", "135158", "135159", "135160", "135161", "135164", "135166", "135168", "135172", "135174", "135175", "135176", "135177", "135178", "135182", "135185", "135187", "135190", "135192", "135195", "135201", "135209", "135211", "135219", "135225", "135227", "135229", "135231", "135234", "135236", "135239", "135245", "135246", "135249", "135250", "135253", "135257", "135258", "135259", "135264", "135266", "135267", "135270", "135271", "135272", "135273", "135274", "135277", "135278", "135279", "135281", "135284", "135285", "135288", "135290", "135293", "135295", "135296", "135297", "135299", "135300", "135302", "135307", "135308", "135309", "135311", "135313", "135314", "135316", "135318", "135321", "135322", "135323", "135324", "135326", "135329", "135330", "135332", "135333", "135336", "135338", "135339", "135342", "135343", "135344", "135346", "135348", "135352", "135359", "135360", "135362", "135365", "135367", "135369", "135370", "135371", "135372", "135373", "135379", "135382", "135386", "135387", "135389", "135390", "135391", "135393", "135394", "135396", "135397", "135398", "135399", "135402", "135406", "135407", "135408", "135410", "135411", "135413", "135414", "135415", "135416", "135417", "135418", "135422", "135429", "135432", "135436", "135437", "135441", "135442", "135443", "135446", "135449", "135451", "135453", "135454", "135455", "135456", "135457", "135458", "135462", "135463", "135464", "135465", "135466", "135467", "135471", "135473", "135474", "135475", "135478", "135479", "135482", "135484", "135489", "135491", "135492", "135493", "135496", "135504", "135506", "135507", "135511", "135512", "135513", "135514", "135515", "135517", "135518", "135520", "135521", "135524", "135526", "135527", "135528", "135529", "135531", "135532", "135533", "135535", "135536", "135538", "135541", "135542", "135543", "135546", "135547", "135548", "135551", "135552", "135553", "135554", "135557", "135558", "135560", "135561", "135562", "135565", "135566", "135570", "135571", "135575", "135576", "135577", "135579", "135581", "135585", "135591", "135592", "135593", "135595", "135600", "135601", "135603", "135605", "135606", "135607", "135608", "135609", "135612", "135613", "135617", "135621", "135623", "135624", "135625", "135628", "135629", "135631", "135632", "135634", "135639", "135641", "135644", "135645", "135646", "135649", "135650", "135655", "135656", "135657", "135658", "135659", "135661", "135667", "135668", "135669", "135670", "135671", "135673", "135674", "135676", "135677", "135679", "135681", "135682", "135683", "135685", "135686", "135692", "135694", "135697", "135703", "135705", "135706", "135707", "135708", "135711", "135713", "135715", "135716", "135718", "135719", "135726", "135728", "135732", "135734", "135735", "135736", "135738", "135739", "135742", "135746", "135748", "135751", "135753", "135754", "135756", "135758", "135760", "135763", "135765", "135769", "135771", "135773", "135775", "135776", "135777", "135778", "135781", "135782", "135783", "135784", "135785", "135787", "135789", "135792", "135793", "135794", "135801", "135804", "135805", "135807", "135809", "135810", "135811", "135813", "135814", "135815", "135817", "135819", "135822", "135824", "135827", "135828", "135829", "135831", "135832", "135835", "135838", "135839", "135841", "135844", "135845", "135846", "135848", "135849", "135854", "135855", "135858", "135859", "135860", "135861", "135862", "135864", "135866", "135867", "135869", "135872", "135875", "135877", "135879", "135884", "135886", "135890", "135891", "135893", "135894", "135897", "135898", "135900", "135902", "135903", "135904", "135906", "135912", "135913", "135914", "135916", "135918", "135920", "135921", "135924", "135926", "135928", "135929", "135930", "135935", "135936", "135937", "135938", "135939", "135943", "135944", "135945", "135946", "135947", "135950", "135954", "135955", "135957", "135958", "135959", "135961", "135962", "135965", "135966", "135970", "135974", "135975", "135976", "135979", "135986", "135988", "135990", "135992", "135994", "135995", "135999", "136000", "136002", "136003", "136011", "136012", "136015", "136020", "136021", "136023", "136024", "136025", "136026", "136028", "136032", "136034", "136036", "136037", "136039", "136040", "136041", "136042", "136046", "136047", "136049", "136050", "136051", "136055", "136056", "136060", "136061", "136062", "136065", "136067", "136068", "136069", "136077", "136080", "136083", "136085", "136086", "136087", "136089", "136091", "136093", "136095", "136096", "136099", "136100", "136102", "136105", "136106", "136108", "136110", "136113", "136114", "136115", "136116", "136117", "136118", "136119", "136121", "136123", "136125", "136126", "136127", "136129", "136133", "136134", "136137", "136140", "136142", "136144", "136145", "136147", "136149", "136152", "136153", "136154", "136156", "136157", "136159", "136160", "136164", "136167", "136170", "136171", "136172", "136174", "136176", "136177", "136179", "136181", "136183", "136184", "136186", "136189", "136190", "136191", "136193", "136196", "136198", "136199", "136201", "136205", "136207", "136208", "136209", "136210", "136211", "136212", "136213", "136214", "136215", "136216", "136217", "136221", "136222", "136224", "136226", "136227", "136229", "136230", "136238", "136243", "136245", "136247", "136250", "136254", "136256", "136258", "136261", "136264", "136266", "136270", "136272", "136273", "136275", "136278", "136279", "136282", "136283", "136284", "136285", "136289", "136290", "136292", "136293", "136294", "136295", "136297", "136298", "136299", "136300", "136303", "136306", "136308", "136309", "136310", "136311", "136312", "136313", "136316", "136318", "136319", "136320", "136321", "136327", "136328", "136330", "136331", "136332", "136333", "136334", "136335", "136336", "136338", "136342", "136344", "136345", "136347", "136349", "136351", "136352", "136356", "136357", "136358", "136360", "136361", "136365", "136366", "136368", "136371", "136373", "136374", "136376", "136377", "136378", "136380", "136381", "136382", "136384", "136385", "136386", "136389", "136390", "136391", "136392", "136394", "136395", "136396", "136397", "136398", "136399", "136401", "136403", "136405", "136407", "136409", "136410", "136414", "136415", "136416", "136417", "136422", "136425", "136426", "136428", "136429", "136430", "136432", "136434", "136435", "136440", "136443", "136444", "136445", "136446", "136448", "136450", "136452", "136453", "136454", "136455", "136456", "136457", "136459", "136460", "136461", "136462", "136464", "136468", "136469", "136470", "136471", "136472", "136475", "136477", "136478", "136480", "136482", "136484", "136485", "136488", "136489", "136491", "136494", "136495", "136497", "136500", "136501", "136502", "136503", "136506", "136508", "136510", "136511", "136514", "136516", "136519", "136521", "136524", "136528", "136531", "136532", "136534", "136536", "136537", "136540", "136543", "136545", "136546", "136550", "136553", "136555", "136557", "136558", "136559", "136560", "136561", "136562", "136564", "136565", "136566", "136568", "136569", "136571", "136572", "136573", "136575", "136576", "136578", "136579", "136580", "136581", "136586", "136587", "136588", "136589", "136590", "136591", "136595", "136597", "136598", "136599", "136600", "136602", "136603", "136605", "136608", "136611", "136612", "136613", "136614", "136615", "136617", "136621", "136622", "136624", "136626", "136627", "136628", "136631", "136632", "136634", "136635", "136636", "136638", "136639", "136640", "136641", "136643", "136644", "136645", "136646", "136647", "136649", "136650", "136651", "136655", "136656", "136657", "136658", "136659", "136660", "136665", "136668", "136672", "136673", "136674", "136675", "136676", "136677", "136684", "136685", "136687", "136689", "136691", "136693", "136698", "136700", "136701", "136702", "136703", "136705", "136706", "136711", "136712", "136716", "136717", "136718", "136719", "136721", "136722", "136726", "136727", "136728", "136730", "136731", "136732", "136733", "136735", "136737", "136738", "136739", "136740", "136747", "136748", "136750", "136751", "136752", "136755", "136758", "136760", "136762", "136763", "136764", "136765", "136768", "136769", "136772", "136774", "136778", "136779", "136782", "136783", "136784", "136785", "136787", "136790", "136791", "136792", "136794", "136795", "136797", "136799", "136801", "136803", "136806", "136807", "136809", "136812", "136814", "136819", "136820", "136821", "136823", "136826", "136828", "136829", "136832", "136834", "136835", "136836", "136837", "136838", "136840", "136841", "136843", "136844", "136846", "136847", "136850", "136851", "136852", "136853", "136856", "136857", "136858", "136859", "136860", "136862", "136865", "136867", "136869", "136870", "136871", "136878", "136879", "136880", "136881", "136884", "136886", "136888", "136891", "136893", "136895", "136899", "136901", "136904", "136906", "136908", "136909", "136911", "136912", "136913", "136915", "136916", "136918", "136919", "136920", "136922", "136923", "136925", "136927", "136928", "136937", "136938", "136943", "136944", "136945", "136949", "136952", "136956", "136959", "136961", "136963", "136967", "136968", "136969", "136973", "136974", "136975", "136978", "136980", "136981", "136982", "136983", "136985", "136992", "136996", "136999", "137001", "137003", "137004", "137006", "137007", "137009", "137010", "137012", "137014", "137017", "137019", "137020", "137021", "137022", "137024", "137026", "137027", "137033", "137037", "137041", "137044", "137045", "137050", "137051", "137052", "137053", "137056", "137059", "137060", "137061", "137062", "137064", "137066", "137067", "137073", "137076", "137081", "137085", "137086", "137090", "137091", "137094", "137095", "137098", "137100", "137104", "137105", "137106", "137107", "137114", "137115", "137117", "137118", "137122", "137124", "137126", "137131", "137135", "137136", "137137", "137138", "137140", "137142", "137143", "137145", "137146", "137150", "137152", "137158", "137160", "137161", "137162", "137168", "137170", "137175", "137177", "137180", "137189", "137195", "137196", "137197", "137198", "137200", "137203", "137206", "137207", "137208", "137210", "137211", "137213", "137214", "137217", "137220", "137221", "137222", "137223", "137224", "137225", "137228", "137230", "137231", "137233", "137234", "137236", "137239", "137240", "137242", "137246", "137247", "137248", "137250", "137252", "137257", "137258", "137260", "137263", "137264", "137265", "137266", "137268", "137270", "137272", "137273", "137276", "137279", "137280", "137284", "137287", "137288", "137291", "137294", "137295", "137296", "137297", "137299", "137300", "137301", "137303", "137305", "137306", "137308", "137309", "137310", "137314", "137316", "137317", "137321", "137322", "137323", "137324", "137325", "137326", "137330", "137336", "137339", "137340", "137342", "137345", "137346", "137347", "137351", "137354", "137355", "137359", "137360", "137361", "137364", "137366", "137367", "137368", "137369", "137376", "137377", "137379", "137380", "137382", "137383", "137385", "137389", "137390", "137396", "137402", "137403", "137405", "137407", "137409", "137410", "137412", "137415", "137416", "137419", "137422", "137423", "137425", "137428", "137430", "137431", "137432", "137436", "137438", "137439", "137440", "137446", "137450", "137451", "137452", "137453", "137456", "137457", "137458", "137460", "137461", "137462", "137463", "137465", "137470", "137474", "137476", "137477", "137478", "137479", "137480", "137483", "137485", "137490", "137492", "137493", "137494", "137495", "137496", "137499", "137501", "137503", "137508", "137509", "137510", "137511", "137513", "137515", "137516", "137519", "137520", "137522", "137524", "137525", "137526", "137528", "137529", "137532", "137534", "137536", "137538", "137539", "137540", "137541", "137542", "137543", "137544", "137547", "137548", "137552", "137553", "137557", "137559", "137560", "137561", "137565", "137566", "137572", "137573", "137574", "137575", "137576", "137579", "137583", "137584", "137587", "137591", "137592", "137593", "137594", "137595", "137596", "137597", "137600", "137601", "137602", "137604", "137608", "137609", "137610", "137614", "137615", "137618", "137619", "137620", "137621", "137623", "137624", "137625", "137626", "137628", "137631", "137632", "137635", "137636", "137639", "137642", "137643", "137644", "137645", "137646", "137648", "137651", "137653", "137655", "137657", "137659", "137661", "137662", "137664", "137665", "137667", "137669", "137671", "137672", "137676", "137678", "137679", "137681", "137684", "137685", "137689", "137692", "137693", "137694", "137702", "137705", "137708", "137709", "137710", "137711", "137712", "137715", "137716", "137718", "137719", "137721", "137722", "137723", "137724", "137725", "137727", "137730", "137731", "137733", "137734", "137735", "137739", "137745", "137747", "137749", "137751", "137755", "137756", "137757", "137759", "137762", "137768", "137769", "137770", "137771", "137775", "137777", "137778", "137779", "137780", "137784", "137787", "137789", "137790", "137791", "137792", "137796", "137801", "137802", "137803", "137805", "137806", "137811", "137812", "137813", "137817", "137823", "137824", "137825", "137828", "137829", "137831", "137834", "137840", "137843", "137844", "137847", "137849", "137852", "137853", "137855", "137856", "137858", "137859", "137860", "137861", "137865", "137867", "137873", "137874", "137875", "137876", "137877", "137881", "137882", "137884", "137885", "137887", "137888", "137889", "137891", "137893", "137894", "137895", "137896", "137899", "137902", "137903", "137907", "137908", "137909", "137910", "137913", "137914", "137916", "137922", "137924", "137926", "137929", "137930", "137932", "137935", "137936", "137938", "137944", "137946", "137949", "137951", "137960", "137962", "137964", "137965", "137966", "137970", "137971", "137973", "137977", "137982", "137986", "137987", "137988", "137990", "137991", "137992", "137996", "137997", "137998", "137999", "138002", "138003", "138004", "138007", "138009", "138010", "138013", "138019", "138020", "138021", "138025", "138026", "138027", "138028", "138029", "138030", "138031", "138037", "138038", "138039", "138040", "138047", "138049", "138052", "138053", "138054", "138056", "138058", "138062", "138063", "138065", "138066", "138067", "138068", "138070", "138072", "138073", "138076", "138077", "138082", "138084", "138085", "138088", "138090", "138093", "138095", "138097", "138098", "138099", "138101", "138102", "138103", "138106", "138109", "138110", "138112", "138115", "138116", "138117", "138118", "138121", "138122", "138124", "138125", "138128", "138131", "138132", "138133", "138137", "138138", "138139", "138142", "138143", "138145", "138146", "138148", "138152", "138153", "138155", "138158", "138159", "138161", "138164", "138165", "138167", "138169", "138170", "138173", "138174", "138175", "138176", "138179", "138181", "138186", "138190", "138191", "138192", "138193", "138195", "138196", "138197", "138198", "138203", "138204", "138209", "138210", "138214", "138220", "138223", "138225", "138226", "138230", "138231", "138232", "138233", "138234", "138236", "138239", "138242", "138243", "138249", "138251", "138252", "138253", "138254", "138255", "138256", "138257", "138259", "138261", "138263", "138265", "138266", "138270", "138271", "138274", "138276", "138278", "138279", "138280", "138283", "138284", "138286", "138287", "138288", "138289", "138290", "138293", "138296", "138298", "138299", "138301", "138302", "138304", "138305", "138306", "138307", "138308", "138311", "138316", "138317", "138319", "138322", "138323", "138324", "138325", "138326", "138327", "138328", "138332", "138334", "138335", "138337", "138339", "138340", "138341", "138343", "138344", "138345", "138347", "138348", "138351", "138352", "138353", "138354", "138356", "138357", "138359", "138364", "138367", "138369", "138370", "138374", "138377", "138378", "138379", "138384", "138385", "138387", "138390", "138391", "138395", "138401", "138404", "138405", "138406", "138407", "138410", "138411", "138413", "138414", "138415", "138416", "138418", "138419", "138421", "138424", "138425", "138428", "138430", "138431", "138432", "138433", "138436", "138441", "138446", "138451", "138455", "138456", "138458", "138459", "138464", "138466", "138467", "138471", "138472", "138473", "138476", "138482", "138483", "138487", "138488", "138489", "138490", "138491", "138492", "138493", "138494", "138495", "138496", "138498", "138499", "138505", "138507", "138508", "138511", "138512", "138513", "138514", "138518", "138520", "138521", "138522", "138523", "138524", "138525", "138528", "138529", "138531", "138532", "138533", "138535", "138536", "138540", "138541", "138542", "138543", "138544", "138546", "138547", "138548", "138551", "138552", "138553", "138555", "138557", "138558", "138559", "138563", "138565", "138566", "138567", "138568", "138571", "138572", "138573", "138574", "138576", "138577", "138578", "138579", "138580", "138581", "138582", "138588", "138589", "138590", "138591", "138596", "138608", "138609", "138610", "138614", "138615", "138616", "138619", "138624", "138625", "138626", "138633", "138636", "138639", "138641", "138642", "138646", "138647", "138649", "138650", "138653", "138654", "138655", "138658", "138662", "138664", "138667", "138668", "138673", "138675", "138676", "138677", "138678", "138680", "138684", "138685", "138687", "138688", "138690", "138691", "138692", "138694", "138696", "138697", "138699", "138700", "138704", "138711", "138712", "138714", "138715", "138716", "138717", "138719", "138720", "138723", "138724", "138725", "138726", "138728", "138734", "138740", "138742", "138743", "138744", "138745", "138746", "138748", "138753", "138754", "138757", "138760", "138761", "138762", "138763", "138766", "138767", "138768", "138769", "138773", "138774", "138775", "138777", "138778", "138784", "138787", "138790", "138791", "138793", "138795", "138797", "138800", "138804", "138806", "138807", "138808", "138809", "138811", "138812", "138813", "138815", "138816", "138817", "138818", "138819", "138820", "138821", "138823", "138826", "138829", "138831", "138833", "138834", "138835", "138837", "138840", "138844", "138845", "138847", "138848", "138849", "138854", "138855", "138857", "138859", "138860", "138861", "138862", "138863", "138865", "138867", "138873", "138876", "138877", "138880", "138886", "138887", "138888", "138890", "138891", "138893", "138894", "138895", "138900", "138903", "138904", "138908", "138909", "138918", "138919", "138921", "138923", "138925", "138926", "138928", "138929", "138931", "138935", "138936", "138937", "138940", "138941", "138945", "138946", "138947", "138948", "138950", "138955", "138957", "138958", "138959", "138961", "138964", "138965", "138968", "138970", "138971", "138972", "138973", "138974", "138976", "138978", "138982", "138983", "138986", "138988", "138991", "138993", "138998", "139003", "139005", "139007", "139008", "139011", "139018", "139019", "139020", "139021", "139023", "139025", "139026", "139028", "139031", "139034", "139036", "139037", "139046", "139048", "139053", "139054", "139055", "139056", "139058", "139061", "139062", "139064", "139065", "139068", "139072", "139075", "139076", "139077", "139079", "139081", "139082", "139085", "139087", "139091", "139092", "139094", "139095", "139098", "139099", "139100", "139102", "139106", "139112", "139113", "139115", "139120", "139123", "139128", "139131", "139132", "139133", "139135", "139136", "139141", "139144", "139146", "139147", "139149", "139155", "139156", "139161", "139164", "139166", "139168", "139170", "139172", "139175", "139178", "139180", "139183", "139187", "139190", "139191", "139193", "139197", "139200", "139202", "139205", "139207", "139209", "139210", "139211", "139212", "139213", "139214", "139218", "139219", "139220", "139221", "139223", "139226", "139231", "139233", "139234", "139236", "139237", "139238", "139240", "139244", "139248", "139249", "139250", "139251", "139252", "139255", "139256", "139257", "139262", "139263", "139265", "139266", "139270", "139272", "139275", "139278", "139280", "139281", "139282", "139284", "139285", "139286", "139288", "139290", "139291", "139292", "139294", "139295", "139297", "139299", "139301", "139304", "139306", "139308", "139310", "139311", "139315", "139320", "139321", "139322", "139324", "139327", "139329", "139331", "139332", "139333", "139335", "139340", "139343", "139344", "139345", "139347", "139348", "139350", "139351", "139353", "139354", "139355", "139356", "139357", "139360", "139361", "139364", "139367", "139372", "139374", "139375", "139376", "139382", "139384", "139388", "139389", "139390", "139395", "139396", "139397", "139398", "139400", "139402", "139403", "139404", "139405", "139408", "139409", "139410", "139411", "139413", "139416", "139417", "139418", "139419", "139420", "139421", "139422", "139424", "139427", "139429", "139432", "139434", "139436", "139437", "139443", "139444", "139447", "139450", "139453", "139454", "139456", "139459", "139461", "139462", "139465", "139469", "139471", "139473", "139476", "139479", "139480", "139481", "139487", "139488", "139491", "139492", "139494", "139495", "139496", "139497", "139498", "139500", "139503", "139504", "139513", "139515", "139516", "139517", "139520", "139521", "139524", "139525", "139527", "139529", "139531", "139532", "139533", "139534", "139536", "139537", "139538", "139541", "139542", "139544", "139545", "139546", "139549", "139550", "139552", "139555", "139556", "139558", "139560", "139561", "139562", "139563", "139564", "139565", "139566", "139568", "139569", "139570", "139571", "139573", "139575", "139576", "139579", "139581", "139583", "139585", "139587", "139588", "139591", "139592", "139595", "139597", "139602", "139603", "139606", "139608", "139609", "139610", "139614", "139615", "139616", "139617", "139618", "139622", "139625", "139626", "139629", "139630", "139631", "139632", "139633", "139634", "139635", "139638", "139644", "139645", "139647", "139648", "139650", "139654", "139655", "139656", "139658", "139660", "139661", "139662", "139663", "139664", "139665", "139666", "139668", "139673", "139675", "139676", "139680", "139681", "139683", "139684", "139686", "139687", "139688", "139689", "139690", "139691", "139692", "139694", "139696", "139698", "139699", "139700", "139701", "139702", "139703", "139704", "139707", "139708", "139709", "139711", "139713", "139715", "139718", "139721", "139722", "139723", "139726", "139727", "139729", "139731", "139740", "139741", "139742", "139744", "139745", "139750", "139752", "139753", "139754", "139755", "139757", "139759", "139760", "139762", "139764", "139765", "139767", "139769", "139770", "139772", "139778", "139779", "139782", "139783", "139784", "139785", "139790", "139793", "139795", "139799", "139800", "139804", "139805", "139810", "139813", "139816", "139817", "139818", "139820", "139822", "139823", "139824", "139825", "139826", "139827", "139828", "139830", "139831", "139832", "139833", "139837", "139839", "139840", "139841", "139843", "139844", "139845", "139846", "139847", "139848", "139849", "139850", "139852", "139853", "139854", "139855", "139856", "139858", "139863", "139865", "139866", "139868", "139872", "139873", "139874", "139876", "139879", "139881", "139885", "139888", "139890", "139892", "139894", "139895", "139897", "139899", "139901", "139904", "139905", "139909", "139912", "139916", "139919", "139921", "139925", "139926", "139928", "139929", "139930", "139933", "139934", "139937", "139938", "139940", "139941", "139942", "139943", "139945", "139946", "139947", "139948", "139950", "139951", "139953", "139954", "139962", "139966", "139968", "139970", "139971", "139972", "139973", "139978", "139979", "139980", "139985", "139986", "139987", "139989", "139995", "139996", "139998", "139999", "140000", "140001", "140002", "140004", "140005", "140006", "140009", "140010", "140011", "140012", "140014", "140020", "140021", "140022", "140028", "140029", "140032", "140033", "140036", "140039", "140042", "140043", "140044", "140047", "140048", "140050", "140051", "140053", "140054", "140056", "140060", "140061", "140063", "140064", "140065", "140066", "140069", "140071", "140073", "140075", "140076", "140082", "140084", "140085", "140086", "140092", "140093", "140096", "140097", "140098", "140099", "140100", "140103", "140106", "140107", "140113", "140114", "140116", "140120", "140122", "140123", "140126", "140127", "140128", "140129", "140130", "140139", "140140", "140143", "140144", "140147", "140150", "140154", "140158", "140159", "140161", "140164", "140166", "140167", "140168", "140169", "140171", "140172", "140175", "140178", "140180", "140181", "140188", "140194", "140196", "140198", "140199", "140200", "140205", "140206", "140207", "140208", "140209", "140211", "140212", "140215", "140216", "140220", "140221", "140222", "140225", "140226", "140231", "140233", "140234", "140237", "140239", "140240", "140241", "140242", "140243", "140245", "140247", "140254", "140255", "140257", "140259", "140260", "140263", "140265", "140266", "140267", "140272", "140273", "140276", "140277", "140281", "140282", "140284", "140287", "140289", "140292", "140294", "140295", "140301", "140302", "140308", "140310", "140312", "140317", "140321", "140322", "140323", "140324", "140326", "140330", "140331", "140332", "140333", "140334", "140338", "140339", "140342", "140344", "140346", "140348", "140351", "140352", "140353", "140354", "140356", "140358", "140360", "140363", "140367", "140368", "140372", "140375", "140376", "140381", "140382", "140383", "140386", "140390", "140392", "140396", "140397", "140399", "140400", "140402", "140405", "140408", "140410", "140411", "140413", "140414", "140415", "140417", "140419", "140423", "140426", "140427", "140428", "140430", "140432", "140436", "140443", "140444", "140445", "140448", "140449", "140451", "140452", "140457", "140458", "140459", "140460", "140461", "140464", "140467", "140468", "140469", "140470", "140474", "140481", "140482", "140485", "140486", "140488", "140490", "140493", "140495", "140499", "140500", "140502", "140505", "140508", "140509", "140512", "140513", "140514", "140515", "140518", "140519", "140520", "140523", "140524", "140525", "140526", "140528", "140529", "140531", "140532", "140533", "140535", "140536", "140538", "140540", "140544", "140550", "140551", "140553", "140554", "140555", "140563", "140564", "140570", "140572", "140577", "140578", "140579", "140584", "140586", "140591", "140593", "140595", "140596", "140597", "140598", "140600", "140601", "140603", "140605", "140608", "140610", "140613", "140614", "140616", "140617", "140618", "140622", "140623", "140624", "140625", "140626", "140628", "140632", "140633", "140634", "140636", "140637", "140638", "140641", "140642", "140643", "140646", "140647", "140648", "140650", "140653", "140655", "140658", "140659", "140660", "140662", "140664", "140666", "140672", "140673", "140677", "140679", "140684", "140688", "140689", "140690", "140691", "140695", "140696", "140697", "140698", "140700", "140704", "140706", "140708", "140711", "140712", "140713", "140714", "140716", "140717", "140719", "140720", "140722", "140725", "140727", "140728", "140729", "140732", "140734", "140737", "140740", "140741", "140743", "140744", "140747", "140748", "140749", "140752", "140754", "140758", "140762", "140763", "140765", "140766", "140771", "140772", "140773", "140780", "140783", "140785", "140787", "140789", "140796", "140798", "140799", "140800", "140801", "140802", "140803", "140807", "140808", "140809", "140810", "140812", "140813", "140814", "140817", "140818", "140819", "140820", "140821", "140822", "140824", "140826", "140828", "140831", "140833", "140835", "140836", "140837", "140838", "140840", "140842", "140843", "140845", "140847", "140851", "140852", "140855", "140857", "140858", "140859", "140860", "140861", "140864", "140871", "140872", "140875", "140876", "140879", "140880", "140881", "140882", "140885", "140886", "140887", "140889", "140891", "140892", "140894", "140895", "140900", "140901", "140903", "140905", "140906", "140907", "140908", "140910", "140911", "140912", "140913", "140916", "140917", "140930", "140931", "140934", "140935", "140937", "140939", "140943", "140945", "140946", "140947", "140948", "140955", "140956", "140958", "140960", "140961", "140963", "140964", "140965", "140966", "140967", "140968", "140969", "140970", "140971", "140974", "140976", "140977", "140978", "140979", "140981", "140982", "140983", "140984", "140987", "140989", "140991", "140992", "140996", "140998", "140999", "141000", "141002", "141003", "141004", "141006", "141011", "141012", "141013", "141014", "141015", "141016", "141017", "141018", "141019", "141020", "141021", "141022", "141023", "141025", "141027", "141031", "141032", "141033", "141035", "141036", "141039", "141040", "141044", "141046", "141049", "141050", "141051", "141053", "141056", "141058", "141059", "141061", "141062", "141063", "141066", "141068", "141070", "141073", "141075", "141076", "141082", "141084", "141085", "141088", "141091", "141092", "141093", "141094", "141095", "141096", "141098", "141104", "141105", "141106", "141108", "141109", "141114", "141117", "141123", "141125", "141127", "141129", "141130", "141131", "141132", "141133", "141134", "141136", "141140", "141141", "141145", "141150", "141152", "141153", "141154", "141155", "141160", "141162", "141164", "141165", "141167", "141168", "141169", "141170", "141172", "141174", "141175", "141176", "141178", "141180", "141181", "141182", "141184", "141185", "141190", "141193", "141194", "141204", "141206", "141208", "141211", "141212", "141218", "141219", "141221", "141222", "141223", "141228", "141232", "141234", "141238", "141242", "141245", "141246", "141251", "141252", "141254", "141256", "141257", "141263", "141264", "141266", "141267", "141268", "141270", "141272", "141273", "141274", "141275", "141277", "141278", "141279", "141280", "141283", "141285", "141287", "141289", "141293", "141294", "141295", "141297", "141298", "141299", "141300", "141303", "141308", "141309", "141310", "141311", "141313", "141317", "141318", "141319", "141321", "141323", "141324", "141325", "141326", "141331", "141333", "141337", "141338", "141339", "141343", "141345", "141350", "141351", "141352", "141354", "141355", "141356", "141357", "141364", "141365", "141366", "141369", "141370", "141371", "141372", "141375", "141376", "141378", "141379", "141386", "141387", "141389", "141390", "141398", "141399", "141402", "141403", "141407", "141408", "141418", "141419", "141423", "141426", "141427", "141428", "141429", "141430", "141431", "141432", "141433", "141435", "141439", "141440", "141441", "141443", "141445", "141447", "141449", "141450", "141451", "141452", "141453", "141454", "141455", "141456", "141457", "141459", "141460", "141462", "141467", "141468", "141470", "141471", "141472", "141473", "141474", "141476", "141478", "141479", "141480", "141481", "141486", "141487", "141489", "141490", "141491", "141495", "141496", "141498", "141499", "141503", "141506", "141507", "141509", "141512", "141519", "141522", "141526", "141532", "141533", "141535", "141536", "141537", "141538", "141540", "141541", "141543", "141544", "141545", "141549", "141550", "141552", "141553", "141554", "141558", "141560", "141561", "141562", "141563", "141564", "141565", "141568", "141569", "141570", "141572", "141573", "141575", "141576", "141577", "141580", "141582", "141583", "141586", "141587", "141588", "141589", "141592", "141593", "141595", "141600", "141601", "141602", "141604", "141605", "141607", "141610", "141612", "141613", "141615", "141616", "141618", "141621", "141622", "141623", "141626", "141629", "141630", "141632", "141637", "141641", "141642", "141643", "141645", "141648", "141651", "141652", "141653", "141655", "141657", "141660", "141662", "141663", "141665", "141667", "141671", "141673", "141674", "141682", "141683", "141685", "141686", "141687", "141690", "141691", "141692", "141693", "141704", "141706", "141708", "141711", "141712", "141714", "141718", "141720", "141721", "141725", "141729", "141730", "141731", "141732", "141734", "141736", "141737", "141738", "141741", "141742", "141743", "141744", "141747", "141750", "141754", "141757", "141760", "141763", "141769", "141771", "141772", "141773", "141775", "141778", "141781", "141782", "141786", "141787", "141788", "141789", "141790", "141791", "141792", "141794", "141796", "141799", "141802", "141806", "141807", "141808", "141810", "141811", "141813", "141814", "141815", "141819", "141822", "141824", "141825", "141826", "141827", "141828", "141830", "141831", "141832", "141835", "141837", "141838", "141842", "141843", "141845", "141847", "141848", "141850", "141851", "141852", "141853", "141854", "141859", "141860", "141864", "141867", "141868", "141870", "141871", "141875", "141876", "141878", "141882", "141883", "141884", "141885", "141889", "141891", "141893", "141894", "141895", "141899", "141901", "141906", "141907", "141910", "141916", "141918", "141922", "141923", "141926", "141927", "141929", "141930", "141933", "141934", "141935", "141936", "141939", "141940", "141942", "141946", "141947", "141948", "141951", "141953", "141959", "141963", "141964", "141965", "141966", "141968", "141969", "141970", "141973", "141976", "141978", "141980", "141981", "141982", "141985", "141986", "141987", "141988", "141990", "141991", "141992", "141993", "141994", "141995", "141997", "142001", "142005", "142007", "142009", "142010", "142013", "142014", "142015", "142017", "142018", "142023", "142024", "142027", "142031", "142032", "142033", "142035", "142037", "142042", "142043", "142045", "142047", "142050", "142051", "142053", "142055", "142057", "142060", "142061", "142063", "142067", "142068", "142069", "142070", "142075", "142081", "142084", "142085", "142087", "142089", "142090", "142092", "142094", "142097", "142100", "142102", "142103", "142107", "142108", "142111", "142112", "142117", "142118", "142119", "142120", "142122", "142123", "142125", "142126", "142131", "142132", "142136", "142138", "142139", "142142", "142145", "142147", "142148", "142151", "142154", "142155", "142156", "142157", "142158", "142159", "142160", "142164", "142165", "142167", "142168", "142171", "142172", "142173", "142175", "142176", "142177", "142178", "142180", "142182", "142183", "142184", "142186", "142188", "142191", "142192", "142193", "142198", "142199", "142201", "142202", "142205", "142208", "142210", "142214", "142215", "142216", "142217", "142218", "142221", "142225", "142229", "142230", "142231", "142232", "142233", "142236", "142239", "142241", "142245", "142246", "142247", "142251", "142252", "142257", "142259", "142261", "142262", "142263", "142269", "142270", "142271", "142273", "142274", "142275", "142276", "142283", "142286", "142287", "142291", "142292", "142293", "142294", "142295", "142297", "142298", "142299", "142304", "142305", "142308", "142310", "142311", "142312", "142313", "142314", "142316", "142317", "142318", "142320", "142323", "142324", "142325", "142329", "142330", "142331", "142332", "142333", "142337", "142338", "142342", "142345", "142347", "142349", "142353", "142355", "142357", "142358", "142359", "142363", "142364", "142366", "142367", "142370", "142373", "142374", "142376", "142377", "142379", "142381", "142382", "142383", "142384", "142385", "142386", "142387", "142388", "142392", "142393", "142395", "142396", "142397", "142400", "142401", "142402", "142405", "142408", "142409", "142412", "142413", "142416", "142419", "142422", "142423", "142425", "142430", "142431", "142433", "142434", "142435", "142438", "142442", "142443", "142444", "142446", "142448", "142450", "142451", "142453", "142456", "142458", "142459", "142463", "142464", "142466", "142467", "142469", "142473", "142474", "142476", "142478", "142482", "142484", "142486", "142487", "142488", "142491", "142493", "142497", "142498", "142502", "142504", "142506", "142507", "142510", "142511", "142514", "142517", "142519", "142521", "142524", "142530", "142531", "142532", "142535", "142536", "142537", "142538", "142539", "142542", "142543", "142545", "142547", "142548", "142551", "142554", "142555", "142557", "142558", "142560", "142563", "142566", "142567", "142569", "142570", "142571", "142572", "142573", "142576", "142578", "142580", "142581", "142583", "142585", "142589", "142590", "142591", "142593", "142597", "142598", "142599", "142600", "142604", "142606", "142607", "142609", "142610", "142614", "142615", "142619", "142620", "142623", "142624", "142627", "142628", "142629", "142630", "142632", "142633", "142636", "142637", "142639", "142640", "142643", "142644", "142645", "142646", "142649", "142653", "142655", "142658", "142662", "142663", "142664", "142668", "142669", "142671", "142672", "142674", "142675", "142676", "142680", "142681", "142682", "142683", "142684", "142687", "142688", "142690", "142691", "142693", "142694", "142696", "142699", "142701", "142703", "142704", "142709", "142716", "142717", "142719", "142720", "142722", "142726", "142727", "142728", "142729", "142737", "142740", "142742", "142743", "142745", "142749", "142751", "142752", "142753", "142754", "142755", "142761", "142765", "142766", "142771", "142772", "142774", "142775", "142776", "142777", "142778", "142781", "142782", "142785", "142786", "142787", "142791", "142795", "142798", "142799", "142803", "142806", "142808", "142810", "142812", "142813", "142815", "142817", "142818", "142819", "142824", "142826", "142834", "142835", "142837", "142839", "142840", "142841", "142842", "142843", "142844", "142845", "142846", "142847", "142849", "142850", "142852", "142854", "142855", "142860", "142861", "142862", "142864", "142868", "142869", "142871", "142874", "142875", "142877", "142878", "142879", "142881", "142882", "142883", "142886", "142887", "142890", "142895", "142897", "142898", "142900", "142902", "142903", "142905", "142907", "142909", "142914", "142916", "142917", "142918", "142919", "142920", "142921", "142923", "142926", "142929", "142930", "142932", "142933", "142937", "142942", "142943", "142944", "142945", "142946", "142947", "142949", "142950", "142952", "142955", "142956", "142959", "142960", "142962", "142967", "142970", "142971", "142974", "142975", "142977", "142980", "142982", "142985", "142989", "142990", "142991", "142992", "143000", "143002", "143003", "143004", "143006", "143007", "143008", "143009", "143010", "143011", "143013", "143014", "143015", "143018", "143021", "143022", "143024", "143027", "143028", "143030", "143032", "143036", "143038", "143040", "143041", "143043", "143050", "143051", "143053", "143054", "143058", "143059", "143064", "143066", "143068", "143070", "143071", "143075", "143080", "143084", "143088", "143091", "143093", "143094", "143095", "143097", "143100", "143107", "143109", "143110", "143111", "143112", "143116", "143118", "143119", "143122", "143123", "143125", "143127", "143129", "143130", "143131", "143137", "143138", "143139", "143140", "143141", "143144", "143145", "143146", "143149", "143150", "143151", "143155", "143157", "143158", "143159", "143161", "143164", "143166", "143167", "143171", "143172", "143174", "143177", "143181", "143184", "143185", "143186", "143188", "143189", "143191", "143192", "143195", "143199", "143200", "143203", "143204", "143205", "143208", "143209", "143211", "143214", "143218", "143221", "143222", "143223", "143225", "143226", "143231", "143233", "143234", "143237", "143238", "143239", "143240", "143241", "143243", "143244", "143248", "143249", "143250", "143254", "143255", "143263", "143268", "143271", "143273", "143275", "143277", "143280", "143282", "143283", "143287", "143290", "143291", "143294", "143295", "143299", "143302", "143303", "143305", "143307", "143313", "143316", "143319", "143321", "143322", "143323", "143327", "143329", "143335", "143338", "143339", "143340", "143341", "143345", "143347", "143351", "143354", "143356", "143357", "143358", "143359", "143362", "143363", "143364", "143366", "143370", "143373", "143374", "143378", "143379", "143380", "143383", "143388", "143389", "143391", "143393", "143396", "143397", "143400", "143401", "143406", "143409", "143410", "143411", "143414", "143417", "143423", "143428", "143430", "143431", "143432", "143433", "143440", "143442", "143445", "143446", "143447", "143449", "143451", "143453", "143455", "143458", "143460", "143463", "143466", "143467", "143469", "143471", "143476", "143477", "143478", "143483", "143484", "143486", "143487", "143489", "143491", "143492", "143494", "143497", "143500", "143501", "143504", "143505", "143506", "143508", "143511", "143514", "143516", "143518", "143519", "143520", "143524", "143525", "143531", "143532", "143533", "143534", "143536", "143539", "143543", "143545", "143546", "143547", "143552", "143553", "143556", "143557", "143559", "143560", "143561", "143563", "143564", "143566", "143567", "143569", "143574", "143575", "143581", "143582", "143584", "143585", "143588", "143589", "143593", "143594", "143595", "143598", "143600", "143603", "143604", "143605", "143609", "143610", "143613", "143614", "143616", "143617", "143618", "143621", "143624", "143625", "143626", "143627", "143629", "143630", "143631", "143632", "143633", "143634", "143635", "143639", "143643", "143644", "143647", "143648", "143649", "143652", "143653", "143654", "143655", "143657", "143658", "143662", "143663", "143666", "143670", "143672", "143673", "143676", "143681", "143682", "143684", "143686", "143688", "143692", "143694", "143697", "143700", "143701", "143705", "143709", "143712", "143715", "143716", "143717", "143718", "143720", "143722", "143723", "143724", "143725", "143726", "143728", "143729", "143730", "143731", "143735", "143736", "143738", "143739", "143741", "143744", "143746", "143748", "143750", "143751", "143752", "143754", "143765", "143766", "143770", "143772", "143774", "143775", "143776", "143777", "143778", "143779", "143783", "143784", "143785", "143786", "143788", "143789", "143793", "143794", "143795", "143797", "143798", "143802", "143803", "143804", "143805", "143806", "143807", "143811", "143814", "143815", "143817", "143821", "143822", "143823", "143825", "143826", "143829", "143831", "143832", "143833", "143835", "143838", "143839", "143840", "143841", "143842", "143843", "143844", "143845", "143846", "143848", "143850", "143851", "143853", "143854", "143856", "143857", "143858", "143861", "143863", "143864", "143866", "143867", "143872", "143873", "143875", "143876", "143877", "143878", "143879", "143880", "143881", "143882", "143883", "143888", "143889", "143890", "143891", "143892", "143893", "143894", "143897", "143898", "143899", "143900", "143902", "143903", "143905", "143906", "143909", "143912", "143913", "143914", "143915", "143917", "143918", "143919", "143920", "143924", "143926", "143927", "143930", "143937", "143939", "143942", "143943", "143944", "143946", "143947", "143949", "143950", "143953", "143954", "143959", "143960", "143961", "143962", "143963", "143964", "143965", "143966", "143967", "143969", "143971", "143973", "143974", "143976", "143978", "143979", "143980", "143982", "143983", "143986", "143990", "143992", "143993", "143995", "143996", "143997", "143998", "144002", "144003", "144006", "144012", "144013", "144014", "144015", "144017", "144018", "144020", "144021", "144028", "144029", "144031", "144032", "144034", "144037", "144038", "144039", "144040", "144041", "144042", "144047", "144049", "144054", "144056", "144057", "144058", "144060", "144063", "144064", "144068", "144070", "144071", "144073", "144074", "144077", "144078", "144081", "144082", "144087", "144092", "144095", "144096", "144097", "144098", "144100", "144101", "144102", "144105", "144106", "144108", "144109", "144110", "144114", "144115", "144116", "144117", "144121", "144124", "144127", "144128", "144129", "144131", "144132", "144136", "144138", "144142", "144144", "144145", "144147", "144148", "144152", "144153", "144154", "144156", "144163", "144165", "144167", "144169", "144172", "144174", "144177", "144179", "144182", "144183", "144184", "144185", "144186", "144187", "144192", "144193", "144195", "144196", "144197", "144199", "144200", "144205", "144206", "144207", "144208", "144209", "144211", "144212", "144213", "144216", "144218", "144219", "144220", "144221", "144222", "144223", "144225", "144226", "144228", "144231", "144232", "144233", "144234", "144235", "144238", "144239", "144242", "144243", "144244", "144248", "144252", "144253", "144254", "144257", "144258", "144259", "144260", "144263", "144265", "144268", "144269", "144270", "144271", "144273", "144276", "144277", "144278", "144285", "144286", "144287", "144288", "144290", "144294", "144296", "144298", "144301", "144303", "144305", "144306", "144307", "144311", "144312", "144313", "144314", "144315", "144316", "144317", "144318", "144319", "144321", "144322", "144323", "144324", "144327", "144328", "144334", "144335", "144336", "144338", "144339", "144340", "144341", "144342", "144344", "144345", "144347", "144352", "144355", "144357", "144358", "144359", "144360", "144361", "144362", "144364", "144365", "144368", "144369", "144371", "144374", "144376", "144377", "144378", "144383", "144386", "144387", "144389", "144390", "144391", "144392", "144394", "144395", "144399", "144400", "144401", "144402", "144405", "144406", "144408", "144409", "144410", "144412", "144417", "144418", "144419", "144420", "144423", "144424", "144425", "144426", "144428", "144429", "144434", "144436", "144439", "144440", "144443", "144445", "144447", "144449", "144451", "144452", "144454", "144455", "144456", "144457", "144460", "144461", "144463", "144464", "144467", "144468", "144469", "144471", "144473", "144474", "144475", "144481", "144483", "144485", "144486", "144487", "144489", "144490", "144493", "144494", "144495", "144497", "144498", "144499", "144500", "144501", "144502", "144503", "144504", "144505", "144507", "144508", "144509", "144510", "144511", "144512", "144515", "144516", "144517", "144519", "144522", "144523", "144525", "144532", "144533", "144535", "144536", "144538", "144540", "144545", "144547", "144551", "144552", "144553", "144554", "144555", "144559", "144560", "144561", "144562", "144563", "144564", "144565", "144566", "144568", "144570", "144571", "144572", "144576", "144577", "144581", "144587", "144588", "144591", "144592", "144593", "144594", "144596", "144597", "144598", "144602", "144604", "144605", "144606", "144607", "144608", "144609", "144610", "144612", "144614", "144616", "144620", "144621", "144622", "144624", "144626", "144627", "144628", "144629", "144631", "144633", "144636", "144638", "144639", "144643", "144645", "144648", "144650", "144651", "144655", "144657", "144658", "144661", "144662", "144663", "144664", "144666", "144668", "144672", "144673", "144675", "144676", "144678", "144682", "144683", "144685", "144689", "144690", "144692", "144694", "144699", "144701", "144702", "144704", "144708", "144712", "144713", "144714", "144715", "144717", "144718", "144720", "144725", "144730", "144733", "144735", "144736", "144737", "144739", "144740", "144743", "144748", "144753", "144754", "144756", "144761", "144762", "144763", "144765", "144766", "144769", "144770", "144773", "144774", "144779", "144780", "144782", "144785", "144791", "144794", "144795", "144799", "144801", "144802", "144804", "144806", "144807", "144809", "144810", "144812", "144814", "144816", "144818", "144819", "144820", "144822", "144823", "144824", "144827", "144828", "144831", "144832", "144834", "144838", "144841", "144843", "144850", "144853", "144854", "144860", "144862", "144868", "144871", "144872", "144874", "144875", "144876", "144878", "144879", "144882", "144883", "144884", "144885", "144889", "144890", "144892", "144893", "144895", "144898", "144899", "144900", "144901", "144903", "144905", "144906", "144907", "144908", "144911", "144916", "144919", "144921", "144922", "144923", "144927", "144928", "144931", "144933", "144935", "144938", "144940", "144941", "144942", "144946", "144947", "144949", "144950", "144951", "144952", "144954", "144957", "144958", "144960", "144961", "144962", "144966", "144968", "144970", "144971", "144973", "144974", "144975", "144977", "144979", "144981", "144982", "144984", "144987", "144990", "144991", "144992", "144996", "145000", "145001", "145003", "145005", "145007", "145008", "145009", "145010", "145013", "145015", "145016", "145018", "145019", "145021", "145023", "145024", "145025", "145026", "145027", "145030", "145031", "145032", "145033", "145034", "145035", "145038", "145043", "145044", "145045", "145047", "145049", "145050", "145051", "145055", "145057", "145058", "145061", "145063", "145064", "145066", "145067", "145073", "145074", "145075", "145077", "145079", "145080", "145082", "145083", "145085", "145088", "145092", "145093", "145096", "145099", "145100", "145101", "145104", "145105", "145106", "145109", "145111", "145112", "145115", "145117", "145118", "145119", "145121", "145123", "145125", "145126", "145128", "145134", "145135", "145137", "145138", "145139", "145140", "145141", "145142", "145145", "145146", "145148", "145149", "145150", "145152", "145157", "145158", "145161", "145162", "145164", "145167", "145168", "145169", "145170", "145171", "145173", "145176", "145177", "145179", "145182", "145184", "145186", "145187", "145190", "145194", "145196", "145197", "145198", "145199", "145201", "145202", "145203", "145205", "145206", "145207", "145209", "145210", "145212", "145214", "145215", "145216", "145217", "145218", "145220", "145223", "145226", "145227", "145229", "145235", "145239", "145241", "145242", "145243", "145245", "145248", "145249", "145251", "145252", "145253", "145254", "145256", "145257", "145259", "145262", "145263", "145267", "145270", "145275", "145277", "145278", "145282", "145285", "145286", "145287", "145290", "145291", "145292", "145293", "145294", "145295", "145296", "145297", "145300", "145301", "145302", "145304", "145305", "145310", "145311", "145312", "145313", "145314", "145315", "145316", "145317", "145318", "145319", "145321", "145322", "145323", "145327", "145330", "145331", "145335", "145338", "145344", "145345", "145347", "145349", "145350", "145351", "145352", "145354", "145355", "145360", "145361", "145363", "145364", "145365", "145367", "145369", "145372", "145376", "145378", "145379", "145380", "145384", "145387", "145388", "145390", "145391", "145393", "145394", "145399", "145400", "145402", "145403", "145404", "145407", "145408", "145409", "145411", "145414", "145415", "145416", "145417", "145421", "145423", "145424", "145426", "145427", "145430", "145433", "145434", "145436", "145437", "145438", "145439", "145441", "145442", "145443", "145444", "145445", "145449", "145450", "145452", "145453", "145455", "145456", "145458", "145460", "145461", "145462", "145467", "145468", "145470", "145472", "145478", "145479", "145482", "145484", "145487", "145490", "145491", "145492", "145494", "145496", "145497", "145502", "145508", "145510", "145511", "145512", "145513", "145515", "145517", "145518", "145520", "145521", "145524", "145526", "145528", "145532", "145535", "145536", "145537", "145540", "145541", "145542", "145544", "145545", "145548", "145549", "145551", "145558", "145559", "145561", "145562", "145563", "145564", "145565", "145567", "145568", "145575", "145578", "145581", "145582", "145584", "145585", "145586", "145587", "145589", "145591", "145592", "145593", "145595", "145597", "145599", "145601", "145602", "145608", "145609", "145610", "145612", "145615", "145617", "145621", "145624", "145625", "145626", "145627", "145629", "145630", "145633", "145634", "145636", "145638", "145639", "145640", "145642", "145643", "145644", "145646", "145647", "145648", "145649", "145657", "145659", "145660", "145661", "145663", "145664", "145665", "145667", "145668", "145669", "145672", "145673", "145674", "145676", "145677", "145681", "145682", "145684", "145685", "145687", "145688", "145690", "145692", "145694", "145695", "145697", "145699", "145704", "145705", "145707", "145708", "145709", "145710", "145714", "145715", "145718", "145720", "145721", "145723", "145724", "145725", "145729", "145731", "145732", "145733", "145734", "145735", "145736", "145738", "145739", "145741", "145745", "145751", "145752", "145753", "145754", "145756", "145757", "145758", "145759", "145762", "145764", "145765", "145766", "145768", "145769", "145770", "145771", "145774", "145778", "145779", "145782", "145784", "145785", "145786", "145787", "145788", "145794", "145795", "145797", "145798", "145804", "145806", "145808", "145810", "145811", "145812", "145813", "145816", "145818", "145819", "145825", "145826", "145828", "145832", "145833", "145834", "145835", "145836", "145842", "145844", "145845", "145846", "145847", "145848", "145849", "145851", "145854", "145856", "145857", "145859", "145861", "145862", "145863", "145864", "145865", "145866", "145867", "145869", "145874", "145876", "145878", "145879", "145881", "145882", "145887", "145888", "145891", "145892", "145896", "145898", "145901", "145903", "145904", "145905", "145906", "145907", "145908", "145913", "145916", "145917", "145919", "145923", "145924", "145930", "145931", "145935", "145936", "145939", "145941", "145945", "145946", "145947", "145948", "145949", "145954", "145956", "145957", "145959", "145962", "145964", "145969", "145970", "145976", "145979", "145985", "145986", "145991", "145995", "145996", "145997", "146003", "146004", "146005", "146006", "146007", "146008", "146010", "146012", "146013", "146015", "146019", "146021", "146022", "146023", "146027", "146031", "146034", "146035", "146036", "146037", "146038", "146039", "146040", "146041", "146042", "146044", "146046", "146048", "146056", "146057", "146058", "146059", "146064", "146065", "146066", "146067", "146069", "146070", "146072", "146073", "146075", "146076", "146078", "146079", "146082", "146089", "146091", "146093", "146097", "146098", "146099", "146103", "146104", "146106", "146109", "146113", "146116", "146118", "146122", "146124", "146125", "146129", "146132", "146133", "146134", "146136", "146138", "146141", "146142", "146143", "146145", "146149", "146151", "146155", "146156", "146158", "146159", "146160", "146161", "146162", "146164", "146166", "146167", "146168", "146170", "146171", "146173", "146175", "146176", "146177", "146178", "146179", "146182", "146183", "146185", "146186", "146187", "146190", "146191", "146192", "146193", "146194", "146195", "146197", "146201", "146203", "146204", "146207", "146215", "146216", "146217", "146221", "146223", "146224", "146225", "146228", "146229", "146234", "146235", "146236", "146237", "146238", "146239", "146240", "146242", "146244", "146246", "146247", "146248", "146250", "146253", "146254", "146255", "146259", "146260", "146263", "146265", "146269", "146271", "146273", "146274", "146275", "146280", "146286", "146287", "146291", "146292", "146293", "146294", "146297", "146298", "146299", "146300", "146301", "146302", "146305", "146306", "146311", "146312", "146315", "146316", "146317", "146320", "146322", "146324", "146326", "146327", "146328", "146330", "146331", "146332", "146333", "146335", "146337", "146338", "146344", "146345", "146347", "146349", "146350", "146352", "146354", "146356", "146357", "146361", "146367", "146369", "146370", "146372", "146373", "146374", "146378", "146379", "146387", "146388", "146390", "146394", "146396", "146400", "146401", "146403", "146404", "146409", "146411", "146414", "146415", "146416", "146417", "146424", "146427", "146429", "146430", "146431", "146433", "146435", "146437", "146438", "146439", "146441", "146442", "146443", "146449", "146451", "146455", "146456", "146460", "146463", "146471", "146472", "146475", "146477", "146478", "146479", "146480", "146481", "146483", "146484", "146486", "146488", "146491", "146494", "146497", "146498", "146499", "146501", "146503", "146506", "146507", "146509", "146511", "146514", "146516", "146518", "146519", "146522", "146524", "146525", "146527", "146531", "146532", "146534", "146535", "146536", "146537", "146540", "146542", "146543", "146544", "146546", "146547", "146550", "146551", "146554", "146555", "146556", "146557", "146558", "146561", "146564", "146565", "146569", "146573", "146574", "146577", "146579", "146581", "146582", "146584", "146588", "146591", "146594", "146596", "146597", "146599", "146600", "146601", "146602", "146603", "146605", "146606", "146607", "146608", "146609", "146610", "146612", "146613", "146615", "146618", "146619", "146628", "146631", "146634", "146636", "146637", "146639", "146640", "146642", "146643", "146644", "146645", "146648", "146653", "146656", "146657", "146660", "146662", "146664", "146668", "146669", "146672", "146674", "146677", "146679", "146683", "146687", "146688", "146689", "146692", "146697", "146698", "146700", "146702", "146703", "146705", "146707", "146708", "146709", "146710", "146711", "146712", "146713", "146716", "146718", "146720", "146722", "146729", "146731", "146732", "146733", "146734", "146735", "146739", "146741", "146742", "146743", "146744", "146746", "146748", "146749", "146752", "146753", "146758", "146759", "146760", "146766", "146768", "146771", "146774", "146778", "146779", "146781", "146782", "146783", "146784", "146785", "146787", "146788", "146789", "146791", "146793", "146796", "146798", "146800", "146801", "146808", "146810", "146811", "146813", "146819", "146820", "146823", "146825", "146826", "146828", "146830", "146832", "146833", "146836", "146838", "146840", "146843", "146846", "146847", "146849", "146850", "146852", "146853", "146854", "146855", "146856", "146857", "146859", "146860", "146861", "146863", "146864", "146867", "146876", "146877", "146878", "146879", "146880", "146881", "146886", "146888", "146889", "146891", "146892", "146894", "146896", "146899", "146901", "146902", "146906", "146907", "146908", "146909", "146910", "146912", "146915", "146917", "146918", "146921", "146922", "146925", "146928", "146930", "146932", "146934", "146935", "146938", "146946", "146947", "146950", "146951", "146952", "146955", "146956", "146958", "146960", "146961", "146962", "146964", "146965", "146967", "146969", "146970", "146971", "146973", "146975", "146976", "146977", "146978", "146980", "146982", "146983", "146987", "146988", "146990", "146992", "146994", "146997", "146998", "146999", "147000", "147001", "147002", "147003", "147005", "147006", "147007", "147009", "147011", "147013", "147015", "147018", "147020", "147021", "147022", "147023", "147027", "147031", "147033", "147034", "147038", "147041", "147042", "147044", "147045", "147047", "147048", "147050", "147051", "147052", "147053", "147055", "147059", "147064", "147065", "147068", "147070", "147073", "147075", "147082", "147084", "147088", "147089", "147090", "147092", "147093", "147099", "147101", "147102", "147103", "147105", "147107", "147109", "147111", "147112", "147113", "147120", "147121", "147122", "147128", "147129", "147130", "147131", "147132", "147134", "147135", "147140", "147141", "147143", "147147", "147148", "147154", "147155", "147156", "147162", "147166", "147171", "147175", "147177", "147180", "147181", "147182", "147184", "147188", "147189", "147190", "147191", "147192", "147194", "147195", "147196", "147198", "147200", "147201", "147202", "147203", "147205", "147208", "147213", "147214", "147216", "147218", "147221", "147222", "147224", "147225", "147227", "147228", "147229", "147230", "147231", "147234", "147235", "147236", "147238", "147242", "147247", "147248", "147249", "147250", "147254", "147255", "147256", "147260", "147263", "147264", "147265", "147266", "147268", "147270", "147271", "147272", "147273", "147277", "147282", "147286", "147294", "147296", "147297", "147298", "147300", "147301", "147302", "147305", "147307", "147311", "147316", "147318", "147323", "147325", "147328", "147330", "147332", "147333", "147335", "147336", "147339", "147340", "147341", "147342", "147343", "147345", "147349", "147351", "147352", "147354", "147356", "147358", "147363", "147364", "147373", "147375", "147376", "147378", "147379", "147380", "147382", "147387", "147389", "147392", "147395", "147396", "147397", "147401", "147402", "147408", "147411", "147412", "147413", "147414", "147417", "147419", "147421", "147422", "147423", "147424", "147425", "147426", "147429", "147431", "147435", "147436", "147437", "147438", "147439", "147440", "147441", "147442", "147443", "147448", "147449", "147455", "147457", "147458", "147462", "147465", "147466", "147467", "147468", "147476", "147478", "147482", "147483", "147484", "147485", "147486", "147487", "147488", "147490", "147492", "147494", "147496", "147498", "147499", "147500", "147501", "147503", "147504", "147507", "147510", "147511", "147513", "147515", "147519", "147521", "147522", "147524", "147526", "147529", "147530", "147532", "147533", "147534", "147535", "147536", "147537", "147539", "147541", "147542", "147543", "147545", "147546", "147549", "147551", "147552", "147555", "147560", "147562", "147564", "147565", "147567", "147569", "147571", "147573", "147576", "147577", "147580", "147582", "147584", "147586", "147590", "147592", "147593", "147594", "147601", "147606", "147607", "147608", "147611", "147613", "147614", "147615", "147619", "147620", "147621", "147622", "147625", "147630", "147632", "147633", "147634", "147637", "147641", "147644", "147645", "147647", "147648", "147650", "147651", "147655", "147657", "147658", "147659", "147660", "147663", "147664", "147665", "147672", "147673", "147678", "147679", "147682", "147686", "147687", "147689", "147692", "147696", "147698", "147700", "147706", "147709", "147713", "147715", "147716", "147719", "147720", "147721", "147723", "147725", "147726", "147728", "147731", "147733", "147734", "147735", "147736", "147740", "147741", "147744", "147745", "147746", "147747", "147748", "147753", "147754", "147757", "147758", "147759", "147761", "147762", "147764", "147765", "147766", "147771", "147772", "147773", "147774", "147775", "147776", "147778", "147780", "147781", "147783", "147785", "147786", "147789", "147790", "147794", "147796", "147797", "147799", "147800", "147801", "147804", "147805", "147806", "147808", "147811", "147812", "147813", "147814", "147817", "147819", "147821", "147822", "147824", "147825", "147826", "147829", "147831", "147832", "147833", "147834", "147840", "147842", "147844", "147846", "147847", "147849", "147850", "147853", "147854", "147855", "147857", "147860", "147863", "147864", "147865", "147868", "147869", "147870", "147873", "147874", "147879", "147880", "147881", "147882", "147884", "147886", "147887", "147890", "147895", "147896", "147898", "147899", "147901", "147903", "147904", "147905", "147906", "147909", "147912", "147913", "147914", "147915", "147916", "147917", "147924", "147927", "147932", "147936", "147938", "147939", "147940", "147942", "147947", "147949", "147954", "147957", "147958", "147961", "147962", "147963", "147965", "147968", "147969", "147972", "147973", "147974", "147975", "147978", "147979", "147981", "147982", "147985", "147986", "147988", "147990", "147991", "147993", "147994", "147997", "147998", "148001", "148003", "148004", "148006", "148010", "148012", "148014", "148017", "148019", "148026", "148027", "148029", "148032", "148034", "148035", "148038", "148039", "148041", "148042", "148043", "148044", "148047", "148048", "148049", "148051", "148052", "148057", "148058", "148063", "148065", "148067", "148068", "148069", "148070", "148074", "148078", "148082", "148083", "148087", "148090", "148091", "148094", "148095", "148097", "148099", "148101", "148105", "148107", "148111", "148112", "148118", "148128", "148130", "148133", "148135", "148140", "148142", "148143", "148145", "148147", "148149", "148150", "148153", "148155", "148157", "148158", "148159", "148161", "148162", "148163", "148164", "148165", "148166", "148167", "148171", "148172", "148173", "148177", "148180", "148182", "148183", "148185", "148187", "148188", "148190", "148192", "148194", "148195", "148196", "148197", "148198", "148199", "148200", "148202", "148203", "148204", "148205", "148207", "148215", "148218", "148219", "148220", "148228", "148230", "148234", "148237", "148238", "148239", "148240", "148243", "148244", "148246", "148247", "148248", "148249", "148251", "148252", "148254", "148258", "148260", "148261", "148263", "148264", "148275", "148276", "148277", "148279", "148280", "148284", "148285", "148286", "148287", "148288", "148289", "148291", "148292", "148293", "148294", "148299", "148300", "148302", "148304", "148310", "148311", "148313", "148314", "148315", "148316", "148318", "148319", "148320", "148322", "148327", "148332", "148333", "148336", "148337", "148340", "148342", "148343", "148346", "148347", "148348", "148349", "148353", "148355", "148356", "148357", "148359", "148363", "148365", "148366", "148367", "148368", "148370", "148372", "148373", "148374", "148376", "148377", "148380", "148381", "148386", "148389", "148390", "148391", "148394", "148395", "148397", "148399", "148402", "148403", "148405", "148406", "148407", "148412", "148413", "148415", "148417", "148420", "148424", "148425", "148431", "148433", "148435", "148436", "148437", "148438", "148439", "148441", "148448", "148449", "148450", "148451", "148452", "148454", "148459", "148460", "148461", "148464", "148465", "148468", "148470", "148474", "148476", "148478", "148479", "148481", "148482", "148486", "148488", "148491", "148492", "148495", "148497", "148503", "148504", "148506", "148508", "148510", "148511", "148512", "148514", "148515", "148518", "148522", "148525", "148526", "148527", "148529", "148532", "148534", "148537", "148539", "148540", "148546", "148547", "148548", "148549", "148550", "148551", "148552", "148553", "148555", "148557", "148559", "148562", "148564", "148565", "148566", "148570", "148571", "148574", "148575", "148576", "148578", "148580", "148581", "148583", "148584", "148588", "148590", "148592", "148594", "148595", "148597", "148598", "148599", "148601", "148602", "148608", "148609", "148610", "148611", "148612", "148615", "148617", "148618", "148620", "148627", "148628", "148631", "148633", "148635", "148637", "148640", "148643", "148645", "148646", "148651", "148652", "148653", "148661", "148662", "148663", "148669", "148670", "148671", "148675", "148676", "148678", "148681", "148685", "148687", "148688", "148689", "148692", "148694", "148697", "148699", "148702", "148705", "148706", "148707", "148708", "148709", "148714", "148716", "148718", "148719", "148721", "148723", "148724", "148725", "148726", "148727", "148728", "148729", "148733", "148734", "148736", "148737", "148739", "148744", "148745", "148746", "148748", "148749", "148750", "148753", "148756", "148757", "148760", "148761", "148762", "148763", "148764", "148765", "148766", "148768", "148769", "148770", "148774", "148777", "148778", "148779", "148781", "148782", "148784", "148785", "148788", "148789", "148791", "148793", "148794", "148795", "148796", "148797", "148800", "148804", "148806", "148809", "148810", "148811", "148814", "148815", "148816", "148818", "148822", "148826", "148830", "148831", "148834", "148835", "148836", "148837", "148838", "148842", "148843", "148846", "148847", "148850", "148851", "148852", "148853", "148855", "148859", "148860", "148863", "148867", "148869", "148873", "148874", "148876", "148879", "148882", "148884", "148885", "148886", "148887", "148889", "148892", "148893", "148896", "148898", "148901", "148902", "148904", "148905", "148906", "148908", "148911", "148912", "148916", "148917", "148918", "148920", "148922", "148923", "148926", "148931", "148932", "148933", "148936", "148937", "148939", "148940", "148941", "148943", "148944", "148946", "148948", "148949", "148950", "148953", "148954", "148961", "148968", "148969", "148970", "148974", "148976", "148977", "148979", "148980", "148983", "148985", "148987", "148988", "148991", "148994", "148996", "148997", "148998", "148999", "149001", "149002", "149003", "149004", "149005", "149006", "149010", "149011", "149013", "149016", "149017", "149018", "149019", "149020", "149023", "149024", "149028", "149036", "149039", "149043", "149044", "149046", "149048", "149051", "149054", "149055", "149056", "149057", "149058", "149061", "149063", "149064", "149065", "149066", "149071", "149077", "149079", "149082", "149083", "149085", "149087", "149089", "149096", "149098", "149099", "149102", "149103", "149105", "149106", "149109", "149110", "149111", "149113", "149115", "149118", "149121", "149122", "149125", "149130", "149132", "149134", "149141", "149143", "149144", "149146", "149147", "149150", "149151", "149152", "149153", "149155", "149157", "149158", "149159", "149163", "149164", "149165", "149166", "149167", "149168", "149173", "149174", "149176", "149177", "149179", "149181", "149182", "149184", "149185", "149190", "149191", "149193", "149194", "149195", "149201", "149204", "149208", "149209", "149210", "149212", "149214", "149217", "149218", "149222", "149224", "149227", "149228", "149229", "149231", "149232", "149235", "149236", "149238", "149241", "149243", "149244", "149246", "149250", "149252", "149253", "149255", "149257", "149258", "149263", "149266", "149268", "149269", "149271", "149275", "149277", "149279", "149287", "149288", "149290", "149291", "149292", "149293", "149294", "149299", "149302", "149304", "149305", "149306", "149307", "149308", "149315", "149316", "149320", "149323", "149325", "149326", "149327", "149330", "149331", "149334", "149335", "149337", "149340", "149341", "149345", "149346", "149349", "149350", "149351", "149352", "149355", "149356", "149357", "149358", "149359", "149361", "149364", "149365", "149366", "149367", "149368", "149371", "149373", "149375", "149377", "149379", "149380", "149381", "149383", "149384", "149387", "149388", "149390", "149391", "149392", "149395", "149396", "149397", "149401", "149402", "149404", "149405", "149406", "149407", "149408", "149409", "149411", "149412", "149413", "149414", "149415", "149416", "149417", "149418", "149419", "149420", "149421", "149427", "149431", "149433", "149436", "149437", "149440", "149444", "149447", "149451", "149452", "149454", "149455", "149456", "149460", "149461", "149462", "149467", "149468", "149469", "149472", "149473", "149476", "149480", "149485", "149487", "149488", "149489", "149490", "149498", "149500", "149502", "149505", "149506", "149510", "149513", "149516", "149517", "149520", "149522", "149523", "149525", "149526", "149527", "149528", "149529", "149531", "149534", "149538", "149540", "149541", "149543", "149547", "149550", "149553", "149554", "149555", "149558", "149560", "149562", "149569", "149574", "149576", "149577", "149578", "149582", "149583", "149586", "149589", "149593", "149594", "149596", "149600", "149601", "149602", "149604", "149605", "149609", "149610", "149612", "149614", "149616", "149618", "149619", "149620", "149622", "149623", "149624", "149629", "149630", "149631", "149633", "149638", "149654", "149656", "149657", "149658", "149660", "149661", "149669", "149670", "149671", "149672", "149674", "149675", "149676", "149679", "149680", "149681", "149682", "149685", "149687", "149688", "149689", "149692", "149693", "149694", "149696", "149697", "149698", "149699", "149703", "149704", "149705", "149709", "149710", "149719", "149722", "149723", "149726", "149729", "149732", "149734", "149737", "149740", "149743", "149745", "149747", "149748", "149749", "149750", "149751", "149752", "149754", "149757", "149758", "149759", "149760", "149761", "149763", "149764", "149765", "149768", "149769", "149770", "149771", "149773", "149774", "149775", "149777", "149778", "149779", "149780", "149783", "149784", "149786", "149790", "149793", "149794", "149795", "149796", "149797", "149798", "149800", "149803", "149807", "149808", "149809", "149810", "149811", "149812", "149813", "149814", "149818", "149820", "149822", "149825", "149828", "149829", "149831", "149832", "149834", "149835", "149836", "149838", "149841", "149842", "149843", "149846", "149848", "149849", "149852", "149854", "149855", "149856", "149857", "149859", "149862", "149863", "149865", "149866", "149868", "149869", "149875", "149877", "149884", "149885", "149887", "149888", "149892", "149895", "149896", "149898", "149899", "149900", "149901", "149905", "149910", "149911", "149915", "149916", "149921", "149923", "149924", "149926", "149928", "149929", "149930", "149937", "149939", "149940", "149943", "149944", "149948", "149949", "149952", "149953", "149954", "149955", "149958", "149960", "149962", "149964", "149979", "149980", "149983", "149984", "149986", "149990", "150000", "150001", "150004", "150009", "150010", "150011", "150015", "150016", "150018", "150019", "150021", "150023", "150025", "150027", "150028", "150031", "150033", "150037", "150039", "150040", "150041", "150042", "150049", "150050", "150051", "150052", "150055", "150056", "150057", "150058", "150060", "150061", "150064", "150065", "150066", "150067", "150070", "150072", "150073", "150074", "150075", "150076", "150080", "150083", "150085", "150086", "150087", "150089", "150090", "150091", "150092", "150093", "150094", "150095", "150096", "150101", "150103", "150106", "150107", "150108", "150111", "150113", "150114", "150116", "150119", "150132", "150133", "150134", "150135", "150138", "150140", "150141", "150142", "150143", "150149", "150160", "150161", "150162", "150166", "150169", "150172", "150174", "150176", "150179", "150181", "150185", "150187", "150188", "150190", "150191", "150192", "150193", "150194", "150195", "150203", "150205", "150207", "150209", "150211", "150212", "150215", "150216", "150217", "150220", "150226", "150227", "150228", "150231", "150232", "150233", "150234", "150240", "150242", "150243", "150245", "150248", "150250", "150252", "150253", "150255", "150257", "150259", "150260", "150261", "150263", "150264", "150266", "150269", "150273", "150274", "150275", "150276", "150278", "150281", "150284", "150285", "150286", "150289", "150298", "150299", "150303", "150304", "150305", "150306", "150307", "150308", "150311", "150312", "150314", "150316", "150317", "150320", "150321", "150322", "150323", "150325", "150326", "150327", "150329", "150330", "150332", "150333", "150334", "150336", "150338", "150341", "150342", "150343", "150345", "150346", "150347", "150349", "150350", "150352", "150353", "150354", "150355", "150357", "150358", "150360", "150367", "150368", "150371", "150374", "150380", "150386", "150389", "150390", "150391", "150394", "150395", "150396", "150397", "150398", "150399", "150402", "150404", "150405", "150407", "150410", "150413", "150414", "150417", "150419", "150421", "150422", "150423", "150426", "150427", "150428", "150436", "150438", "150440", "150443", "150444", "150446", "150451", "150452", "150456", "150457", "150460", "150461", "150462", "150463", "150464", "150466", "150471", "150473", "150474", "150476", "150477", "150479", "150482", "150483", "150484", "150487", "150488", "150489", "150490", "150491", "150494", "150495", "150497", "150499", "150502", "150506", "150507", "150508", "150510", "150511", "150515", "150516", "150518", "150519", "150521", "150526", "150527", "150529", "150530", "150532", "150533", "150534", "150535", "150536", "150540", "150542", "150546", "150547", "150548", "150549", "150550", "150551", "150552", "150559", "150562", "150564", "150565", "150566", "150569", "150570", "150572", "150575", "150578", "150580", "150582", "150585", "150587", "150588", "150591", "150592", "150595", "150597", "150598", "150599", "150606", "150608", "150609", "150610", "150612", "150613", "150615", "150616", "150620", "150621", "150622", "150624", "150626", "150627", "150628", "150629", "150630", "150631", "150632", "150636", "150639", "150646", "150647", "150650", "150652", "150654", "150655", "150656", "150657", "150659", "150660", "150661", "150662", "150663", "150664", "150665", "150668", "150669", "150671", "150674", "150677", "150678", "150679", "150680", "150683", "150684", "150685", "150686", "150690", "150691", "150692", "150693", "150696", "150697", "150698", "150699", "150701", "150703", "150706", "150707", "150709", "150711", "150712", "150713", "150714", "150716", "150719", "150720", "150721", "150723", "150727", "150729", "150733", "150734", "150736", "150738", "150741", "150742", "150743", "150745", "150747", "150752", "150753", "150754", "150756", "150758", "150760", "150761", "150763", "150764", "150765", "150766", "150767", "150768", "150772", "150773", "150776", "150778", "150782", "150783", "150785", "150787", "150794", "150796", "150797", "150800", "150804", "150805", "150807", "150812", "150814", "150815", "150816", "150817", "150820", "150821", "150824", "150826", "150827", "150830", "150832", "150835", "150836", "150838", "150839", "150841", "150843", "150848", "150849", "150851", "150852", "150856", "150857", "150863", "150866", "150868", "150869", "150873", "150874", "150875", "150876", "150877", "150880", "150881", "150887", "150890", "150892", "150893", "150894", "150896", "150897", "150899", "150901", "150902", "150903", "150905", "150907", "150908", "150910", "150911", "150912", "150914", "150915", "150920", "150924", "150925", "150926", "150927", "150933", "150935", "150939", "150940", "150941", "150942", "150943", "150947", "150950", "150952", "150955", "150956", "150957", "150960", "150962", "150966", "150967", "150969", "150971", "150972", "150975", "150976", "150977", "150978", "150984", "150985", "150987", "150989", "150990", "150991", "150992", "150994", "150996", "150999", "151002", "151003", "151004", "151006", "151007", "151008", "151010", "151012", "151016", "151018", "151020", "151024", "151025", "151028", "151029", "151030", "151031", "151032", "151034", "151038", "151039", "151041", "151047", "151049", "151050", "151051", "151053", "151054", "151055", "151056", "151059", "151060", "151065", "151067", "151068", "151070", "151071", "151072", "151074", "151075", "151077", "151081", "151082", "151083", "151084", "151085", "151086", "151087", "151088", "151089", "151092", "151095", "151096", "151099", "151100", "151101", "151102", "151104", "151105", "151108", "151109", "151113", "151115", "151119", "151121", "151124", "151128", "151131", "151133", "151134", "151135", "151137", "151139", "151145", "151146", "151153", "151154", "151155", "151158", "151159", "151160", "151161", "151162", "151166", "151168", "151169", "151170", "151172", "151173", "151176", "151177", "151184", "151187", "151188", "151189", "151190", "151191", "151195", "151206", "151208", "151209", "151210", "151211", "151215", "151217", "151219", "151222", "151229", "151231", "151232", "151233", "151235", "151238", "151245", "151246", "151247", "151248", "151249", "151250", "151254", "151255", "151257", "151258", "151260", "151261", "151262", "151264", "151271", "151272", "151275", "151276", "151279", "151280", "151282", "151284", "151285", "151288", "151289", "151290", "151291", "151293", "151297", "151298", "151300", "151301", "151302", "151303", "151306", "151309", "151312", "151316", "151323", "151325", "151327", "151329", "151331", "151332", "151334", "151337", "151338", "151339", "151344", "151349", "151350", "151354", "151355", "151356", "151358", "151359", "151361", "151364", "151369", "151372", "151373", "151374", "151375", "151382", "151388", "151390", "151394", "151395", "151397", "151398", "151400", "151401", "151402", "151406", "151407", "151409", "151412", "151413", "151414", "151415", "151416", "151419", "151422", "151423", "151426", "151428", "151434", "151435", "151436", "151437", "151440", "151441", "151444", "151445", "151446", "151449", "151452", "151453", "151454", "151460", "151461", "151463", "151465", "151468", "151469", "151470", "151473", "151474", "151478", "151479", "151480", "151486", "151487", "151488", "151490", "151497", "151498", "151499", "151504", "151505", "151506", "151507", "151508", "151509", "151512", "151513", "151515", "151516", "151518", "151519", "151524", "151526", "151533", "151535", "151540", "151541", "151542", "151544", "151548", "151549", "151552", "151553", "151554", "151558", "151562", "151566", "151568", "151569", "151571", "151574", "151575", "151576", "151578", "151581", "151584", "151585", "151586", "151588", "151592", "151593", "151595", "151596", "151597", "151598", "151600", "151601", "151604", "151606", "151610", "151611", "151612", "151616", "151619", "151621", "151624", "151625", "151626", "151627", "151628", "151631", "151632", "151633", "151635", "151636", "151637", "151638", "151639", "151643", "151645", "151646", "151650", "151652", "151653", "151656", "151657", "151658", "151662", "151664", "151665", "151670", "151673", "151675", "151677", "151678", "151680", "151681", "151683", "151684", "151685", "151686", "151687", "151688", "151690", "151691", "151694", "151697"]],
+ "valid" : ["int" , ["0", "2", "4", "6", "9", "13", "14", "16", "17", "20", "21", "23", "24", "26", "27", "28", "30", "32", "33", "34", "36", "37", "43", "44", "45", "46", "47", "48", "50", "51", "54", "56", "57", "58", "59", "61", "64", "66", "68", "72", "73", "75", "76", "77", "79", "80", "86", "89", "90", "91", "92", "93", "96", "98", "99", "101", "102", "104", "106", "108", "110", "111", "113", "114", "117", "118", "119", "120", "125", "127", "128", "129", "130", "138", "141", "146", "148", "150", "151", "152", "154", "158", "159", "160", "161", "166", "168", "170", "173", "174", "175", "176", "177", "178", "181", "182", "186", "187", "188", "189", "192", "194", "195", "196", "197", "199", "200", "202", "205", "207", "210", "211", "213", "214", "215", "218", "221", "222", "223", "230", "232", "233", "234", "235", "237", "238", "239", "241", "244", "246", "248", "252", "258", "259", "261", "262", "263", "264", "267", "271", "273", "276", "277", "279", "281", "283", "284", "286", "287", "288", "289", "290", "291", "292", "295", "298", "301", "303", "304", "306", "312", "314", "315", "317", "318", "320", "323", "324", "326", "329", "330", "335", "336", "338", "340", "342", "344", "345", "347", "348", "349", "351", "354", "359", "364", "365", "369", "370", "372", "375", "376", "377", "379", "381", "383", "386", "387", "388", "392", "394", "396", "397", "398", "400", "401", "404", "405", "406", "407", "409", "411", "415", "417", "419", "420", "422", "423", "424", "427", "431", "433", "437", "438", "439", "440", "441", "443", "444", "445", "446", "447", "449", "452", "453", "454", "455", "460", "463", "467", "469", "472", "473", "475", "477", "478", "485", "486", "487", "490", "491", "492", "494", "496", "498", "499", "501", "502", "503", "505", "508", "512", "513", "516", "517", "520", "521", "522", "523", "524", "525", "527", "528", "529", "530", "532", "533", "535", "537", "540", "541", "543", "547", "548", "550", "553", "554", "556", "557", "558", "559", "562", "564", "566", "568", "572", "573", "574", "575", "576", "578", "581", "582", "585", "586", "590", "593", "594", "596", "597", "598", "600", "601", "602", "603", "604", "605", "609", "612", "616", "618", "622", "624", "630", "631", "632", "635", "638", "639", "641", "643", "645", "648", "650", "651", "653", "654", "656", "658", "659", "660", "661", "663", "664", "667", "670", "672", "673", "674", "677", "678", "680", "682", "691", "693", "695", "696", "698", "700", "701", "702", "705", "706", "708", "711", "712", "715", "716", "717", "719", "720", "722", "724", "725", "727", "731", "736", "744", "747", "748", "750", "751", "752", "754", "755", "757", "761", "765", "766", "767", "769", "774", "776", "778", "779", "780", "781", "783", "784", "792", "794", "799", "802", "803", "804", "805", "807", "812", "814", "816", "818", "820", "821", "822", "823", "824", "825", "831", "832", "833", "836", "837", "840", "841", "843", "846", "849", "850", "851", "852", "855", "856", "857", "858", "860", "861", "864", "865", "869", "870", "871", "875", "876", "877", "878", "880", "882", "883", "884", "887", "888", "892", "893", "894", "899", "901", "903", "904", "906", "914", "917", "921", "925", "926", "927", "928", "931", "932", "933", "935", "938", "943", "944", "945", "947", "949", "952", "953", "954", "956", "957", "961", "963", "967", "968", "970", "972", "973", "975", "978", "980", "982", "985", "988", "989", "990", "992", "994", "996", "1000", "1005", "1008", "1009", "1010", "1011", "1013", "1015", "1022", "1023", "1024", "1025", "1029", "1034", "1035", "1036", "1039", "1040", "1041", "1043", "1044", "1048", "1050", "1056", "1059", "1060", "1061", "1064", "1065", "1066", "1067", "1069", "1070", "1076", "1080", "1081", "1082", "1084", "1086", "1087", "1089", "1092", "1095", "1097", "1098", "1100", "1102", "1103", "1104", "1107", "1114", "1116", "1117", "1119", "1120", "1121", "1125", "1128", "1129", "1131", "1134", "1135", "1136", "1138", "1140", "1143", "1145", "1146", "1147", "1149", "1150", "1151", "1152", "1153", "1156", "1158", "1159", "1160", "1163", "1164", "1167", "1169", "1170", "1171", "1174", "1178", "1180", "1181", "1184", "1185", "1186", "1191", "1192", "1193", "1194", "1195", "1197", "1202", "1205", "1206", "1207", "1211", "1215", "1216", "1220", "1222", "1223", "1224", "1225", "1227", "1230", "1232", "1233", "1236", "1239", "1240", "1246", "1247", "1248", "1249", "1250", "1251", "1253", "1254", "1255", "1256", "1262", "1263", "1266", "1267", "1269", "1270", "1273", "1282", "1286", "1290", "1291", "1292", "1293", "1296", "1298", "1299", "1301", "1303", "1305", "1306", "1309", "1310", "1312", "1313", "1314", "1315", "1317", "1318", "1319", "1320", "1323", "1327", "1334", "1335", "1337", "1338", "1341", "1344", "1346", "1348", "1349", "1350", "1351", "1352", "1354", "1355", "1356", "1357", "1358", "1360", "1361", "1368", "1369", "1373", "1374", "1376", "1378", "1385", "1387", "1388", "1389", "1390", "1391", "1392", "1395", "1399", "1402", "1408", "1411", "1412", "1414", "1415", "1418", "1419", "1422", "1424", "1426", "1427", "1431", "1434", "1440", "1441", "1442", "1446", "1447", "1451", "1453", "1456", "1458", "1460", "1461", "1462", "1464", "1468", "1469", "1470", "1472", "1473", "1475", "1477", "1478", "1479", "1482", "1485", "1486", "1489", "1490", "1492", "1494", "1495", "1496", "1497", "1498", "1499", "1500", "1503", "1506", "1509", "1510", "1511", "1515", "1518", "1519", "1520", "1523", "1524", "1525", "1526", "1527", "1528", "1529", "1530", "1531", "1532", "1533", "1535", "1536", "1537", "1539", "1542", "1545", "1547", "1549", "1550", "1553", "1554", "1555", "1556", "1558", "1560", "1562", "1563", "1565", "1568", "1569", "1570", "1572", "1575", "1579", "1591", "1594", "1602", "1604", "1605", "1606", "1609", "1614", "1617", "1618", "1620", "1623", "1624", "1625", "1627", "1628", "1629", "1630", "1631", "1632", "1633", "1635", "1636", "1637", "1640", "1644", "1645", "1646", "1648", "1650", "1653", "1654", "1656", "1659", "1660", "1661", "1665", "1666", "1668", "1669", "1670", "1671", "1673", "1674", "1675", "1679", "1681", "1682", "1683", "1685", "1688", "1690", "1691", "1694", "1695", "1697", "1698", "1700", "1702", "1703", "1705", "1706", "1707", "1710", "1712", "1713", "1715", "1721", "1722", "1723", "1724", "1725", "1728", "1729", "1730", "1731", "1732", "1733", "1734", "1736", "1738", "1740", "1741", "1747", "1749", "1750", "1752", "1753", "1756", "1757", "1758", "1762", "1767", "1772", "1775", "1776", "1777", "1778", "1779", "1781", "1784", "1786", "1787", "1788", "1790", "1791", "1793", "1794", "1796", "1797", "1799", "1800", "1801", "1802", "1803", "1804", "1805", "1809", "1812", "1813", "1815", "1817", "1818", "1819", "1821", "1823", "1834", "1835", "1839", "1843", "1845", "1847", "1849", "1850", "1852", "1856", "1857", "1860", "1861", "1862", "1866", "1870", "1871", "1872", "1873", "1874", "1875", "1887", "1890", "1894", "1896", "1897", "1899", "1900", "1902", "1904", "1907", "1909", "1911", "1913", "1914", "1915", "1917", "1919", "1922", "1924", "1928", "1929", "1932", "1933", "1935", "1937", "1939", "1941", "1942", "1946", "1947", "1951", "1952", "1953", "1954", "1956", "1958", "1960", "1961", "1962", "1964", "1967", "1968", "1969", "1970", "1971", "1972", "1973", "1974", "1976", "1979", "1980", "1982", "1984", "1985", "1987", "1988", "1989", "1990", "1991", "1992", "1994", "1995", "1996", "2001", "2003", "2009", "2010", "2011", "2012", "2013", "2014", "2019", "2021", "2022", "2026", "2027", "2029", "2033", "2034", "2037", "2038", "2039", "2043", "2044", "2045", "2046", "2047", "2050", "2054", "2062", "2065", "2068", "2071", "2072", "2073", "2074", "2076", "2077", "2081", "2082", "2083", "2085", "2088", "2095", "2096", "2097", "2099", "2102", "2103", "2105", "2106", "2107", "2108", "2110", "2111", "2113", "2114", "2118", "2119", "2120", "2121", "2122", "2125", "2129", "2132", "2133", "2134", "2135", "2139", "2140", "2143", "2146", "2151", "2154", "2155", "2159", "2161", "2162", "2163", "2164", "2165", "2166", "2168", "2169", "2170", "2171", "2172", "2173", "2175", "2178", "2180", "2182", "2183", "2186", "2187", "2189", "2190", "2191", "2194", "2195", "2198", "2199", "2202", "2203", "2204", "2208", "2210", "2218", "2219", "2220", "2222", "2223", "2224", "2226", "2228", "2229", "2230", "2233", "2234", "2235", "2236", "2239", "2244", "2245", "2248", "2249", "2251", "2252", "2254", "2257", "2258", "2260", "2261", "2264", "2266", "2268", "2269", "2270", "2271", "2272", "2273", "2276", "2277", "2279", "2280", "2282", "2284", "2286", "2287", "2288", "2289", "2294", "2298", "2300", "2301", "2304", "2305", "2310", "2311", "2313", "2316", "2319", "2321", "2322", "2324", "2325", "2326", "2327", "2329", "2331", "2333", "2335", "2337", "2338", "2339", "2340", "2342", "2345", "2347", "2348", "2349", "2350", "2351", "2353", "2354", "2355", "2358", "2359", "2360", "2363", "2364", "2365", "2366", "2367", "2368", "2370", "2376", "2377", "2379", "2380", "2384", "2385", "2390", "2393", "2394", "2397", "2399", "2400", "2401", "2403", "2404", "2405", "2406", "2409", "2412", "2414", "2419", "2424", "2426", "2428", "2430", "2431", "2432", "2433", "2434", "2437", "2438", "2440", "2441", "2442", "2447", "2448", "2449", "2452", "2454", "2455", "2456", "2458", "2460", "2462", "2465", "2468", "2469", "2471", "2472", "2475", "2476", "2479", "2480", "2481", "2487", "2488", "2492", "2493", "2497", "2498", "2500", "2502", "2505", "2506", "2507", "2508", "2509", "2510", "2512", "2513", "2514", "2517", "2518", "2519", "2521", "2522", "2526", "2529", "2530", "2531", "2534", "2536", "2537", "2538", "2539", "2540", "2543", "2544", "2545", "2549", "2551", "2552", "2553", "2558", "2561", "2566", "2567", "2569", "2570", "2575", "2576", "2577", "2579", "2580", "2582", "2584", "2588", "2589", "2590", "2592", "2593", "2596", "2597", "2602", "2604", "2606", "2608", "2609", "2611", "2615", "2616", "2618", "2622", "2624", "2625", "2629", "2631", "2632", "2633", "2635", "2636", "2637", "2638", "2641", "2642", "2643", "2649", "2652", "2653", "2654", "2655", "2656", "2657", "2658", "2660", "2664", "2667", "2668", "2670", "2672", "2673", "2678", "2679", "2680", "2681", "2682", "2684", "2690", "2691", "2692", "2695", "2697", "2702", "2703", "2704", "2706", "2708", "2709", "2710", "2711", "2712", "2715", "2717", "2718", "2720", "2722", "2723", "2734", "2735", "2737", "2739", "2741", "2743", "2744", "2746", "2747", "2749", "2750", "2751", "2752", "2755", "2756", "2757", "2759", "2760", "2762", "2763", "2764", "2765", "2768", "2769", "2770", "2771", "2772", "2776", "2777", "2779", "2781", "2783", "2786", "2787", "2789", "2790", "2792", "2793", "2794", "2796", "2798", "2799", "2801", "2802", "2803", "2806", "2807", "2809", "2810", "2811", "2815", "2816", "2819", "2820", "2821", "2822", "2823", "2825", "2826", "2827", "2830", "2832", "2836", "2837", "2841", "2844", "2848", "2849", "2850", "2851", "2853", "2857", "2858", "2859", "2862", "2863", "2866", "2867", "2868", "2873", "2874", "2876", "2877", "2878", "2879", "2881", "2882", "2884", "2886", "2887", "2888", "2894", "2898", "2899", "2900", "2901", "2903", "2904", "2906", "2910", "2912", "2913", "2914", "2917", "2918", "2923", "2924", "2926", "2929", "2930", "2931", "2933", "2936", "2942", "2944", "2945", "2946", "2948", "2949", "2951", "2953", "2954", "2955", "2956", "2957", "2959", "2960", "2961", "2962", "2964", "2969", "2970", "2972", "2973", "2975", "2976", "2977", "2980", "2981", "2982", "2983", "2984", "2985", "2986", "2989", "2990", "2991", "2992", "2994", "2998", "3000", "3003", "3006", "3007", "3008", "3009", "3012", "3013", "3018", "3019", "3020", "3022", "3025", "3026", "3027", "3029", "3030", "3031", "3032", "3042", "3043", "3045", "3046", "3049", "3051", "3054", "3057", "3058", "3059", "3062", "3063", "3064", "3065", "3068", "3069", "3070", "3072", "3074", "3075", "3081", "3082", "3084", "3085", "3087", "3088", "3089", "3090", "3093", "3096", "3107", "3109", "3111", "3118", "3120", "3121", "3122", "3123", "3125", "3127", "3129", "3130", "3132", "3135", "3136", "3137", "3140", "3141", "3142", "3144", "3145", "3146", "3147", "3148", "3152", "3153", "3154", "3163", "3164", "3165", "3166", "3169", "3170", "3171", "3175", "3176", "3178", "3180", "3181", "3183", "3184", "3185", "3186", "3187", "3191", "3192", "3193", "3195", "3198", "3200", "3203", "3204", "3205", "3206", "3207", "3212", "3213", "3214", "3215", "3216", "3218", "3219", "3222", "3227", "3228", "3229", "3230", "3233", "3235", "3236", "3242", "3246", "3247", "3250", "3255", "3256", "3258", "3259", "3260", "3262", "3263", "3265", "3266", "3269", "3270", "3271", "3277", "3279", "3280", "3283", "3284", "3285", "3287", "3291", "3292", "3293", "3294", "3295", "3296", "3298", "3301", "3303", "3304", "3305", "3307", "3308", "3309", "3310", "3311", "3312", "3316", "3317", "3320", "3321", "3323", "3325", "3327", "3328", "3330", "3336", "3337", "3339", "3340", "3343", "3346", "3347", "3348", "3352", "3353", "3355", "3356", "3357", "3358", "3359", "3360", "3361", "3362", "3365", "3366", "3371", "3374", "3375", "3378", "3379", "3380", "3386", "3387", "3391", "3393", "3394", "3396", "3398", "3399", "3400", "3401", "3403", "3405", "3407", "3409", "3412", "3414", "3415", "3416", "3418", "3422", "3423", "3429", "3432", "3435", "3437", "3439", "3443", "3451", "3452", "3453", "3455", "3456", "3462", "3464", "3467", "3471", "3473", "3474", "3476", "3478", "3481", "3483", "3484", "3485", "3487", "3488", "3489", "3492", "3493", "3495", "3498", "3500", "3501", "3502", "3508", "3511", "3515", "3517", "3518", "3519", "3520", "3521", "3522", "3526", "3528", "3529", "3530", "3531", "3533", "3535", "3537", "3538", "3544", "3547", "3548", "3550", "3552", "3553", "3554", "3555", "3557", "3561", "3563", "3565", "3566", "3567", "3568", "3569", "3572", "3575", "3576", "3579", "3581", "3582", "3583", "3584", "3585", "3586", "3588", "3591", "3592", "3593", "3594", "3597", "3599", "3600", "3602", "3603", "3605", "3608", "3610", "3614", "3615", "3616", "3617", "3619", "3623", "3624", "3626", "3627", "3628", "3630", "3632", "3633", "3635", "3638", "3641", "3643", "3644", "3646", "3650", "3651", "3652", "3655", "3657", "3661", "3662", "3665", "3670", "3677", "3679", "3682", "3683", "3684", "3686", "3689", "3695", "3696", "3697", "3699", "3701", "3702", "3704", "3705", "3707", "3709", "3711", "3713", "3715", "3719", "3720", "3723", "3725", "3728", "3729", "3732", "3734", "3736", "3737", "3738", "3739", "3741", "3743", "3748", "3750", "3753", "3754", "3757", "3758", "3759", "3760", "3763", "3768", "3773", "3775", "3777", "3778", "3779", "3784", "3786", "3793", "3794", "3795", "3797", "3803", "3805", "3809", "3811", "3814", "3815", "3817", "3820", "3821", "3823", "3825", "3826", "3827", "3829", "3831", "3832", "3834", "3835", "3836", "3839", "3842", "3844", "3845", "3846", "3852", "3853", "3854", "3857", "3858", "3859", "3864", "3865", "3868", "3869", "3870", "3871", "3872", "3873", "3874", "3876", "3877", "3881", "3882", "3890", "3891", "3892", "3893", "3895", "3897", "3899", "3901", "3902", "3907", "3909", "3910", "3911", "3912", "3913", "3915", "3916", "3917", "3918", "3919", "3922", "3925", "3926", "3927", "3929", "3931", "3935", "3936", "3937", "3940", "3941", "3942", "3947", "3948", "3949", "3950", "3952", "3953", "3954", "3956", "3958", "3959", "3960", "3961", "3962", "3964", "3967", "3972", "3974", "3975", "3977", "3979", "3981", "3982", "3984", "3985", "3986", "3987", "3991", "3993", "3994", "3996", "3999", "4000", "4002", "4005", "4006", "4007", "4008", "4009", "4010", "4012", "4013", "4014", "4015", "4018", "4019", "4021", "4024", "4027", "4029", "4032", "4034", "4035", "4037", "4038", "4039", "4040", "4042", "4043", "4044", "4045", "4051", "4054", "4056", "4057", "4064", "4065", "4066", "4069", "4072", "4073", "4074", "4078", "4080", "4083", "4084", "4089", "4090", "4092", "4093", "4094", "4095", "4098", "4100", "4101", "4103", "4104", "4107", "4108", "4110", "4112", "4113", "4114", "4122", "4123", "4124", "4127", "4129", "4132", "4133", "4135", "4136", "4140", "4141", "4142", "4143", "4144", "4145", "4147", "4148", "4149", "4150", "4151", "4152", "4154", "4156", "4160", "4164", "4168", "4171", "4172", "4173", "4174", "4175", "4180", "4181", "4182", "4183", "4184", "4185", "4186", "4191", "4193", "4195", "4197", "4198", "4199", "4200", "4201", "4202", "4203", "4204", "4207", "4212", "4214", "4216", "4218", "4222", "4223", "4224", "4225", "4226", "4230", "4232", "4234", "4237", "4238", "4239", "4242", "4243", "4245", "4246", "4248", "4249", "4250", "4256", "4257", "4258", "4260", "4261", "4262", "4263", "4264", "4266", "4268", "4269", "4273", "4274", "4275", "4278", "4282", "4284", "4285", "4287", "4289", "4292", "4294", "4295", "4297", "4299", "4301", "4302", "4304", "4305", "4307", "4310", "4314", "4316", "4317", "4322", "4325", "4326", "4327", "4328", "4329", "4331", "4332", "4334", "4336", "4337", "4340", "4341", "4345", "4347", "4350", "4352", "4354", "4358", "4359", "4361", "4367", "4370", "4371", "4375", "4380", "4381", "4384", "4385", "4386", "4387", "4388", "4389", "4391", "4392", "4394", "4396", "4397", "4398", "4399", "4400", "4403", "4404", "4405", "4406", "4407", "4408", "4409", "4412", "4413", "4416", "4417", "4418", "4420", "4423", "4424", "4425", "4426", "4427", "4428", "4432", "4434", "4436", "4438", "4442", "4443", "4446", "4447", "4448", "4454", "4455", "4456", "4457", "4459", "4464", "4469", "4470", "4471", "4472", "4473", "4476", "4477", "4482", "4483", "4485", "4486", "4487", "4493", "4496", "4498", "4499", "4502", "4503", "4506", "4507", "4508", "4509", "4510", "4511", "4513", "4517", "4518", "4520", "4521", "4523", "4526", "4527", "4528", "4530", "4531", "4533", "4534", "4536", "4537", "4538", "4540", "4541", "4542", "4544", "4546", "4548", "4550", "4552", "4556", "4557", "4560", "4562", "4564", "4565", "4566", "4567", "4568", "4574", "4575", "4577", "4578", "4579", "4582", "4583", "4584", "4586", "4588", "4590", "4591", "4592", "4596", "4599", "4603", "4605", "4606", "4607", "4613", "4616", "4617", "4619", "4620", "4621", "4623", "4624", "4630", "4637", "4638", "4640", "4641", "4642", "4645", "4647", "4650", "4656", "4658", "4659", "4661", "4663", "4664", "4667", "4671", "4673", "4674", "4678", "4679", "4680", "4683", "4684", "4685", "4686", "4687", "4689", "4690", "4691", "4692", "4693", "4696", "4697", "4701", "4702", "4707", "4709", "4711", "4713", "4717", "4719", "4720", "4723", "4724", "4725", "4728", "4729", "4731", "4732", "4733", "4734", "4736", "4738", "4740", "4743", "4745", "4749", "4750", "4751", "4752", "4753", "4754", "4759", "4765", "4767", "4768", "4769", "4770", "4773", "4774", "4776", "4777", "4780", "4781", "4783", "4784", "4785", "4787", "4789", "4790", "4791", "4793", "4794", "4797", "4798", "4799", "4802", "4805", "4808", "4809", "4810", "4811", "4812", "4813", "4814", "4817", "4818", "4819", "4820", "4821", "4823", "4825", "4826", "4829", "4830", "4832", "4834", "4836", "4837", "4839", "4841", "4842", "4844", "4846", "4850", "4851", "4852", "4854", "4855", "4856", "4859", "4860", "4861", "4862", "4864", "4866", "4867", "4871", "4876", "4878", "4879", "4880", "4884", "4885", "4890", "4892", "4894", "4896", "4898", "4901", "4902", "4903", "4904", "4911", "4912", "4913", "4915", "4916", "4917", "4918", "4921", "4923", "4925", "4926", "4927", "4929", "4932", "4933", "4934", "4935", "4939", "4940", "4943", "4947", "4949", "4950", "4953", "4954", "4955", "4957", "4958", "4961", "4963", "4964", "4966", "4967", "4970", "4972", "4973", "4974", "4975", "4976", "4977", "4979", "4983", "4985", "4986", "4987", "4992", "4993", "4996", "4997", "4998", "5000", "5001", "5002", "5004", "5005", "5007", "5012", "5013", "5015", "5016", "5022", "5024", "5027", "5029", "5031", "5032", "5033", "5034", "5035", "5036", "5042", "5045", "5051", "5054", "5060", "5061", "5062", "5065", "5068", "5071", "5074", "5076", "5077", "5078", "5080", "5081", "5082", "5083", "5084", "5087", "5088", "5089", "5094", "5099", "5103", "5108", "5110", "5111", "5113", "5114", "5115", "5116", "5117", "5121", "5123", "5124", "5125", "5126", "5129", "5132", "5133", "5134", "5135", "5136", "5137", "5138", "5139", "5141", "5142", "5144", "5149", "5151", "5154", "5155", "5157", "5158", "5160", "5168", "5172", "5173", "5175", "5177", "5178", "5179", "5183", "5185", "5186", "5190", "5192", "5193", "5195", "5196", "5197", "5205", "5206", "5207", "5208", "5210", "5215", "5216", "5218", "5219", "5220", "5222", "5223", "5225", "5226", "5227", "5228", "5229", "5232", "5233", "5234", "5236", "5237", "5238", "5239", "5241", "5243", "5249", "5252", "5253", "5254", "5257", "5259", "5261", "5262", "5263", "5264", "5268", "5269", "5270", "5272", "5273", "5274", "5279", "5280", "5282", "5284", "5285", "5286", "5291", "5292", "5293", "5294", "5296", "5298", "5299", "5302", "5303", "5304", "5306", "5307", "5309", "5310", "5311", "5314", "5316", "5322", "5324", "5326", "5327", "5330", "5333", "5334", "5336", "5338", "5340", "5341", "5343", "5345", "5346", "5350", "5353", "5356", "5358", "5359", "5361", "5365", "5366", "5371", "5373", "5374", "5378", "5380", "5381", "5382", "5385", "5386", "5387", "5389", "5390", "5391", "5392", "5393", "5394", "5395", "5396", "5397", "5398", "5400", "5403", "5405", "5409", "5410", "5413", "5416", "5419", "5420", "5424", "5425", "5427", "5430", "5431", "5433", "5438", "5439", "5440", "5441", "5442", "5443", "5444", "5445", "5448", "5450", "5451", "5453", "5455", "5456", "5459", "5463", "5466", "5467", "5472", "5473", "5474", "5478", "5479", "5484", "5486", "5487", "5488", "5490", "5492", "5494", "5495", "5496", "5497", "5499", "5501", "5505", "5506", "5509", "5510", "5512", "5515", "5517", "5519", "5520", "5522", "5525", "5526", "5527", "5528", "5529", "5530", "5532", "5533", "5535", "5541", "5543", "5544", "5547", "5548", "5550", "5551", "5553", "5554", "5558", "5560", "5561", "5563", "5566", "5568", "5569", "5570", "5571", "5573", "5575", "5578", "5583", "5585", "5586", "5591", "5592", "5593", "5594", "5596", "5600", "5602", "5605", "5607", "5611", "5612", "5613", "5614", "5615", "5616", "5617", "5619", "5620", "5621", "5622", "5623", "5626", "5627", "5628", "5631", "5633", "5634", "5635", "5636", "5639", "5642", "5644", "5647", "5648", "5649", "5651", "5652", "5660", "5661", "5663", "5667", "5669", "5670", "5677", "5679", "5682", "5683", "5684", "5689", "5692", "5693", "5697", "5698", "5701", "5705", "5707", "5709", "5714", "5715", "5716", "5717", "5719", "5723", "5724", "5726", "5727", "5728", "5729", "5730", "5732", "5733", "5735", "5737", "5738", "5739", "5740", "5741", "5748", "5751", "5755", "5760", "5761", "5762", "5767", "5773", "5775", "5776", "5777", "5779", "5780", "5781", "5782", "5783", "5785", "5786", "5787", "5788", "5789", "5791", "5794", "5795", "5796", "5797", "5799", "5802", "5803", "5805", "5806", "5808", "5810", "5811", "5813", "5823", "5824", "5825", "5826", "5827", "5829", "5830", "5831", "5832", "5833", "5836", "5837", "5838", "5841", "5842", "5845", "5846", "5849", "5851", "5856", "5857", "5858", "5860", "5861", "5862", "5864", "5866", "5867", "5868", "5872", "5873", "5877", "5880", "5882", "5886", "5888", "5890", "5892", "5895", "5897", "5900", "5901", "5905", "5908", "5909", "5912", "5914", "5915", "5918", "5919", "5921", "5922", "5926", "5927", "5928", "5929", "5930", "5931", "5935", "5936", "5939", "5941", "5942", "5945", "5948", "5949", "5951", "5955", "5956", "5957", "5958", "5959", "5960", "5961", "5963", "5964", "5965", "5966", "5967", "5968", "5969", "5974", "5975", "5976", "5977", "5978", "5979", "5980", "5981", "5984", "5985", "5986", "5989", "5994", "5995", "5996", "5998", "5999", "6002", "6006", "6007", "6008", "6013", "6015", "6017", "6018", "6020", "6022", "6023", "6024", "6025", "6027", "6031", "6034", "6037", "6041", "6042", "6049", "6051", "6052", "6053", "6056", "6057", "6058", "6061", "6062", "6063", "6065", "6067", "6069", "6073", "6075", "6078", "6079", "6082", "6084", "6087", "6089", "6091", "6094", "6095", "6096", "6099", "6100", "6104", "6105", "6106", "6108", "6109", "6110", "6112", "6115", "6118", "6120", "6123", "6128", "6129", "6130", "6132", "6134", "6136", "6138", "6147", "6148", "6149", "6150", "6151", "6152", "6154", "6157", "6159", "6160", "6162", "6163", "6164", "6165", "6168", "6171", "6172", "6173", "6174", "6175", "6176", "6177", "6178", "6179", "6184", "6188", "6189", "6190", "6195", "6197", "6200", "6203", "6205", "6206", "6207", "6208", "6209", "6210", "6211", "6213", "6216", "6219", "6222", "6224", "6225", "6227", "6228", "6230", "6231", "6232", "6233", "6234", "6235", "6237", "6238", "6239", "6241", "6243", "6245", "6247", "6250", "6252", "6254", "6255", "6256", "6258", "6261", "6265", "6269", "6270", "6271", "6272", "6273", "6278", "6281", "6282", "6283", "6286", "6288", "6289", "6290", "6294", "6295", "6299", "6301", "6303", "6305", "6307", "6308", "6309", "6310", "6311", "6313", "6314", "6318", "6320", "6321", "6322", "6323", "6324", "6325", "6326", "6329", "6330", "6332", "6336", "6339", "6340", "6342", "6345", "6346", "6348", "6349", "6350", "6351", "6352", "6353", "6355", "6356", "6357", "6358", "6359", "6361", "6363", "6364", "6365", "6366", "6367", "6369", "6370", "6371", "6372", "6373", "6374", "6375", "6377", "6379", "6381", "6382", "6383", "6384", "6385", "6388", "6389", "6390", "6392", "6393", "6395", "6397", "6400", "6403", "6404", "6405", "6406", "6407", "6414", "6415", "6416", "6417", "6418", "6419", "6421", "6426", "6429", "6430", "6433", "6434", "6437", "6440", "6442", "6443", "6444", "6446", "6447", "6448", "6451", "6453", "6454", "6457", "6470", "6475", "6476", "6477", "6481", "6484", "6485", "6488", "6489", "6490", "6491", "6492", "6493", "6494", "6495", "6496", "6497", "6498", "6499", "6501", "6502", "6503", "6504", "6505", "6506", "6507", "6509", "6510", "6513", "6514", "6519", "6521", "6522", "6525", "6527", "6528", "6530", "6533", "6534", "6535", "6537", "6538", "6541", "6544", "6547", "6550", "6551", "6553", "6556", "6559", "6560", "6562", "6563", "6564", "6565", "6567", "6569", "6570", "6571", "6573", "6574", "6576", "6577", "6582", "6583", "6587", "6588", "6595", "6598", "6599", "6600", "6602", "6603", "6605", "6606", "6608", "6609", "6610", "6612", "6613", "6615", "6619", "6620", "6621", "6623", "6624", "6626", "6630", "6633", "6634", "6637", "6638", "6640", "6642", "6643", "6647", "6648", "6654", "6655", "6658", "6661", "6662", "6668", "6669", "6676", "6679", "6680", "6681", "6689", "6691", "6692", "6694", "6696", "6699", "6703", "6704", "6707", "6708", "6709", "6711", "6712", "6713", "6716", "6725", "6726", "6727", "6729", "6730", "6732", "6733", "6736", "6738", "6739", "6740", "6741", "6742", "6744", "6747", "6749", "6756", "6758", "6760", "6763", "6764", "6766", "6770", "6771", "6775", "6776", "6777", "6778", "6782", "6784", "6787", "6790", "6792", "6793", "6794", "6795", "6796", "6797", "6798", "6800", "6801", "6802", "6803", "6805", "6806", "6808", "6809", "6811", "6813", "6814", "6815", "6818", "6819", "6820", "6822", "6828", "6829", "6840", "6842", "6845", "6847", "6848", "6849", "6850", "6851", "6853", "6855", "6858", "6864", "6865", "6866", "6867", "6869", "6870", "6874", "6879", "6881", "6884", "6888", "6890", "6892", "6894", "6895", "6896", "6897", "6900", "6904", "6906", "6907", "6908", "6912", "6915", "6918", "6920", "6924", "6925", "6927", "6934", "6935", "6936", "6938", "6940", "6943", "6945", "6946", "6947", "6949", "6952", "6953", "6956", "6958", "6959", "6961", "6965", "6967", "6968", "6969", "6973", "6976", "6977", "6978", "6979", "6980", "6983", "6984", "6987", "6989", "6991", "6993", "6994", "6995", "6997", "6998", "6999", "7001", "7002", "7004", "7006", "7008", "7015", "7016", "7018", "7019", "7021", "7022", "7023", "7025", "7026", "7028", "7029", "7030", "7036", "7037", "7041", "7042", "7046", "7049", "7050", "7052", "7053", "7056", "7059", "7060", "7061", "7062", "7066", "7068", "7070", "7073", "7075", "7077", "7084", "7085", "7088", "7089", "7093", "7095", "7100", "7101", "7102", "7103", "7105", "7106", "7107", "7108", "7109", "7112", "7115", "7116", "7117", "7119", "7120", "7121", "7126", "7127", "7128", "7130", "7134", "7137", "7138", "7141", "7142", "7143", "7144", "7145", "7148", "7151", "7153", "7155", "7156", "7157", "7161", "7162", "7163", "7166", "7168", "7169", "7171", "7174", "7175", "7178", "7179", "7180", "7184", "7185", "7187", "7188", "7192", "7195", "7196", "7198", "7205", "7206", "7207", "7208", "7209", "7213", "7214", "7219", "7221", "7223", "7226", "7228", "7229", "7230", "7232", "7233", "7234", "7235", "7238", "7240", "7241", "7243", "7244", "7248", "7250", "7251", "7256", "7257", "7259", "7264", "7267", "7268", "7269", "7270", "7271", "7272", "7273", "7274", "7278", "7282", "7285", "7286", "7287", "7288", "7289", "7290", "7291", "7292", "7293", "7296", "7297", "7298", "7302", "7304", "7305", "7307", "7308", "7310", "7314", "7315", "7316", "7319", "7320", "7323", "7325", "7327", "7329", "7330", "7333", "7335", "7338", "7339", "7340", "7341", "7342", "7343", "7344", "7345", "7346", "7347", "7348", "7349", "7350", "7351", "7353", "7355", "7356", "7357", "7358", "7359", "7360", "7361", "7364", "7365", "7369", "7370", "7371", "7372", "7373", "7374", "7375", "7377", "7378", "7379", "7380", "7381", "7387", "7388", "7390", "7391", "7392", "7394", "7401", "7402", "7405", "7412", "7413", "7415", "7417", "7418", "7423", "7424", "7425", "7426", "7427", "7429", "7430", "7432", "7433", "7436", "7443", "7446", "7447", "7451", "7458", "7460", "7464", "7465", "7466", "7468", "7470", "7472", "7473", "7474", "7477", "7483", "7486", "7490", "7491", "7493", "7494", "7495", "7496", "7498", "7499", "7500", "7501", "7504", "7508", "7509", "7511", "7513", "7515", "7516", "7517", "7518", "7524", "7525", "7526", "7528", "7529", "7532", "7534", "7535", "7536", "7539", "7541", "7546", "7547", "7549", "7551", "7552", "7553", "7555", "7556", "7560", "7566", "7567", "7568", "7570", "7573", "7575", "7576", "7577", "7578", "7583", "7585", "7588", "7590", "7592", "7593", "7594", "7595", "7596", "7597", "7601", "7607", "7609", "7610", "7611", "7615", "7616", "7618", "7621", "7622", "7625", "7626", "7629", "7630", "7633", "7636", "7638", "7639", "7641", "7642", "7643", "7645", "7647", "7649", "7651", "7654", "7655", "7657", "7658", "7660", "7661", "7663", "7664", "7665", "7671", "7674", "7677", "7679", "7680", "7683", "7684", "7686", "7688", "7689", "7691", "7693", "7697", "7700", "7704", "7705", "7706", "7707", "7711", "7712", "7713", "7718", "7721", "7722", "7725", "7726", "7727", "7728", "7732", "7733", "7736", "7740", "7741", "7742", "7743", "7744", "7748", "7753", "7755", "7758", "7760", "7762", "7763", "7765", "7766", "7767", "7768", "7769", "7772", "7774", "7775", "7778", "7779", "7780", "7781", "7782", "7783", "7785", "7786", "7787", "7789", "7790", "7795", "7796", "7799", "7801", "7802", "7805", "7806", "7808", "7810", "7814", "7815", "7818", "7819", "7824", "7825", "7828", "7830", "7835", "7837", "7838", "7839", "7842", "7843", "7844", "7845", "7846", "7847", "7848", "7849", "7852", "7854", "7857", "7859", "7861", "7863", "7864", "7865", "7866", "7867", "7869", "7871", "7872", "7875", "7882", "7884", "7885", "7889", "7891", "7892", "7895", "7896", "7898", "7899", "7903", "7904", "7906", "7908", "7909", "7910", "7911", "7912", "7914", "7915", "7917", "7920", "7921", "7923", "7924", "7925", "7926", "7930", "7932", "7934", "7935", "7936", "7937", "7938", "7942", "7943", "7944", "7946", "7948", "7954", "7955", "7956", "7958", "7959", "7961", "7963", "7964", "7965", "7967", "7969", "7970", "7971", "7973", "7978", "7979", "7982", "7984", "7986", "7988", "7990", "7991", "7996", "7998", "8004", "8006", "8007", "8011", "8014", "8015", "8016", "8019", "8023", "8024", "8025", "8027", "8028", "8029", "8030", "8035", "8038", "8040", "8043", "8044", "8045", "8051", "8052", "8053", "8054", "8055", "8057", "8060", "8061", "8064", "8066", "8068", "8073", "8074", "8077", "8078", "8079", "8082", "8084", "8085", "8086", "8088", "8093", "8094", "8095", "8096", "8098", "8099", "8100", "8105", "8107", "8108", "8109", "8110", "8111", "8112", "8113", "8114", "8118", "8121", "8122", "8124", "8127", "8128", "8129", "8131", "8132", "8133", "8137", "8139", "8140", "8141", "8143", "8145", "8148", "8150", "8151", "8156", "8158", "8162", "8163", "8165", "8167", "8168", "8170", "8171", "8172", "8173", "8176", "8177", "8179", "8180", "8182", "8184", "8185", "8186", "8187", "8188", "8193", "8197", "8199", "8201", "8202", "8206", "8207", "8209", "8210", "8211", "8212", "8213", "8214", "8215", "8217", "8218", "8219", "8220", "8224", "8225", "8226", "8228", "8230", "8231", "8232", "8237", "8238", "8242", "8243", "8244", "8245", "8247", "8248", "8250", "8252", "8253", "8258", "8263", "8264", "8267", "8269", "8273", "8274", "8276", "8279", "8280", "8281", "8282", "8283", "8286", "8287", "8290", "8291", "8292", "8295", "8297", "8298", "8299", "8300", "8304", "8305", "8306", "8309", "8310", "8311", "8312", "8313", "8316", "8317", "8318", "8319", "8322", "8328", "8329", "8330", "8332", "8333", "8335", "8336", "8337", "8338", "8339", "8343", "8344", "8349", "8350", "8351", "8355", "8358", "8359", "8361", "8362", "8365", "8367", "8368", "8369", "8370", "8372", "8374", "8375", "8377", "8378", "8379", "8383", "8384", "8387", "8388", "8389", "8391", "8394", "8395", "8398", "8409", "8412", "8413", "8415", "8418", "8419", "8420", "8421", "8422", "8423", "8424", "8425", "8429", "8431", "8432", "8434", "8435", "8436", "8438", "8440", "8441", "8442", "8443", "8447", "8448", "8449", "8450", "8452", "8454", "8460", "8461", "8463", "8464", "8465", "8466", "8468", "8469", "8473", "8474", "8475", "8477", "8480", "8483", "8484", "8485", "8486", "8488", "8489", "8490", "8493", "8495", "8497", "8498", "8499", "8503", "8504", "8506", "8507", "8508", "8509", "8510", "8512", "8514", "8515", "8516", "8517", "8520", "8523", "8525", "8526", "8527", "8528", "8530", "8532", "8533", "8535", "8538", "8539", "8540", "8541", "8542", "8545", "8546", "8547", "8549", "8552", "8553", "8554", "8555", "8557", "8558", "8559", "8563", "8566", "8567", "8570", "8571", "8572", "8573", "8574", "8576", "8579", "8580", "8581", "8584", "8585", "8588", "8589", "8593", "8595", "8597", "8598", "8600", "8603", "8604", "8605", "8606", "8613", "8615", "8618", "8619", "8620", "8621", "8623", "8624", "8625", "8626", "8627", "8629", "8631", "8635", "8638", "8639", "8641", "8642", "8643", "8644", "8646", "8647", "8648", "8649", "8651", "8653", "8656", "8657", "8658", "8659", "8660", "8661", "8666", "8668", "8672", "8674", "8675", "8676", "8677", "8678", "8679", "8682", "8683", "8686", "8687", "8689", "8690", "8692", "8693", "8694", "8695", "8696", "8698", "8699", "8700", "8701", "8702", "8703", "8706", "8707", "8710", "8711", "8712", "8713", "8714", "8717", "8720", "8721", "8722", "8725", "8726", "8727", "8728", "8730", "8731", "8732", "8734", "8736", "8738", "8739", "8742", "8744", "8747", "8755", "8756", "8760", "8763", "8764", "8765", "8766", "8767", "8780", "8781", "8782", "8784", "8789", "8794", "8795", "8796", "8798", "8800", "8803", "8805", "8806", "8807", "8809", "8810", "8811", "8812", "8815", "8819", "8821", "8824", "8826", "8829", "8830", "8831", "8832", "8833", "8838", "8839", "8842", "8843", "8847", "8848", "8849", "8851", "8855", "8859", "8862", "8863", "8866", "8867", "8869", "8870", "8871", "8873", "8876", "8877", "8878", "8882", "8883", "8885", "8886", "8887", "8888", "8889", "8890", "8892", "8895", "8897", "8898", "8899", "8900", "8908", "8910", "8911", "8912", "8913", "8921", "8925", "8926", "8927", "8928", "8931", "8933", "8934", "8935", "8936", "8937", "8939", "8940", "8941", "8943", "8946", "8951", "8952", "8955", "8956", "8958", "8959", "8960", "8964", "8965", "8966", "8967", "8968", "8969", "8973", "8977", "8978", "8979", "8980", "8983", "8984", "8988", "8989", "8990", "8991", "9000", "9002", "9003", "9007", "9010", "9011", "9015", "9019", "9027", "9028", "9029", "9030", "9031", "9032", "9033", "9034", "9035", "9036", "9037", "9038", "9039", "9040", "9041", "9042", "9043", "9044", "9045", "9046", "9049", "9050", "9052", "9056", "9061", "9065", "9067", "9068", "9071", "9073", "9075", "9077", "9078", "9079", "9081", "9084", "9089", "9090", "9093", "9094", "9095", "9096", "9099", "9100", "9105", "9110", "9112", "9113", "9114", "9115", "9116", "9117", "9118", "9119", "9120", "9121", "9123", "9124", "9125", "9127", "9128", "9133", "9135", "9138", "9139", "9141", "9143", "9145", "9146", "9149", "9150", "9152", "9153", "9154", "9155", "9158", "9159", "9160", "9162", "9168", "9169", "9170", "9171", "9173", "9174", "9175", "9178", "9180", "9181", "9182", "9185", "9186", "9187", "9190", "9191", "9192", "9193", "9194", "9197", "9198", "9199", "9200", "9201", "9203", "9207", "9212", "9213", "9217", "9218", "9219", "9221", "9223", "9225", "9233", "9234", "9235", "9236", "9237", "9238", "9240", "9241", "9243", "9244", "9247", "9248", "9252", "9254", "9255", "9257", "9258", "9259", "9261", "9263", "9265", "9267", "9268", "9269", "9270", "9271", "9275", "9276", "9278", "9280", "9283", "9284", "9287", "9288", "9291", "9292", "9296", "9297", "9298", "9299", "9300", "9301", "9302", "9305", "9306", "9307", "9309", "9312", "9315", "9316", "9317", "9320", "9323", "9325", "9326", "9328", "9329", "9330", "9333", "9335", "9336", "9340", "9343", "9344", "9348", "9349", "9353", "9355", "9356", "9359", "9360", "9361", "9362", "9363", "9366", "9369", "9370", "9374", "9376", "9378", "9379", "9380", "9382", "9383", "9387", "9388", "9389", "9390", "9391", "9392", "9398", "9401", "9402", "9403", "9404", "9407", "9408", "9411", "9412", "9413", "9416", "9419", "9423", "9424", "9425", "9426", "9429", "9431", "9433", "9434", "9435", "9436", "9441", "9443", "9446", "9447", "9449", "9452", "9455", "9459", "9462", "9464", "9468", "9469", "9473", "9475", "9476", "9477", "9480", "9481", "9482", "9487", "9489", "9490", "9492", "9496", "9498", "9499", "9500", "9501", "9505", "9506", "9508", "9509", "9510", "9514", "9515", "9517", "9518", "9519", "9520", "9523", "9525", "9527", "9530", "9533", "9534", "9535", "9536", "9538", "9542", "9543", "9545", "9546", "9547", "9549", "9552", "9554", "9555", "9556", "9557", "9560", "9561", "9562", "9565", "9568", "9569", "9570", "9571", "9574", "9579", "9580", "9581", "9582", "9587", "9589", "9590", "9591", "9592", "9595", "9596", "9597", "9598", "9604", "9607", "9609", "9610", "9611", "9613", "9615", "9618", "9619", "9621", "9622", "9623", "9624", "9625", "9627", "9630", "9633", "9636", "9638", "9639", "9641", "9642", "9643", "9645", "9647", "9649", "9650", "9653", "9656", "9657", "9659", "9660", "9661", "9662", "9663", "9664", "9665", "9667", "9668", "9669", "9673", "9675", "9676", "9677", "9678", "9679", "9682", "9686", "9687", "9688", "9690", "9692", "9694", "9696", "9698", "9704", "9705", "9707", "9712", "9713", "9714", "9715", "9716", "9718", "9721", "9722", "9727", "9728", "9731", "9732", "9734", "9736", "9737", "9742", "9743", "9747", "9748", "9749", "9751", "9752", "9753", "9754", "9760", "9761", "9768", "9769", "9770", "9771", "9773", "9774", "9775", "9776", "9786", "9788", "9790", "9792", "9793", "9794", "9797", "9798", "9799", "9803", "9804", "9805", "9806", "9808", "9809", "9810", "9812", "9813", "9820", "9821", "9822", "9824", "9825", "9826", "9827", "9830", "9831", "9832", "9833", "9834", "9835", "9836", "9837", "9840", "9843", "9844", "9848", "9849", "9850", "9852", "9853", "9854", "9858", "9859", "9861", "9862", "9864", "9865", "9867", "9870", "9872", "9873", "9877", "9881", "9885", "9887", "9888", "9889", "9892", "9894", "9900", "9901", "9903", "9906", "9910", "9912", "9917", "9919", "9921", "9923", "9924", "9928", "9930", "9931", "9934", "9939", "9941", "9945", "9949", "9950", "9951", "9952", "9953", "9955", "9956", "9958", "9959", "9961", "9966", "9967", "9968", "9970", "9971", "9975", "9977", "9978", "9981", "9982", "9985", "9987", "9990", "9994", "9995", "9996", "9997", "10000", "10002", "10004", "10005", "10009", "10011", "10012", "10015", "10016", "10018", "10019", "10021", "10022", "10025", "10026", "10027", "10030", "10031", "10033", "10037", "10039", "10048", "10049", "10051", "10052", "10053", "10056", "10057", "10061", "10062", "10063", "10064", "10065", "10066", "10070", "10071", "10073", "10076", "10079", "10082", "10083", "10085", "10087", "10088", "10092", "10093", "10094", "10095", "10096", "10097", "10099", "10101", "10102", "10103", "10105", "10106", "10107", "10108", "10113", "10114", "10116", "10118", "10122", "10123", "10129", "10134", "10135", "10136", "10138", "10139", "10146", "10148", "10149", "10151", "10153", "10155", "10156", "10157", "10162", "10166", "10167", "10168", "10170", "10171", "10174", "10175", "10176", "10182", "10183", "10187", "10188", "10190", "10192", "10194", "10196", "10197", "10200", "10201", "10202", "10205", "10206", "10207", "10208", "10212", "10213", "10214", "10219", "10221", "10223", "10224", "10229", "10230", "10232", "10233", "10235", "10238", "10240", "10242", "10243", "10248", "10250", "10252", "10253", "10257", "10258", "10263", "10266", "10269", "10270", "10271", "10272", "10276", "10277", "10279", "10280", "10282", "10285", "10286", "10291", "10292", "10293", "10297", "10302", "10304", "10307", "10308", "10312", "10314", "10315", "10318", "10319", "10320", "10327", "10331", "10332", "10333", "10338", "10339", "10341", "10342", "10343", "10344", "10347", "10348", "10349", "10350", "10351", "10353", "10355", "10359", "10361", "10364", "10365", "10368", "10369", "10371", "10372", "10373", "10376", "10377", "10378", "10380", "10381", "10383", "10384", "10385", "10394", "10396", "10402", "10403", "10406", "10408", "10409", "10410", "10418", "10419", "10423", "10424", "10426", "10429", "10430", "10431", "10433", "10434", "10436", "10438", "10439", "10441", "10444", "10446", "10448", "10450", "10452", "10453", "10456", "10458", "10461", "10464", "10465", "10467", "10468", "10469", "10471", "10473", "10481", "10485", "10488", "10490", "10491", "10492", "10494", "10495", "10497", "10499", "10503", "10504", "10505", "10506", "10508", "10510", "10515", "10516", "10517", "10520", "10523", "10524", "10525", "10527", "10528", "10529", "10530", "10532", "10533", "10536", "10537", "10538", "10539", "10542", "10543", "10544", "10545", "10548", "10550", "10552", "10553", "10555", "10557", "10558", "10559", "10562", "10563", "10566", "10568", "10570", "10572", "10573", "10574", "10576", "10578", "10582", "10583", "10584", "10585", "10587", "10590", "10591", "10592", "10593", "10595", "10598", "10601", "10604", "10606", "10609", "10613", "10614", "10618", "10620", "10622", "10625", "10626", "10627", "10629", "10631", "10634", "10636", "10637", "10638", "10639", "10642", "10643", "10645", "10646", "10648", "10650", "10652", "10653", "10656", "10657", "10658", "10659", "10660", "10662", "10663", "10666", "10668", "10671", "10672", "10673", "10675", "10677", "10679", "10680", "10681", "10683", "10684", "10685", "10686", "10691", "10692", "10697", "10701", "10703", "10704", "10705", "10706", "10708", "10709", "10710", "10711", "10713", "10714", "10717", "10719", "10721", "10722", "10724", "10725", "10726", "10730", "10731", "10737", "10738", "10742", "10744", "10745", "10747", "10748", "10749", "10750", "10753", "10754", "10755", "10757", "10758", "10759", "10760", "10763", "10764", "10765", "10767", "10768", "10769", "10770", "10774", "10776", "10777", "10779", "10780", "10781", "10782", "10784", "10785", "10789", "10790", "10794", "10795", "10798", "10799", "10800", "10801", "10802", "10803", "10804", "10806", "10807", "10808", "10809", "10810", "10812", "10813", "10814", "10815", "10816", "10817", "10819", "10820", "10825", "10827", "10830", "10831", "10832", "10836", "10839", "10841", "10844", "10850", "10851", "10855", "10856", "10859", "10865", "10866", "10869", "10870", "10871", "10872", "10873", "10874", "10875", "10876", "10877", "10880", "10882", "10886", "10888", "10889", "10893", "10894", "10895", "10897", "10898", "10899", "10900", "10901", "10902", "10905", "10907", "10908", "10909", "10911", "10913", "10914", "10916", "10918", "10919", "10922", "10923", "10925", "10927", "10930", "10933", "10935", "10936", "10937", "10939", "10941", "10942", "10944", "10945", "10947", "10948", "10949", "10959", "10961", "10964", "10965", "10968", "10972", "10973", "10974", "10978", "10979", "10980", "10981", "10983", "10987", "10990", "10991", "10992", "10995", "10996", "10997", "11000", "11002", "11003", "11005", "11007", "11008", "11010", "11011", "11015", "11018", "11019", "11024", "11025", "11026", "11028", "11029", "11030", "11033", "11037", "11038", "11039", "11040", "11041", "11045", "11046", "11048", "11049", "11050", "11052", "11054", "11056", "11067", "11069", "11070", "11075", "11076", "11077", "11081", "11082", "11083", "11084", "11085", "11086", "11089", "11090", "11091", "11092", "11093", "11095", "11096", "11098", "11103", "11105", "11106", "11107", "11110", "11113", "11114", "11115", "11116", "11120", "11121", "11128", "11129", "11130", "11131", "11137", "11138", "11140", "11141", "11147", "11148", "11149", "11152", "11153", "11154", "11156", "11157", "11161", "11162", "11163", "11164", "11165", "11172", "11173", "11174", "11176", "11177", "11178", "11179", "11181", "11182", "11185", "11188", "11191", "11193", "11196", "11202", "11203", "11205", "11207", "11209", "11211", "11212", "11216", "11218", "11220", "11221", "11222", "11223", "11226", "11229", "11230", "11231", "11234", "11235", "11238", "11242", "11244", "11246", "11254", "11257", "11259", "11262", "11265", "11266", "11271", "11273", "11275", "11276", "11277", "11278", "11279", "11287", "11288", "11291", "11296", "11299", "11301", "11302", "11305", "11306", "11307", "11308", "11309", "11311", "11312", "11314", "11317", "11318", "11322", "11323", "11325", "11327", "11328", "11332", "11333", "11334", "11335", "11338", "11341", "11346", "11348", "11350", "11351", "11355", "11357", "11358", "11361", "11366", "11367", "11368", "11373", "11374", "11376", "11377", "11379", "11381", "11382", "11388", "11389", "11392", "11396", "11397", "11398", "11399", "11400", "11403", "11404", "11407", "11408", "11410", "11411", "11412", "11414", "11415", "11416", "11417", "11419", "11424", "11426", "11427", "11429", "11430", "11431", "11432", "11433", "11435", "11437", "11438", "11440", "11445", "11446", "11447", "11450", "11451", "11453", "11454", "11461", "11462", "11469", "11471", "11474", "11477", "11478", "11482", "11483", "11489", "11490", "11497", "11498", "11499", "11502", "11504", "11507", "11508", "11509", "11511", "11512", "11515", "11518", "11519", "11520", "11521", "11522", "11524", "11525", "11526", "11527", "11531", "11532", "11533", "11534", "11535", "11536", "11539", "11541", "11544", "11545", "11547", "11548", "11549", "11550", "11551", "11554", "11557", "11558", "11564", "11565", "11566", "11569", "11571", "11572", "11573", "11575", "11576", "11577", "11578", "11580", "11582", "11584", "11585", "11586", "11587", "11588", "11590", "11592", "11594", "11595", "11599", "11600", "11604", "11605", "11606", "11607", "11609", "11610", "11611", "11613", "11615", "11617", "11621", "11623", "11632", "11633", "11636", "11637", "11641", "11642", "11643", "11644", "11645", "11648", "11651", "11652", "11653", "11654", "11655", "11656", "11657", "11659", "11662", "11664", "11665", "11666", "11669", "11672", "11673", "11675", "11677", "11679", "11681", "11687", "11688", "11691", "11695", "11696", "11697", "11698", "11700", "11702", "11703", "11706", "11709", "11710", "11711", "11712", "11714", "11715", "11717", "11718", "11719", "11720", "11721", "11724", "11726", "11728", "11732", "11733", "11734", "11738", "11739", "11742", "11745", "11746", "11747", "11749", "11753", "11755", "11757", "11761", "11762", "11765", "11766", "11769", "11771", "11772", "11773", "11774", "11775", "11777", "11778", "11779", "11782", "11785", "11786", "11788", "11789", "11791", "11792", "11793", "11799", "11800", "11801", "11803", "11806", "11808", "11813", "11815", "11819", "11822", "11823", "11827", "11828", "11832", "11836", "11842", "11843", "11844", "11845", "11850", "11851", "11853", "11854", "11855", "11856", "11860", "11863", "11864", "11865", "11869", "11870", "11871", "11872", "11873", "11875", "11876", "11877", "11878", "11879", "11880", "11884", "11885", "11888", "11889", "11891", "11893", "11894", "11899", "11901", "11906", "11907", "11909", "11914", "11916", "11917", "11918", "11920", "11921", "11924", "11929", "11930", "11931", "11932", "11941", "11942", "11943", "11945", "11947", "11948", "11950", "11952", "11953", "11956", "11957", "11958", "11961", "11962", "11965", "11966", "11967", "11968", "11971", "11972", "11973", "11978", "11979", "11980", "11984", "11985", "11986", "11987", "11988", "11991", "11992", "11998", "12001", "12003", "12004", "12005", "12008", "12009", "12010", "12011", "12016", "12018", "12019", "12020", "12021", "12025", "12026", "12028", "12030", "12033", "12037", "12038", "12039", "12041", "12042", "12045", "12048", "12051", "12057", "12058", "12059", "12062", "12064", "12065", "12066", "12069", "12072", "12073", "12076", "12080", "12082", "12083", "12084", "12086", "12087", "12088", "12091", "12092", "12093", "12095", "12096", "12098", "12101", "12102", "12104", "12105", "12109", "12110", "12111", "12113", "12114", "12115", "12116", "12122", "12124", "12128", "12131", "12132", "12135", "12138", "12142", "12144", "12150", "12151", "12153", "12155", "12160", "12161", "12162", "12164", "12166", "12167", "12170", "12174", "12175", "12176", "12178", "12180", "12181", "12182", "12183", "12184", "12185", "12186", "12187", "12189", "12191", "12193", "12194", "12202", "12203", "12206", "12207", "12209", "12212", "12213", "12214", "12222", "12224", "12229", "12230", "12232", "12235", "12236", "12237", "12238", "12240", "12241", "12243", "12246", "12247", "12249", "12250", "12251", "12252", "12256", "12257", "12258", "12263", "12271", "12273", "12274", "12278", "12289", "12291", "12298", "12301", "12302", "12303", "12304", "12305", "12306", "12309", "12312", "12313", "12315", "12316", "12317", "12319", "12320", "12321", "12322", "12324", "12325", "12326", "12329", "12330", "12331", "12336", "12341", "12342", "12343", "12344", "12345", "12346", "12347", "12348", "12349", "12351", "12352", "12354", "12355", "12358", "12360", "12362", "12363", "12366", "12368", "12371", "12376", "12377", "12378", "12382", "12386", "12388", "12392", "12393", "12396", "12397", "12399", "12401", "12405", "12406", "12409", "12411", "12412", "12413", "12414", "12415", "12418", "12419", "12420", "12424", "12426", "12431", "12434", "12435", "12436", "12439", "12443", "12446", "12448", "12449", "12451", "12452", "12453", "12455", "12456", "12458", "12459", "12460", "12461", "12463", "12464", "12465", "12466", "12470", "12471", "12475", "12479", "12480", "12481", "12482", "12483", "12484", "12487", "12488", "12493", "12494", "12495", "12496", "12497", "12500", "12502", "12504", "12505", "12507", "12511", "12512", "12515", "12516", "12519", "12520", "12522", "12524", "12525", "12530", "12532", "12533", "12537", "12539", "12540", "12543", "12544", "12546", "12547", "12548", "12550", "12551", "12552", "12555", "12557", "12558", "12559", "12566", "12569", "12571", "12572", "12574", "12578", "12580", "12583", "12585", "12587", "12588", "12590", "12591", "12592", "12598", "12600", "12603", "12605", "12608", "12609", "12612", "12613", "12615", "12617", "12618", "12619", "12620", "12621", "12623", "12626", "12627", "12628", "12633", "12634", "12635", "12637", "12639", "12640", "12641", "12643", "12644", "12645", "12646", "12647", "12648", "12649", "12650", "12651", "12656", "12658", "12659", "12660", "12662", "12664", "12665", "12667", "12669", "12670", "12673", "12677", "12678", "12681", "12687", "12688", "12690", "12691", "12693", "12694", "12700", "12701", "12707", "12709", "12710", "12712", "12713", "12714", "12716", "12717", "12718", "12721", "12722", "12727", "12728", "12731", "12732", "12736", "12743", "12745", "12746", "12749", "12750", "12751", "12754", "12756", "12759", "12761", "12763", "12767", "12771", "12772", "12779", "12780", "12781", "12782", "12784", "12787", "12788", "12789", "12790", "12791", "12792", "12795", "12798", "12799", "12800", "12804", "12809", "12810", "12811", "12812", "12813", "12814", "12816", "12817", "12820", "12822", "12823", "12825", "12829", "12830", "12833", "12835", "12836", "12837", "12839", "12840", "12841", "12842", "12846", "12847", "12848", "12849", "12854", "12855", "12857", "12858", "12864", "12865", "12866", "12867", "12871", "12876", "12878", "12880", "12883", "12885", "12886", "12888", "12891", "12892", "12894", "12898", "12900", "12901", "12905", "12906", "12907", "12911", "12912", "12913", "12914", "12915", "12916", "12917", "12920", "12921", "12922", "12924", "12925", "12926", "12927", "12931", "12932", "12933", "12935", "12937", "12938", "12947", "12951", "12952", "12955", "12957", "12960", "12961", "12965", "12968", "12972", "12973", "12979", "12981", "12982", "12983", "12986", "12987", "12989", "12991", "12992", "12995", "13002", "13004", "13005", "13006", "13007", "13008", "13010", "13012", "13014", "13015", "13016", "13017", "13020", "13021", "13022", "13027", "13030", "13034", "13037", "13038", "13040", "13041", "13043", "13045", "13046", "13049", "13051", "13053", "13055", "13059", "13062", "13064", "13068", "13069", "13070", "13073", "13074", "13076", "13078", "13082", "13086", "13087", "13089", "13091", "13094", "13095", "13096", "13097", "13100", "13101", "13107", "13108", "13110", "13111", "13113", "13115", "13116", "13118", "13120", "13121", "13123", "13124", "13127", "13128", "13129", "13130", "13133", "13135", "13136", "13137", "13138", "13139", "13143", "13150", "13151", "13153", "13154", "13155", "13156", "13160", "13161", "13165", "13166", "13167", "13169", "13170", "13171", "13172", "13176", "13178", "13179", "13181", "13182", "13183", "13185", "13186", "13187", "13188", "13189", "13190", "13195", "13199", "13203", "13204", "13207", "13209", "13216", "13219", "13221", "13225", "13227", "13228", "13231", "13233", "13234", "13235", "13236", "13238", "13239", "13240", "13241", "13246", "13251", "13252", "13253", "13254", "13256", "13259", "13263", "13265", "13267", "13268", "13270", "13271", "13272", "13273", "13274", "13276", "13279", "13286", "13287", "13289", "13291", "13292", "13293", "13296", "13297", "13299", "13301", "13304", "13306", "13307", "13308", "13309", "13310", "13311", "13312", "13314", "13316", "13319", "13320", "13321", "13323", "13324", "13328", "13329", "13330", "13331", "13335", "13336", "13339", "13340", "13342", "13345", "13351", "13357", "13358", "13359", "13360", "13370", "13371", "13372", "13374", "13376", "13377", "13380", "13383", "13386", "13387", "13389", "13392", "13393", "13395", "13396", "13398", "13399", "13400", "13402", "13403", "13404", "13407", "13409", "13413", "13414", "13415", "13419", "13420", "13423", "13425", "13428", "13431", "13432", "13433", "13435", "13437", "13438", "13439", "13443", "13451", "13453", "13454", "13455", "13456", "13457", "13458", "13459", "13460", "13464", "13465", "13467", "13469", "13471", "13472", "13476", "13478", "13479", "13481", "13484", "13485", "13488", "13489", "13491", "13492", "13495", "13496", "13497", "13500", "13501", "13504", "13505", "13506", "13514", "13515", "13521", "13522", "13523", "13524", "13525", "13526", "13527", "13528", "13529", "13532", "13533", "13534", "13535", "13540", "13542", "13543", "13546", "13554", "13555", "13557", "13559", "13561", "13562", "13565", "13567", "13568", "13570", "13572", "13575", "13577", "13580", "13582", "13583", "13586", "13587", "13588", "13593", "13594", "13595", "13597", "13599", "13600", "13602", "13603", "13606", "13608", "13609", "13613", "13616", "13618", "13619", "13620", "13623", "13633", "13634", "13637", "13639", "13640", "13641", "13642", "13654", "13655", "13657", "13658", "13659", "13660", "13661", "13662", "13663", "13665", "13669", "13671", "13672", "13673", "13674", "13675", "13678", "13679", "13685", "13690", "13695", "13701", "13703", "13705", "13706", "13708", "13714", "13718", "13721", "13722", "13727", "13728", "13730", "13731", "13732", "13734", "13736", "13737", "13739", "13740", "13741", "13742", "13743", "13745", "13747", "13748", "13749", "13750", "13754", "13755", "13757", "13758", "13761", "13763", "13765", "13766", "13769", "13770", "13772", "13773", "13775", "13779", "13782", "13784", "13785", "13786", "13787", "13789", "13795", "13797", "13799", "13800", "13801", "13802", "13803", "13806", "13807", "13810", "13812", "13813", "13814", "13816", "13817", "13820", "13821", "13822", "13827", "13831", "13832", "13834", "13835", "13836", "13841", "13843", "13847", "13848", "13849", "13852", "13853", "13855", "13857", "13859", "13860", "13862", "13863", "13864", "13865", "13867", "13870", "13871", "13872", "13874", "13877", "13879", "13880", "13882", "13884", "13886", "13887", "13888", "13891", "13895", "13896", "13897", "13899", "13901", "13902", "13903", "13905", "13906", "13908", "13909", "13910", "13911", "13913", "13914", "13916", "13923", "13924", "13927", "13928", "13929", "13930", "13935", "13938", "13940", "13942", "13943", "13944", "13950", "13955", "13956", "13961", "13962", "13964", "13968", "13970", "13971", "13976", "13978", "13982", "13984", "13988", "13990", "13993", "13997", "13998", "13999", "14002", "14003", "14005", "14006", "14007", "14008", "14009", "14010", "14012", "14014", "14020", "14022", "14024", "14025", "14026", "14027", "14028", "14030", "14035", "14036", "14038", "14041", "14042", "14043", "14044", "14045", "14046", "14048", "14049", "14050", "14051", "14053", "14054", "14055", "14058", "14059", "14060", "14062", "14063", "14064", "14065", "14066", "14068", "14069", "14071", "14072", "14073", "14075", "14078", "14084", "14086", "14087", "14088", "14092", "14093", "14094", "14095", "14097", "14099", "14100", "14102", "14106", "14107", "14111", "14112", "14114", "14116", "14118", "14119", "14121", "14124", "14125", "14126", "14128", "14133", "14134", "14135", "14136", "14137", "14139", "14141", "14142", "14144", "14145", "14151", "14152", "14155", "14158", "14162", "14163", "14164", "14167", "14168", "14170", "14171", "14172", "14174", "14175", "14177", "14183", "14185", "14187", "14190", "14193", "14194", "14195", "14198", "14200", "14203", "14204", "14207", "14210", "14212", "14214", "14215", "14220", "14222", "14228", "14234", "14238", "14241", "14242", "14243", "14245", "14248", "14249", "14251", "14252", "14253", "14255", "14259", "14260", "14262", "14263", "14264", "14265", "14267", "14269", "14272", "14273", "14274", "14275", "14276", "14280", "14282", "14284", "14287", "14289", "14291", "14292", "14294", "14295", "14296", "14297", "14298", "14300", "14308", "14310", "14311", "14313", "14315", "14316", "14317", "14319", "14320", "14321", "14322", "14324", "14325", "14326", "14328", "14329", "14330", "14331", "14332", "14337", "14339", "14340", "14341", "14343", "14345", "14346", "14347", "14348", "14349", "14350", "14357", "14358", "14359", "14361", "14362", "14364", "14365", "14367", "14368", "14369", "14373", "14374", "14375", "14377", "14381", "14383", "14390", "14394", "14395", "14400", "14402", "14408", "14409", "14410", "14411", "14412", "14419", "14420", "14421", "14422", "14423", "14424", "14429", "14430", "14431", "14432", "14433", "14435", "14436", "14439", "14440", "14441", "14444", "14446", "14447", "14451", "14453", "14454", "14457", "14458", "14459", "14462", "14463", "14465", "14469", "14470", "14472", "14473", "14474", "14478", "14479", "14484", "14491", "14493", "14494", "14495", "14496", "14497", "14498", "14499", "14500", "14504", "14506", "14508", "14514", "14518", "14522", "14523", "14524", "14525", "14528", "14529", "14531", "14532", "14538", "14539", "14540", "14542", "14543", "14552", "14554", "14556", "14558", "14562", "14563", "14564", "14566", "14568", "14569", "14570", "14571", "14576", "14578", "14580", "14584", "14586", "14587", "14588", "14589", "14593", "14594", "14595", "14597", "14603", "14605", "14609", "14615", "14616", "14619", "14625", "14627", "14628", "14629", "14634", "14635", "14640", "14643", "14646", "14647", "14648", "14649", "14650", "14651", "14652", "14654", "14656", "14657", "14660", "14663", "14664", "14667", "14668", "14669", "14671", "14672", "14673", "14674", "14676", "14681", "14683", "14684", "14685", "14686", "14687", "14689", "14690", "14691", "14692", "14694", "14695", "14696", "14698", "14700", "14702", "14703", "14706", "14709", "14718", "14721", "14723", "14724", "14725", "14726", "14728", "14729", "14730", "14731", "14732", "14733", "14739", "14741", "14742", "14747", "14748", "14749", "14752", "14758", "14759", "14761", "14763", "14766", "14770", "14772", "14775", "14776", "14778", "14779", "14780", "14781", "14787", "14788", "14794", "14796", "14798", "14799", "14801", "14804", "14805", "14807", "14808", "14809", "14810", "14811", "14816", "14817", "14819", "14820", "14822", "14824", "14825", "14827", "14830", "14833", "14834", "14835", "14836", "14837", "14838", "14840", "14842", "14843", "14846", "14847", "14849", "14850", "14851", "14855", "14856", "14858", "14860", "14863", "14864", "14867", "14868", "14869", "14870", "14872", "14873", "14875", "14876", "14877", "14879", "14880", "14883", "14884", "14890", "14891", "14892", "14895", "14896", "14897", "14898", "14899", "14901", "14902", "14903", "14905", "14908", "14911", "14914", "14919", "14921", "14925", "14926", "14927", "14928", "14933", "14935", "14936", "14937", "14938", "14939", "14941", "14942", "14943", "14944", "14946", "14947", "14949", "14950", "14954", "14955", "14957", "14958", "14960", "14962", "14963", "14969", "14970", "14971", "14973", "14977", "14978", "14981", "14983", "14986", "14987", "14989", "14990", "14991", "14993", "14996", "14997", "15000", "15001", "15002", "15004", "15006", "15007", "15008", "15011", "15012", "15014", "15026", "15028", "15029", "15030", "15034", "15039", "15040", "15041", "15044", "15045", "15047", "15048", "15051", "15052", "15054", "15055", "15057", "15058", "15062", "15064", "15065", "15066", "15067", "15069", "15070", "15071", "15072", "15074", "15077", "15078", "15087", "15088", "15091", "15092", "15093", "15094", "15095", "15096", "15098", "15100", "15101", "15103", "15106", "15107", "15108", "15110", "15112", "15113", "15114", "15115", "15118", "15121", "15123", "15124", "15125", "15126", "15127", "15128", "15131", "15132", "15133", "15135", "15139", "15140", "15141", "15142", "15143", "15145", "15146", "15147", "15148", "15150", "15153", "15154", "15155", "15157", "15159", "15162", "15163", "15164", "15166", "15168", "15170", "15172", "15173", "15178", "15182", "15183", "15184", "15185", "15191", "15201", "15207", "15208", "15209", "15213", "15215", "15217", "15218", "15220", "15222", "15228", "15229", "15230", "15232", "15233", "15234", "15242", "15243", "15244", "15245", "15246", "15247", "15248", "15249", "15250", "15251", "15254", "15256", "15257", "15259", "15261", "15263", "15268", "15269", "15271", "15274", "15276", "15277", "15278", "15279", "15282", "15283", "15285", "15286", "15287", "15288", "15289", "15290", "15293", "15294", "15295", "15298", "15302", "15309", "15311", "15312", "15314", "15316", "15317", "15318", "15319", "15325", "15326", "15328", "15329", "15330", "15332", "15335", "15341", "15344", "15345", "15346", "15347", "15349", "15351", "15353", "15354", "15355", "15360", "15361", "15365", "15366", "15367", "15369", "15370", "15374", "15375", "15377", "15379", "15380", "15381", "15385", "15386", "15393", "15394", "15395", "15397", "15399", "15400", "15401", "15402", "15404", "15408", "15409", "15410", "15411", "15413", "15415", "15416", "15421", "15425", "15428", "15433", "15434", "15436", "15437", "15438", "15441", "15446", "15448", "15449", "15450", "15453", "15454", "15456", "15457", "15458", "15459", "15460", "15461", "15462", "15465", "15466", "15470", "15471", "15474", "15475", "15478", "15479", "15481", "15483", "15485", "15487", "15488", "15489", "15492", "15494", "15496", "15497", "15498", "15500", "15501", "15503", "15506", "15507", "15508", "15510", "15511", "15515", "15516", "15520", "15521", "15523", "15524", "15525", "15527", "15530", "15532", "15537", "15539", "15540", "15541", "15543", "15548", "15549", "15550", "15551", "15552", "15555", "15557", "15558", "15559", "15560", "15562", "15563", "15564", "15567", "15568", "15569", "15572", "15575", "15576", "15577", "15578", "15581", "15582", "15584", "15585", "15586", "15588", "15590", "15592", "15593", "15596", "15597", "15598", "15599", "15600", "15601", "15602", "15607", "15611", "15612", "15614", "15619", "15621", "15624", "15625", "15626", "15628", "15630", "15631", "15633", "15634", "15635", "15637", "15640", "15642", "15645", "15646", "15647", "15649", "15655", "15656", "15658", "15659", "15660", "15661", "15664", "15667", "15668", "15669", "15670", "15672", "15674", "15675", "15676", "15677", "15682", "15683", "15687", "15688", "15689", "15690", "15691", "15692", "15694", "15695", "15696", "15697", "15699", "15701", "15702", "15703", "15704", "15705", "15708", "15709", "15710", "15714", "15720", "15721", "15722", "15723", "15725", "15726", "15727", "15728", "15729", "15731", "15733", "15734", "15735", "15737", "15738", "15739", "15740", "15741", "15744", "15745", "15746", "15747", "15748", "15749", "15754", "15755", "15756", "15757", "15759", "15764", "15765", "15766", "15767", "15768", "15769", "15770", "15771", "15777", "15778", "15779", "15780", "15784", "15786", "15788", "15789", "15794", "15797", "15798", "15799", "15801", "15806", "15808", "15811", "15814", "15817", "15818", "15819", "15820", "15821", "15822", "15829", "15831", "15832", "15833", "15834", "15836", "15837", "15838", "15839", "15840", "15841", "15844", "15847", "15848", "15852", "15854", "15855", "15856", "15858", "15859", "15860", "15865", "15867", "15868", "15869", "15871", "15874", "15880", "15882", "15884", "15885", "15887", "15889", "15891", "15892", "15894", "15895", "15897", "15898", "15899", "15901", "15902", "15905", "15910", "15911", "15912", "15915", "15917", "15918", "15924", "15928", "15929", "15932", "15933", "15934", "15936", "15937", "15939", "15940", "15941", "15942", "15943", "15944", "15945", "15946", "15949", "15952", "15954", "15955", "15956", "15958", "15960", "15962", "15963", "15964", "15965", "15968", "15969", "15970", "15972", "15973", "15977", "15979", "15980", "15986", "15993", "15995", "15998", "15999", "16000", "16001", "16007", "16009", "16010", "16012", "16013", "16015", "16016", "16017", "16018", "16022", "16024", "16025", "16028", "16030", "16033", "16035", "16038", "16044", "16046", "16049", "16050", "16051", "16052", "16053", "16054", "16055", "16057", "16058", "16060", "16063", "16065", "16067", "16070", "16071", "16074", "16075", "16077", "16078", "16079", "16084", "16088", "16089", "16090", "16091", "16094", "16096", "16097", "16100", "16101", "16104", "16105", "16106", "16109", "16111", "16112", "16113", "16114", "16115", "16116", "16117", "16121", "16130", "16133", "16134", "16136", "16137", "16138", "16139", "16141", "16143", "16144", "16146", "16150", "16151", "16157", "16158", "16159", "16160", "16161", "16163", "16166", "16167", "16170", "16174", "16175", "16178", "16179", "16180", "16181", "16183", "16186", "16190", "16191", "16192", "16194", "16198", "16199", "16201", "16202", "16208", "16213", "16215", "16216", "16217", "16220", "16222", "16225", "16226", "16228", "16231", "16232", "16237", "16238", "16242", "16243", "16246", "16249", "16250", "16251", "16252", "16255", "16256", "16259", "16260", "16261", "16262", "16264", "16266", "16270", "16272", "16274", "16276", "16278", "16280", "16281", "16282", "16284", "16288", "16293", "16297", "16300", "16305", "16307", "16308", "16310", "16319", "16322", "16323", "16324", "16325", "16327", "16330", "16331", "16334", "16335", "16339", "16341", "16344", "16346", "16347", "16351", "16352", "16357", "16358", "16359", "16360", "16361", "16363", "16364", "16365", "16369", "16370", "16378", "16380", "16381", "16382", "16383", "16384", "16385", "16387", "16388", "16390", "16393", "16395", "16396", "16397", "16399", "16401", "16402", "16403", "16405", "16407", "16408", "16411", "16413", "16414", "16416", "16419", "16421", "16422", "16426", "16427", "16429", "16431", "16434", "16436", "16437", "16438", "16439", "16440", "16442", "16443", "16447", "16448", "16450", "16451", "16452", "16457", "16458", "16459", "16460", "16463", "16464", "16465", "16467", "16468", "16470", "16472", "16474", "16475", "16479", "16480", "16484", "16486", "16487", "16488", "16489", "16490", "16499", "16501", "16505", "16507", "16508", "16514", "16518", "16519", "16521", "16522", "16524", "16526", "16527", "16529", "16530", "16531", "16532", "16535", "16539", "16542", "16543", "16544", "16547", "16548", "16549", "16551", "16553", "16555", "16557", "16559", "16560", "16561", "16562", "16563", "16565", "16568", "16569", "16570", "16572", "16573", "16574", "16575", "16577", "16579", "16580", "16581", "16584", "16586", "16587", "16588", "16589", "16591", "16593", "16595", "16596", "16598", "16606", "16607", "16608", "16609", "16610", "16611", "16612", "16614", "16616", "16622", "16625", "16629", "16630", "16631", "16632", "16635", "16636", "16637", "16638", "16640", "16641", "16642", "16643", "16644", "16649", "16650", "16651", "16653", "16654", "16656", "16661", "16662", "16663", "16664", "16665", "16666", "16667", "16668", "16672", "16674", "16677", "16678", "16679", "16681", "16682", "16685", "16687", "16691", "16692", "16693", "16694", "16696", "16697", "16699", "16700", "16702", "16703", "16704", "16705", "16706", "16707", "16708", "16710", "16714", "16716", "16719", "16727", "16729", "16736", "16738", "16739", "16740", "16741", "16742", "16743", "16745", "16746", "16748", "16749", "16751", "16752", "16753", "16755", "16756", "16757", "16758", "16761", "16762", "16763", "16767", "16770", "16772", "16774", "16776", "16777", "16778", "16779", "16781", "16783", "16784", "16785", "16788", "16790", "16791", "16792", "16793", "16797", "16798", "16800", "16803", "16804", "16806", "16807", "16808", "16811", "16813", "16816", "16820", "16822", "16824", "16826", "16827", "16833", "16834", "16835", "16839", "16840", "16841", "16842", "16843", "16844", "16845", "16846", "16847", "16848", "16849", "16851", "16852", "16854", "16855", "16857", "16859", "16860", "16861", "16862", "16863", "16864", "16870", "16873", "16875", "16876", "16877", "16879", "16880", "16882", "16884", "16885", "16886", "16887", "16889", "16891", "16893", "16898", "16901", "16903", "16905", "16908", "16910", "16913", "16916", "16917", "16920", "16921", "16924", "16926", "16928", "16929", "16930", "16936", "16937", "16938", "16941", "16942", "16943", "16946", "16947", "16948", "16949", "16950", "16953", "16954", "16956", "16958", "16959", "16960", "16963", "16964", "16965", "16966", "16968", "16970", "16971", "16972", "16976", "16977", "16979", "16980", "16981", "16982", "16986", "16987", "16989", "16990", "16992", "16994", "16995", "16998", "16999", "17000", "17001", "17003", "17004", "17006", "17007", "17009", "17011", "17012", "17013", "17015", "17016", "17018", "17024", "17026", "17028", "17029", "17030", "17032", "17036", "17037", "17038", "17039", "17040", "17045", "17046", "17048", "17049", "17052", "17053", "17055", "17059", "17065", "17066", "17067", "17069", "17070", "17072", "17074", "17075", "17076", "17079", "17080", "17081", "17083", "17085", "17086", "17088", "17090", "17091", "17092", "17096", "17097", "17098", "17099", "17100", "17101", "17103", "17104", "17108", "17109", "17110", "17114", "17115", "17118", "17120", "17121", "17122", "17125", "17127", "17131", "17132", "17133", "17135", "17136", "17138", "17141", "17143", "17144", "17145", "17146", "17147", "17148", "17150", "17151", "17155", "17160", "17162", "17164", "17167", "17171", "17172", "17174", "17175", "17178", "17179", "17181", "17183", "17190", "17193", "17199", "17202", "17203", "17205", "17209", "17211", "17213", "17214", "17215", "17216", "17217", "17218", "17219", "17223", "17224", "17226", "17227", "17231", "17233", "17235", "17236", "17237", "17241", "17243", "17244", "17246", "17249", "17251", "17252", "17256", "17259", "17260", "17261", "17262", "17266", "17268", "17269", "17270", "17275", "17276", "17277", "17278", "17280", "17281", "17283", "17287", "17288", "17289", "17290", "17293", "17295", "17298", "17300", "17302", "17303", "17306", "17311", "17314", "17315", "17316", "17318", "17319", "17320", "17321", "17325", "17327", "17328", "17329", "17332", "17333", "17335", "17336", "17337", "17338", "17340", "17346", "17347", "17348", "17349", "17351", "17352", "17353", "17354", "17355", "17357", "17359", "17360", "17361", "17363", "17365", "17366", "17367", "17368", "17373", "17375", "17377", "17381", "17384", "17388", "17389", "17392", "17396", "17398", "17399", "17401", "17405", "17406", "17417", "17418", "17420", "17423", "17427", "17429", "17430", "17432", "17434", "17442", "17444", "17445", "17446", "17448", "17451", "17453", "17459", "17461", "17466", "17470", "17472", "17473", "17475", "17476", "17480", "17481", "17482", "17483", "17486", "17487", "17488", "17490", "17495", "17497", "17500", "17501", "17502", "17506", "17508", "17511", "17512", "17514", "17520", "17521", "17522", "17523", "17524", "17526", "17527", "17528", "17529", "17530", "17534", "17538", "17539", "17540", "17541", "17543", "17544", "17545", "17546", "17547", "17548", "17549", "17550", "17552", "17553", "17555", "17556", "17559", "17565", "17569", "17570", "17573", "17574", "17577", "17580", "17581", "17582", "17583", "17584", "17587", "17588", "17589", "17591", "17593", "17594", "17596", "17599", "17603", "17605", "17606", "17607", "17608", "17609", "17613", "17614", "17617", "17618", "17619", "17620", "17625", "17626", "17627", "17629", "17630", "17633", "17634", "17637", "17639", "17640", "17641", "17645", "17646", "17648", "17651", "17652", "17653", "17654", "17655", "17656", "17660", "17664", "17666", "17668", "17671", "17673", "17675", "17677", "17678", "17680", "17681", "17682", "17683", "17685", "17686", "17688", "17689", "17692", "17693", "17694", "17696", "17697", "17701", "17702", "17704", "17707", "17711", "17712", "17713", "17714", "17716", "17717", "17721", "17722", "17723", "17725", "17727", "17728", "17730", "17731", "17732", "17733", "17735", "17738", "17743", "17744", "17745", "17746", "17748", "17749", "17750", "17753", "17755", "17757", "17759", "17761", "17762", "17765", "17766", "17769", "17770", "17771", "17774", "17777", "17779", "17780", "17781", "17782", "17783", "17784", "17787", "17788", "17790", "17792", "17793", "17796", "17797", "17799", "17800", "17801", "17802", "17803", "17805", "17806", "17807", "17808", "17810", "17812", "17813", "17814", "17816", "17817", "17818", "17820", "17821", "17822", "17823", "17824", "17828", "17830", "17835", "17837", "17838", "17839", "17840", "17841", "17843", "17845", "17847", "17848", "17849", "17850", "17851", "17853", "17855", "17856", "17858", "17860", "17861", "17864", "17865", "17868", "17871", "17873", "17874", "17876", "17877", "17878", "17881", "17885", "17887", "17889", "17891", "17897", "17901", "17904", "17905", "17907", "17909", "17912", "17916", "17917", "17918", "17920", "17921", "17924", "17925", "17934", "17935", "17936", "17938", "17939", "17941", "17943", "17944", "17945", "17946", "17947", "17948", "17953", "17954", "17955", "17957", "17958", "17960", "17961", "17962", "17963", "17964", "17965", "17967", "17970", "17973", "17979", "17981", "17982", "17986", "17992", "17995", "17997", "17999", "18001", "18002", "18006", "18013", "18017", "18019", "18021", "18023", "18024", "18025", "18028", "18029", "18036", "18037", "18039", "18044", "18045", "18048", "18049", "18051", "18054", "18056", "18057", "18058", "18061", "18062", "18063", "18064", "18066", "18067", "18068", "18070", "18072", "18074", "18077", "18086", "18087", "18088", "18090", "18091", "18093", "18094", "18096", "18099", "18101", "18102", "18103", "18105", "18106", "18107", "18109", "18110", "18111", "18112", "18114", "18115", "18121", "18122", "18123", "18124", "18127", "18128", "18129", "18131", "18133", "18134", "18137", "18138", "18139", "18142", "18143", "18144", "18145", "18146", "18148", "18152", "18153", "18155", "18158", "18163", "18166", "18168", "18170", "18171", "18172", "18176", "18177", "18178", "18179", "18180", "18181", "18185", "18189", "18191", "18193", "18194", "18196", "18197", "18200", "18205", "18214", "18217", "18221", "18224", "18225", "18226", "18227", "18230", "18231", "18232", "18234", "18235", "18238", "18240", "18242", "18243", "18244", "18246", "18247", "18255", "18257", "18258", "18260", "18261", "18263", "18266", "18267", "18268", "18270", "18271", "18273", "18280", "18281", "18282", "18286", "18287", "18288", "18290", "18291", "18293", "18294", "18300", "18301", "18303", "18304", "18305", "18307", "18308", "18309", "18311", "18313", "18314", "18317", "18318", "18319", "18320", "18321", "18325", "18328", "18329", "18334", "18336", "18337", "18338", "18339", "18340", "18344", "18345", "18346", "18347", "18348", "18349", "18351", "18353", "18355", "18356", "18357", "18359", "18360", "18363", "18364", "18365", "18366", "18367", "18368", "18370", "18371", "18372", "18374", "18380", "18383", "18384", "18385", "18386", "18388", "18390", "18392", "18393", "18394", "18395", "18397", "18399", "18401", "18403", "18404", "18405", "18406", "18410", "18415", "18418", "18420", "18422", "18423", "18425", "18429", "18430", "18432", "18434", "18440", "18442", "18446", "18448", "18452", "18453", "18459", "18460", "18461", "18463", "18464", "18467", "18468", "18470", "18472", "18473", "18476", "18477", "18481", "18482", "18483", "18485", "18486", "18492", "18493", "18494", "18498", "18503", "18504", "18505", "18506", "18508", "18510", "18513", "18515", "18516", "18521", "18522", "18525", "18531", "18532", "18533", "18536", "18538", "18539", "18540", "18544", "18545", "18548", "18554", "18558", "18559", "18560", "18561", "18562", "18564", "18567", "18568", "18572", "18573", "18577", "18581", "18582", "18585", "18589", "18590", "18593", "18595", "18596", "18597", "18600", "18602", "18607", "18609", "18610", "18611", "18615", "18616", "18617", "18620", "18622", "18624", "18627", "18632", "18634", "18638", "18640", "18641", "18642", "18643", "18645", "18646", "18651", "18652", "18653", "18658", "18659", "18660", "18662", "18663", "18666", "18668", "18673", "18674", "18675", "18676", "18678", "18680", "18681", "18683", "18684", "18687", "18688", "18689", "18691", "18693", "18695", "18696", "18697", "18699", "18702", "18705", "18706", "18707", "18708", "18709", "18710", "18711", "18712", "18713", "18716", "18717", "18718", "18720", "18721", "18723", "18724", "18725", "18726", "18728", "18730", "18731", "18732", "18737", "18740", "18743", "18745", "18748", "18751", "18752", "18753", "18756", "18757", "18758", "18762", "18763", "18764", "18765", "18767", "18771", "18776", "18777", "18778", "18780", "18781", "18784", "18789", "18791", "18793", "18798", "18800", "18801", "18802", "18806", "18807", "18808", "18812", "18815", "18818", "18819", "18821", "18823", "18824", "18826", "18828", "18829", "18832", "18833", "18836", "18841", "18842", "18844", "18849", "18851", "18852", "18853", "18856", "18857", "18858", "18859", "18862", "18864", "18870", "18873", "18878", "18881", "18883", "18885", "18886", "18888", "18889", "18890", "18892", "18893", "18896", "18897", "18898", "18899", "18901", "18903", "18905", "18907", "18908", "18909", "18911", "18912", "18913", "18914", "18918", "18920", "18921", "18923", "18928", "18929", "18930", "18934", "18939", "18941", "18942", "18943", "18944", "18945", "18946", "18947", "18948", "18949", "18950", "18952", "18955", "18956", "18957", "18959", "18963", "18964", "18965", "18967", "18968", "18970", "18973", "18974", "18981", "18983", "18985", "18988", "18991", "18992", "18994", "19000", "19002", "19003", "19011", "19012", "19014", "19015", "19016", "19018", "19021", "19022", "19026", "19027", "19028", "19030", "19031", "19034", "19035", "19036", "19037", "19040", "19041", "19044", "19052", "19059", "19060", "19065", "19066", "19067", "19069", "19071", "19072", "19073", "19075", "19076", "19078", "19081", "19083", "19084", "19085", "19088", "19089", "19091", "19096", "19097", "19103", "19105", "19106", "19107", "19108", "19109", "19113", "19117", "19120", "19121", "19122", "19124", "19125", "19128", "19132", "19135", "19136", "19138", "19141", "19142", "19146", "19147", "19148", "19150", "19152", "19154", "19155", "19158", "19159", "19160", "19161", "19163", "19165", "19166", "19167", "19168", "19169", "19170", "19172", "19174", "19178", "19179", "19180", "19183", "19184", "19186", "19187", "19189", "19190", "19192", "19198", "19199", "19200", "19201", "19205", "19207", "19208", "19211", "19213", "19215", "19218", "19221", "19223", "19229", "19231", "19232", "19236", "19237", "19240", "19241", "19242", "19243", "19244", "19246", "19247", "19248", "19250", "19251", "19253", "19254", "19256", "19260", "19263", "19264", "19265", "19266", "19267", "19269", "19270", "19271", "19274", "19277", "19278", "19280", "19281", "19282", "19284", "19285", "19287", "19288", "19289", "19290", "19291", "19292", "19293", "19294", "19295", "19296", "19297", "19298", "19299", "19301", "19304", "19305", "19307", "19311", "19312", "19313", "19314", "19316", "19318", "19321", "19323", "19324", "19330", "19331", "19332", "19333", "19335", "19336", "19337", "19338", "19339", "19342", "19345", "19346", "19347", "19348", "19349", "19351", "19355", "19357", "19358", "19359", "19360", "19361", "19362", "19367", "19369", "19372", "19373", "19384", "19386", "19388", "19391", "19394", "19396", "19397", "19398", "19400", "19401", "19402", "19403", "19404", "19405", "19407", "19409", "19411", "19412", "19414", "19415", "19416", "19418", "19421", "19422", "19424", "19427", "19429", "19432", "19434", "19435", "19436", "19439", "19441", "19442", "19444", "19449", "19450", "19451", "19452", "19454", "19457", "19458", "19464", "19467", "19468", "19469", "19472", "19477", "19478", "19480", "19481", "19482", "19485", "19486", "19487", "19489", "19493", "19494", "19495", "19498", "19499", "19502", "19503", "19504", "19505", "19513", "19515", "19517", "19518", "19520", "19522", "19523", "19525", "19526", "19527", "19528", "19531", "19532", "19533", "19536", "19537", "19538", "19539", "19540", "19541", "19542", "19543", "19545", "19548", "19549", "19551", "19552", "19556", "19557", "19559", "19562", "19569", "19572", "19573", "19575", "19579", "19580", "19581", "19583", "19585", "19586", "19587", "19589", "19590", "19593", "19594", "19596", "19599", "19601", "19602", "19607", "19608", "19609", "19611", "19613", "19614", "19621", "19625", "19626", "19632", "19635", "19636", "19637", "19638", "19639", "19641", "19643", "19644", "19645", "19650", "19651", "19654", "19658", "19663", "19665", "19666", "19668", "19669", "19670", "19671", "19675", "19676", "19677", "19678", "19679", "19683", "19684", "19686", "19688", "19690", "19691", "19693", "19694", "19695", "19696", "19698", "19701", "19704", "19707", "19708", "19709", "19712", "19713", "19714", "19716", "19718", "19719", "19721", "19722", "19725", "19731", "19733", "19734", "19735", "19737", "19738", "19739", "19740", "19746", "19747", "19748", "19752", "19756", "19759", "19760", "19761", "19763", "19765", "19768", "19770", "19779", "19780", "19782", "19784", "19787", "19789", "19791", "19793", "19794", "19796", "19797", "19798", "19800", "19801", "19802", "19803", "19806", "19809", "19812", "19813", "19827", "19830", "19831", "19833", "19835", "19837", "19838", "19839", "19840", "19844", "19845", "19846", "19847", "19848", "19850", "19859", "19860", "19861", "19863", "19867", "19870", "19875", "19877", "19878", "19879", "19882", "19886", "19890", "19891", "19893", "19894", "19895", "19903", "19909", "19910", "19911", "19912", "19915", "19917", "19920", "19921", "19922", "19926", "19927", "19928", "19935", "19936", "19938", "19939", "19940", "19944", "19945", "19946", "19947", "19948", "19949", "19951", "19953", "19954", "19955", "19959", "19960", "19963", "19964", "19965", "19966", "19972", "19975", "19976", "19978", "19979", "19982", "19983", "19984", "19988", "19989", "19990", "19991", "19995", "19997", "19998", "20001", "20002", "20003", "20004", "20005", "20006", "20009", "20011", "20012", "20013", "20016", "20017", "20019", "20021", "20022", "20023", "20024", "20028", "20029", "20031", "20032", "20034", "20035", "20037", "20038", "20043", "20045", "20047", "20048", "20049", "20050", "20051", "20052", "20053", "20055", "20057", "20059", "20060", "20062", "20065", "20066", "20071", "20073", "20074", "20076", "20077", "20080", "20083", "20084", "20085", "20086", "20087", "20088", "20089", "20091", "20093", "20095", "20096", "20097", "20098", "20101", "20105", "20108", "20110", "20112", "20113", "20120", "20122", "20126", "20127", "20128", "20132", "20136", "20137", "20141", "20142", "20143", "20144", "20145", "20146", "20148", "20149", "20153", "20156", "20157", "20159", "20160", "20166", "20173", "20174", "20176", "20177", "20180", "20181", "20182", "20183", "20186", "20187", "20191", "20192", "20195", "20196", "20197", "20198", "20199", "20200", "20201", "20205", "20206", "20211", "20213", "20215", "20221", "20222", "20223", "20225", "20227", "20228", "20230", "20233", "20235", "20236", "20237", "20238", "20239", "20242", "20243", "20247", "20248", "20249", "20250", "20253", "20255", "20256", "20259", "20263", "20266", "20267", "20268", "20269", "20278", "20280", "20281", "20284", "20287", "20288", "20289", "20290", "20292", "20293", "20295", "20297", "20298", "20299", "20301", "20302", "20304", "20305", "20306", "20307", "20308", "20310", "20311", "20314", "20318", "20319", "20322", "20325", "20326", "20330", "20334", "20336", "20340", "20347", "20348", "20350", "20352", "20353", "20354", "20355", "20357", "20358", "20359", "20360", "20365", "20366", "20367", "20368", "20369", "20370", "20371", "20372", "20373", "20374", "20375", "20377", "20378", "20379", "20388", "20390", "20396", "20397", "20401", "20403", "20404", "20414", "20417", "20420", "20421", "20424", "20426", "20428", "20430", "20431", "20432", "20433", "20434", "20436", "20439", "20443", "20444", "20445", "20453", "20455", "20456", "20457", "20458", "20460", "20462", "20463", "20464", "20465", "20468", "20469", "20470", "20472", "20473", "20475", "20478", "20480", "20482", "20483", "20484", "20485", "20487", "20488", "20489", "20491", "20493", "20494", "20497", "20500", "20502", "20503", "20504", "20506", "20507", "20508", "20511", "20515", "20516", "20519", "20522", "20523", "20527", "20529", "20531", "20532", "20533", "20534", "20536", "20539", "20543", "20544", "20545", "20546", "20547", "20548", "20549", "20551", "20552", "20553", "20556", "20558", "20559", "20565", "20567", "20571", "20572", "20577", "20578", "20580", "20584", "20585", "20587", "20588", "20589", "20590", "20598", "20600", "20602", "20603", "20605", "20606", "20608", "20609", "20615", "20617", "20620", "20621", "20622", "20626", "20627", "20630", "20631", "20634", "20637", "20638", "20642", "20644", "20645", "20646", "20647", "20648", "20651", "20652", "20653", "20654", "20656", "20657", "20660", "20666", "20668", "20669", "20670", "20672", "20679", "20680", "20681", "20682", "20685", "20686", "20687", "20689", "20690", "20692", "20693", "20694", "20695", "20697", "20698", "20700", "20702", "20706", "20707", "20708", "20710", "20716", "20717", "20720", "20721", "20722", "20723", "20724", "20725", "20727", "20730", "20733", "20734", "20736", "20737", "20742", "20744", "20746", "20750", "20752", "20753", "20754", "20755", "20757", "20759", "20761", "20764", "20766", "20767", "20768", "20770", "20771", "20773", "20778", "20779", "20780", "20781", "20782", "20783", "20784", "20786", "20789", "20791", "20792", "20793", "20795", "20797", "20798", "20800", "20801", "20804", "20808", "20809", "20810", "20812", "20814", "20816", "20818", "20823", "20828", "20829", "20830", "20832", "20835", "20836", "20837", "20838", "20839", "20841", "20844", "20849", "20852", "20856", "20857", "20859", "20860", "20861", "20864", "20865", "20866", "20870", "20875", "20878", "20879", "20880", "20885", "20886", "20888", "20889", "20891", "20892", "20894", "20895", "20900", "20907", "20910", "20914", "20915", "20918", "20921", "20923", "20924", "20928", "20931", "20937", "20941", "20943", "20944", "20946", "20950", "20953", "20954", "20956", "20957", "20959", "20962", "20963", "20967", "20968", "20970", "20972", "20973", "20974", "20980", "20982", "20983", "20984", "20987", "20988", "20990", "20991", "20992", "20993", "20994", "20996", "20998", "21000", "21003", "21004", "21005", "21008", "21013", "21019", "21021", "21023", "21026", "21029", "21033", "21034", "21036", "21041", "21043", "21044", "21045", "21048", "21049", "21050", "21053", "21057", "21058", "21059", "21060", "21061", "21062", "21066", "21068", "21069", "21070", "21071", "21072", "21075", "21078", "21079", "21081", "21082", "21083", "21085", "21086", "21087", "21088", "21089", "21093", "21099", "21102", "21104", "21108", "21116", "21117", "21123", "21124", "21125", "21126", "21127", "21128", "21132", "21134", "21137", "21139", "21145", "21146", "21147", "21149", "21150", "21152", "21155", "21159", "21160", "21161", "21165", "21166", "21169", "21171", "21175", "21180", "21181", "21184", "21185", "21186", "21189", "21193", "21194", "21197", "21201", "21202", "21205", "21206", "21207", "21209", "21210", "21213", "21214", "21215", "21219", "21220", "21221", "21222", "21223", "21224", "21225", "21233", "21236", "21238", "21239", "21244", "21247", "21248", "21252", "21256", "21257", "21260", "21265", "21267", "21268", "21269", "21270", "21271", "21273", "21274", "21275", "21277", "21279", "21280", "21281", "21282", "21284", "21285", "21286", "21287", "21289", "21290", "21292", "21293", "21294", "21295", "21296", "21298", "21299", "21300", "21304", "21305", "21307", "21309", "21311", "21313", "21315", "21317", "21320", "21322", "21324", "21325", "21326", "21327", "21329", "21330", "21331", "21332", "21335", "21336", "21339", "21343", "21346", "21347", "21348", "21349", "21350", "21352", "21353", "21355", "21358", "21362", "21368", "21372", "21373", "21374", "21379", "21381", "21382", "21383", "21385", "21388", "21389", "21397", "21398", "21399", "21401", "21402", "21404", "21406", "21407", "21408", "21409", "21410", "21412", "21413", "21414", "21415", "21417", "21419", "21421", "21423", "21427", "21428", "21429", "21432", "21433", "21434", "21435", "21436", "21440", "21441", "21443", "21445", "21446", "21447", "21448", "21449", "21451", "21454", "21455", "21456", "21459", "21460", "21462", "21463", "21464", "21465", "21466", "21467", "21468", "21469", "21473", "21474", "21476", "21478", "21479", "21481", "21482", "21489", "21490", "21491", "21492", "21494", "21496", "21498", "21499", "21501", "21503", "21505", "21508", "21509", "21511", "21514", "21517", "21519", "21524", "21528", "21529", "21530", "21531", "21532", "21533", "21535", "21538", "21540", "21541", "21544", "21546", "21548", "21549", "21553", "21554", "21556", "21557", "21559", "21562", "21564", "21565", "21566", "21567", "21568", "21571", "21574", "21575", "21578", "21582", "21583", "21584", "21587", "21588", "21590", "21591", "21592", "21593", "21594", "21598", "21601", "21605", "21606", "21607", "21610", "21614", "21617", "21620", "21621", "21624", "21625", "21627", "21629", "21631", "21632", "21634", "21635", "21639", "21642", "21644", "21646", "21647", "21648", "21649", "21651", "21652", "21654", "21656", "21658", "21664", "21666", "21667", "21668", "21669", "21670", "21673", "21678", "21680", "21681", "21682", "21683", "21686", "21688", "21692", "21693", "21695", "21697", "21699", "21703", "21705", "21706", "21708", "21710", "21712", "21713", "21715", "21717", "21718", "21719", "21720", "21721", "21725", "21727", "21729", "21730", "21731", "21733", "21734", "21735", "21737", "21738", "21741", "21742", "21743", "21747", "21750", "21752", "21760", "21761", "21762", "21763", "21764", "21766", "21767", "21772", "21773", "21774", "21778", "21781", "21784", "21786", "21788", "21789", "21790", "21791", "21796", "21797", "21803", "21805", "21806", "21809", "21810", "21812", "21813", "21815", "21818", "21819", "21821", "21827", "21831", "21832", "21833", "21834", "21836", "21839", "21840", "21844", "21847", "21848", "21850", "21852", "21853", "21854", "21856", "21860", "21862", "21865", "21869", "21870", "21872", "21874", "21877", "21879", "21880", "21881", "21882", "21885", "21886", "21887", "21891", "21892", "21896", "21901", "21902", "21904", "21905", "21907", "21908", "21911", "21917", "21921", "21922", "21923", "21925", "21926", "21927", "21934", "21935", "21936", "21940", "21941", "21950", "21952", "21955", "21958", "21959", "21960", "21965", "21966", "21967", "21968", "21969", "21971", "21972", "21973", "21975", "21977", "21979", "21980", "21981", "21987", "21988", "21990", "21992", "21994", "21995", "21998", "22001", "22003", "22004", "22005", "22006", "22011", "22012", "22013", "22014", "22015", "22017", "22022", "22025", "22026", "22029", "22032", "22033", "22034", "22039", "22042", "22044", "22045", "22046", "22048", "22049", "22050", "22051", "22052", "22055", "22057", "22059", "22062", "22064", "22065", "22067", "22075", "22077", "22080", "22082", "22083", "22090", "22093", "22096", "22099", "22101", "22103", "22105", "22110", "22112", "22113", "22123", "22128", "22130", "22131", "22133", "22135", "22136", "22139", "22140", "22142", "22143", "22144", "22145", "22146", "22147", "22148", "22153", "22154", "22155", "22156", "22158", "22160", "22161", "22163", "22164", "22165", "22167", "22168", "22170", "22172", "22174", "22175", "22178", "22179", "22183", "22185", "22190", "22193", "22197", "22200", "22201", "22202", "22203", "22205", "22207", "22208", "22209", "22210", "22213", "22215", "22216", "22217", "22218", "22220", "22223", "22225", "22226", "22227", "22229", "22230", "22231", "22232", "22234", "22235", "22238", "22241", "22246", "22248", "22249", "22251", "22252", "22253", "22256", "22257", "22261", "22263", "22264", "22265", "22266", "22267", "22269", "22272", "22273", "22275", "22276", "22278", "22282", "22283", "22287", "22288", "22290", "22291", "22292", "22295", "22298", "22300", "22302", "22305", "22306", "22308", "22309", "22310", "22312", "22313", "22315", "22317", "22318", "22320", "22321", "22325", "22330", "22336", "22338", "22340", "22341", "22342", "22343", "22344", "22347", "22349", "22351", "22352", "22354", "22356", "22358", "22362", "22363", "22365", "22366", "22368", "22370", "22371", "22373", "22374", "22381", "22382", "22387", "22388", "22389", "22390", "22391", "22394", "22396", "22397", "22399", "22400", "22401", "22402", "22405", "22408", "22412", "22416", "22417", "22418", "22420", "22423", "22424", "22426", "22429", "22430", "22431", "22432", "22434", "22436", "22437", "22440", "22443", "22445", "22450", "22452", "22454", "22459", "22460", "22462", "22463", "22465", "22466", "22468", "22470", "22471", "22472", "22473", "22474", "22475", "22478", "22479", "22482", "22484", "22485", "22487", "22489", "22490", "22491", "22492", "22495", "22496", "22497", "22499", "22501", "22502", "22507", "22513", "22515", "22516", "22517", "22518", "22522", "22524", "22527", "22528", "22533", "22535", "22537", "22540", "22542", "22543", "22548", "22549", "22550", "22551", "22552", "22553", "22557", "22559", "22560", "22561", "22565", "22567", "22569", "22570", "22571", "22573", "22577", "22578", "22579", "22581", "22584", "22587", "22588", "22589", "22594", "22595", "22597", "22598", "22602", "22604", "22605", "22610", "22611", "22612", "22614", "22615", "22617", "22619", "22620", "22621", "22625", "22626", "22627", "22632", "22635", "22637", "22639", "22640", "22643", "22644", "22647", "22648", "22649", "22651", "22652", "22654", "22656", "22657", "22658", "22659", "22665", "22666", "22667", "22671", "22672", "22674", "22675", "22677", "22678", "22680", "22681", "22682", "22686", "22687", "22688", "22689", "22694", "22695", "22699", "22702", "22708", "22710", "22715", "22716", "22717", "22718", "22719", "22720", "22721", "22722", "22724", "22726", "22730", "22731", "22735", "22737", "22738", "22739", "22740", "22745", "22747", "22748", "22749", "22750", "22751", "22752", "22753", "22754", "22756", "22758", "22760", "22764", "22765", "22766", "22768", "22771", "22773", "22774", "22777", "22778", "22779", "22782", "22783", "22785", "22787", "22789", "22790", "22791", "22792", "22793", "22794", "22795", "22796", "22807", "22811", "22816", "22820", "22823", "22826", "22832", "22833", "22834", "22835", "22836", "22839", "22840", "22847", "22849", "22851", "22852", "22855", "22857", "22861", "22863", "22864", "22868", "22870", "22871", "22875", "22882", "22883", "22888", "22889", "22891", "22894", "22898", "22899", "22900", "22901", "22903", "22904", "22905", "22906", "22908", "22909", "22911", "22912", "22913", "22914", "22915", "22916", "22917", "22921", "22922", "22926", "22927", "22929", "22932", "22935", "22936", "22937", "22939", "22941", "22944", "22946", "22948", "22950", "22951", "22952", "22955", "22956", "22958", "22959", "22960", "22963", "22965", "22966", "22970", "22974", "22975", "22976", "22978", "22979", "22982", "22983", "22984", "22985", "22986", "22991", "22992", "22994", "22995", "22997", "22998", "23000", "23002", "23004", "23005", "23007", "23008", "23009", "23010", "23011", "23013", "23017", "23018", "23020", "23021", "23023", "23024", "23025", "23026", "23027", "23032", "23033", "23035", "23037", "23039", "23041", "23042", "23049", "23050", "23052", "23053", "23058", "23060", "23063", "23066", "23068", "23069", "23075", "23076", "23082", "23083", "23086", "23087", "23088", "23089", "23090", "23091", "23092", "23095", "23096", "23097", "23098", "23099", "23100", "23103", "23104", "23105", "23106", "23109", "23111", "23114", "23116", "23117", "23118", "23119", "23120", "23122", "23123", "23126", "23128", "23129", "23132", "23138", "23139", "23140", "23142", "23143", "23144", "23147", "23148", "23149", "23150", "23157", "23162", "23165", "23168", "23169", "23173", "23179", "23180", "23181", "23182", "23186", "23188", "23191", "23192", "23193", "23196", "23197", "23198", "23199", "23200", "23201", "23205", "23206", "23208", "23210", "23213", "23215", "23216", "23218", "23222", "23223", "23226", "23228", "23230", "23232", "23234", "23236", "23238", "23239", "23241", "23247", "23253", "23256", "23257", "23258", "23260", "23262", "23263", "23266", "23267", "23268", "23269", "23270", "23271", "23272", "23275", "23279", "23284", "23285", "23286", "23289", "23290", "23292", "23293", "23295", "23297", "23298", "23300", "23301", "23302", "23307", "23312", "23316", "23319", "23320", "23321", "23322", "23325", "23328", "23329", "23330", "23332", "23333", "23334", "23335", "23336", "23338", "23341", "23342", "23346", "23348", "23349", "23350", "23352", "23353", "23362", "23363", "23364", "23365", "23366", "23367", "23371", "23373", "23375", "23376", "23380", "23385", "23387", "23389", "23390", "23393", "23394", "23397", "23398", "23399", "23400", "23401", "23402", "23403", "23405", "23406", "23409", "23410", "23413", "23414", "23416", "23418", "23419", "23420", "23422", "23423", "23424", "23429", "23432", "23433", "23434", "23436", "23439", "23440", "23441", "23443", "23447", "23448", "23450", "23451", "23452", "23454", "23455", "23457", "23458", "23460", "23461", "23462", "23463", "23464", "23465", "23466", "23467", "23468", "23469", "23471", "23472", "23473", "23474", "23475", "23477", "23482", "23485", "23488", "23492", "23494", "23497", "23498", "23500", "23501", "23506", "23507", "23508", "23509", "23510", "23511", "23512", "23513", "23515", "23517", "23518", "23519", "23520", "23521", "23522", "23523", "23525", "23531", "23533", "23534", "23537", "23538", "23540", "23546", "23547", "23552", "23553", "23554", "23555", "23556", "23557", "23558", "23560", "23561", "23563", "23565", "23566", "23567", "23568", "23569", "23570", "23574", "23578", "23579", "23582", "23584", "23586", "23588", "23589", "23592", "23596", "23599", "23601", "23602", "23603", "23604", "23605", "23608", "23609", "23610", "23614", "23617", "23618", "23621", "23624", "23626", "23627", "23629", "23630", "23631", "23632", "23633", "23636", "23637", "23640", "23643", "23644", "23645", "23647", "23648", "23650", "23651", "23652", "23653", "23657", "23658", "23659", "23660", "23665", "23667", "23668", "23669", "23670", "23671", "23672", "23673", "23675", "23678", "23682", "23683", "23685", "23686", "23687", "23688", "23689", "23690", "23691", "23694", "23696", "23697", "23698", "23699", "23700", "23704", "23707", "23709", "23710", "23711", "23713", "23716", "23717", "23718", "23720", "23721", "23722", "23724", "23725", "23728", "23729", "23731", "23732", "23733", "23734", "23735", "23736", "23737", "23739", "23740", "23741", "23742", "23743", "23744", "23745", "23747", "23748", "23750", "23751", "23754", "23755", "23756", "23757", "23758", "23759", "23760", "23761", "23762", "23764", "23765", "23767", "23773", "23774", "23775", "23778", "23779", "23780", "23781", "23784", "23786", "23787", "23788", "23789", "23791", "23793", "23794", "23797", "23800", "23801", "23802", "23807", "23808", "23809", "23811", "23813", "23814", "23818", "23820", "23823", "23824", "23828", "23832", "23834", "23836", "23837", "23838", "23840", "23841", "23847", "23848", "23850", "23851", "23852", "23853", "23854", "23858", "23861", "23864", "23866", "23874", "23879", "23885", "23886", "23887", "23891", "23893", "23895", "23896", "23897", "23898", "23900", "23901", "23902", "23903", "23904", "23908", "23910", "23911", "23912", "23913", "23914", "23918", "23919", "23920", "23926", "23927", "23928", "23929", "23931", "23935", "23936", "23939", "23942", "23943", "23944", "23946", "23949", "23950", "23953", "23954", "23956", "23961", "23962", "23963", "23964", "23965", "23969", "23972", "23973", "23976", "23983", "23985", "23986", "23987", "23988", "23990", "23997", "23998", "23999", "24000", "24001", "24005", "24007", "24009", "24010", "24011", "24012", "24013", "24016", "24017", "24018", "24021", "24026", "24027", "24028", "24030", "24031", "24032", "24033", "24034", "24035", "24039", "24040", "24042", "24043", "24044", "24045", "24046", "24048", "24055", "24059", "24063", "24064", "24066", "24068", "24072", "24074", "24075", "24076", "24080", "24081", "24082", "24083", "24085", "24086", "24087", "24089", "24092", "24095", "24099", "24100", "24101", "24103", "24105", "24107", "24108", "24109", "24111", "24112", "24115", "24117", "24125", "24127", "24128", "24130", "24132", "24135", "24137", "24138", "24139", "24140", "24143", "24144", "24145", "24149", "24154", "24156", "24158", "24159", "24160", "24163", "24164", "24165", "24168", "24172", "24173", "24178", "24180", "24182", "24183", "24184", "24185", "24186", "24193", "24194", "24197", "24206", "24207", "24209", "24212", "24213", "24214", "24217", "24218", "24225", "24226", "24227", "24228", "24229", "24231", "24232", "24234", "24236", "24237", "24241", "24242", "24246", "24248", "24250", "24255", "24257", "24263", "24265", "24268", "24269", "24270", "24271", "24272", "24274", "24275", "24276", "24279", "24281", "24283", "24284", "24289", "24290", "24293", "24294", "24300", "24302", "24305", "24307", "24309", "24310", "24311", "24315", "24321", "24322", "24328", "24329", "24332", "24338", "24339", "24340", "24341", "24343", "24344", "24345", "24350", "24353", "24355", "24357", "24358", "24360", "24362", "24364", "24365", "24369", "24370", "24373", "24375", "24376", "24377", "24378", "24379", "24380", "24381", "24384", "24386", "24389", "24390", "24392", "24393", "24398", "24400", "24401", "24404", "24405", "24406", "24408", "24412", "24414", "24417", "24419", "24420", "24422", "24423", "24424", "24426", "24431", "24433", "24435", "24436", "24437", "24440", "24443", "24444", "24445", "24446", "24450", "24453", "24455", "24456", "24457", "24459", "24460", "24461", "24462", "24464", "24465", "24466", "24467", "24469", "24470", "24472", "24478", "24479", "24481", "24485", "24487", "24488", "24492", "24493", "24494", "24496", "24498", "24500", "24501", "24503", "24505", "24507", "24508", "24509", "24511", "24512", "24513", "24515", "24516", "24518", "24519", "24522", "24530", "24531", "24533", "24535", "24537", "24538", "24543", "24545", "24546", "24548", "24549", "24552", "24553", "24554", "24556", "24557", "24558", "24559", "24562", "24563", "24570", "24572", "24574", "24577", "24581", "24586", "24587", "24588", "24589", "24591", "24592", "24593", "24596", "24597", "24598", "24600", "24601", "24608", "24609", "24611", "24612", "24615", "24617", "24621", "24622", "24623", "24624", "24628", "24631", "24632", "24633", "24636", "24637", "24638", "24641", "24642", "24645", "24652", "24657", "24659", "24661", "24662", "24663", "24664", "24665", "24666", "24667", "24668", "24674", "24676", "24677", "24678", "24679", "24680", "24681", "24683", "24684", "24686", "24691", "24693", "24694", "24696", "24697", "24699", "24700", "24701", "24702", "24703", "24704", "24705", "24714", "24717", "24718", "24723", "24724", "24728", "24730", "24732", "24733", "24734", "24735", "24739", "24740", "24744", "24746", "24747", "24752", "24754", "24757", "24758", "24759", "24762", "24763", "24764", "24766", "24772", "24774", "24778", "24779", "24780", "24783", "24784", "24785", "24786", "24787", "24790", "24794", "24799", "24800", "24802", "24804", "24805", "24809", "24810", "24812", "24813", "24814", "24817", "24819", "24824", "24825", "24827", "24828", "24830", "24832", "24833", "24834", "24835", "24838", "24839", "24842", "24847", "24849", "24852", "24855", "24859", "24861", "24862", "24864", "24865", "24866", "24867", "24868", "24876", "24878", "24880", "24881", "24882", "24884", "24887", "24888", "24889", "24890", "24893", "24897", "24898", "24899", "24902", "24905", "24906", "24907", "24908", "24910", "24912", "24913", "24914", "24918", "24920", "24921", "24922", "24923", "24924", "24925", "24927", "24929", "24930", "24931", "24934", "24935", "24936", "24939", "24940", "24942", "24947", "24948", "24949", "24952", "24955", "24956", "24959", "24960", "24962", "24964", "24966", "24968", "24969", "24970", "24971", "24973", "24980", "24983", "24984", "24987", "24988", "24989", "24996", "24998", "24999", "25000", "25003", "25004", "25010", "25011", "25012", "25014", "25015", "25017", "25018", "25020", "25022", "25023", "25024", "25026", "25029", "25031", "25032", "25036", "25039", "25040", "25041", "25042", "25043", "25046", "25050", "25051", "25052", "25053", "25055", "25056", "25057", "25061", "25062", "25065", "25073", "25076", "25077", "25079", "25080", "25081", "25082", "25085", "25087", "25088", "25089", "25090", "25092", "25093", "25095", "25096", "25098", "25100", "25103", "25105", "25107", "25109", "25110", "25111", "25114", "25115", "25116", "25120", "25121", "25126", "25127", "25128", "25130", "25134", "25135", "25137", "25138", "25140", "25141", "25143", "25144", "25145", "25147", "25148", "25149", "25150", "25154", "25158", "25161", "25163", "25166", "25167", "25169", "25170", "25171", "25174", "25175", "25178", "25180", "25182", "25184", "25187", "25188", "25189", "25194", "25195", "25196", "25198", "25199", "25201", "25205", "25213", "25216", "25217", "25222", "25226", "25227", "25228", "25229", "25230", "25231", "25233", "25234", "25235", "25237", "25238", "25241", "25242", "25245", "25247", "25251", "25252", "25254", "25255", "25256", "25257", "25258", "25261", "25263", "25265", "25267", "25268", "25274", "25275", "25276", "25277", "25280", "25281", "25282", "25283", "25286", "25287", "25290", "25291", "25295", "25297", "25298", "25300", "25303", "25304", "25305", "25307", "25309", "25310", "25312", "25317", "25318", "25319", "25320", "25322", "25325", "25327", "25332", "25335", "25342", "25347", "25350", "25351", "25353", "25354", "25358", "25359", "25363", "25364", "25367", "25371", "25372", "25374", "25375", "25377", "25378", "25379", "25382", "25383", "25385", "25386", "25388", "25389", "25390", "25393", "25394", "25395", "25396", "25397", "25398", "25400", "25403", "25406", "25408", "25409", "25413", "25414", "25417", "25418", "25420", "25423", "25424", "25426", "25429", "25433", "25434", "25437", "25438", "25441", "25442", "25444", "25445", "25446", "25453", "25455", "25457", "25458", "25465", "25466", "25467", "25468", "25470", "25471", "25474", "25483", "25486", "25487", "25489", "25490", "25496", "25497", "25499", "25501", "25503", "25505", "25510", "25512", "25513", "25516", "25517", "25518", "25519", "25521", "25522", "25523", "25524", "25525", "25529", "25530", "25535", "25543", "25544", "25546", "25547", "25548", "25552", "25555", "25557", "25558", "25559", "25560", "25561", "25563", "25566", "25567", "25569", "25570", "25573", "25574", "25575", "25580", "25581", "25582", "25583", "25585", "25589", "25592", "25594", "25596", "25597", "25599", "25602", "25604", "25605", "25607", "25608", "25614", "25615", "25616", "25617", "25618", "25620", "25622", "25624", "25625", "25626", "25627", "25628", "25632", "25635", "25638", "25640", "25645", "25647", "25650", "25653", "25656", "25657", "25659", "25660", "25663", "25666", "25667", "25669", "25670", "25677", "25678", "25680", "25681", "25684", "25688", "25690", "25692", "25699", "25703", "25704", "25705", "25709", "25711", "25715", "25717", "25718", "25719", "25721", "25724", "25725", "25726", "25727", "25730", "25731", "25733", "25736", "25737", "25739", "25740", "25743", "25749", "25750", "25751", "25753", "25754", "25755", "25756", "25757", "25760", "25762", "25763", "25766", "25767", "25769", "25770", "25775", "25776", "25777", "25778", "25779", "25780", "25781", "25782", "25784", "25785", "25786", "25796", "25800", "25804", "25806", "25809", "25811", "25812", "25813", "25815", "25816", "25817", "25819", "25826", "25828", "25829", "25830", "25832", "25834", "25836", "25837", "25839", "25843", "25844", "25845", "25846", "25848", "25850", "25851", "25852", "25854", "25855", "25864", "25865", "25866", "25867", "25868", "25869", "25871", "25873", "25876", "25877", "25878", "25880", "25881", "25882", "25884", "25886", "25891", "25892", "25893", "25894", "25895", "25897", "25899", "25900", "25902", "25903", "25906", "25908", "25909", "25910", "25916", "25919", "25920", "25921", "25922", "25927", "25929", "25932", "25935", "25938", "25939", "25940", "25944", "25946", "25948", "25951", "25953", "25955", "25956", "25957", "25958", "25959", "25961", "25963", "25964", "25965", "25966", "25967", "25969", "25970", "25971", "25974", "25977", "25978", "25981", "25984", "25985", "25986", "25991", "25992", "25996", "25997", "25998", "26002", "26006", "26007", "26008", "26009", "26010", "26012", "26015", "26017", "26018", "26020", "26021", "26026", "26027", "26028", "26029", "26030", "26031", "26032", "26033", "26034", "26035", "26036", "26037", "26038", "26042", "26047", "26048", "26051", "26057", "26058", "26059", "26060", "26061", "26062", "26064", "26065", "26069", "26072", "26073", "26075", "26076", "26077", "26083", "26085", "26089", "26091", "26096", "26099", "26101", "26102", "26106", "26107", "26108", "26109", "26110", "26112", "26118", "26123", "26124", "26127", "26130", "26134", "26135", "26140", "26141", "26143", "26147", "26148", "26150", "26151", "26153", "26154", "26155", "26156", "26157", "26159", "26160", "26162", "26163", "26166", "26168", "26171", "26173", "26174", "26175", "26177", "26179", "26181", "26184", "26185", "26186", "26187", "26191", "26192", "26195", "26196", "26198", "26199", "26201", "26203", "26204", "26205", "26207", "26211", "26213", "26214", "26215", "26221", "26224", "26225", "26226", "26227", "26228", "26230", "26231", "26233", "26234", "26236", "26241", "26244", "26246", "26251", "26252", "26255", "26256", "26257", "26259", "26261", "26262", "26266", "26267", "26268", "26271", "26274", "26276", "26279", "26280", "26281", "26282", "26283", "26284", "26285", "26286", "26287", "26288", "26289", "26296", "26297", "26298", "26300", "26301", "26302", "26303", "26304", "26306", "26311", "26312", "26313", "26315", "26317", "26318", "26321", "26331", "26332", "26334", "26335", "26336", "26341", "26342", "26346", "26347", "26348", "26350", "26352", "26354", "26355", "26357", "26358", "26360", "26361", "26364", "26367", "26368", "26373", "26374", "26376", "26377", "26378", "26380", "26381", "26382", "26387", "26390", "26392", "26393", "26395", "26399", "26400", "26401", "26404", "26405", "26406", "26407", "26408", "26409", "26412", "26413", "26414", "26418", "26419", "26420", "26421", "26422", "26424", "26428", "26430", "26432", "26435", "26438", "26439", "26442", "26443", "26444", "26445", "26447", "26451", "26454", "26460", "26461", "26462", "26464", "26465", "26470", "26474", "26475", "26476", "26478", "26479", "26480", "26481", "26483", "26485", "26486", "26488", "26491", "26493", "26494", "26496", "26497", "26500", "26502", "26503", "26504", "26505", "26506", "26509", "26511", "26512", "26513", "26515", "26516", "26517", "26518", "26520", "26521", "26525", "26527", "26529", "26530", "26534", "26537", "26538", "26542", "26543", "26544", "26545", "26546", "26548", "26550", "26553", "26554", "26555", "26556", "26557", "26558", "26559", "26563", "26564", "26566", "26567", "26568", "26569", "26570", "26571", "26573", "26576", "26578", "26580", "26581", "26583", "26585", "26587", "26588", "26590", "26591", "26593", "26594", "26595", "26596", "26598", "26601", "26603", "26605", "26607", "26609", "26610", "26612", "26613", "26614", "26618", "26619", "26622", "26623", "26624", "26627", "26633", "26636", "26640", "26641", "26646", "26648", "26650", "26651", "26652", "26653", "26655", "26657", "26660", "26664", "26665", "26666", "26670", "26672", "26673", "26674", "26676", "26678", "26679", "26680", "26681", "26682", "26683", "26684", "26686", "26687", "26691", "26693", "26696", "26700", "26701", "26704", "26712", "26714", "26716", "26717", "26718", "26720", "26721", "26722", "26723", "26724", "26725", "26726", "26727", "26731", "26732", "26733", "26736", "26737", "26739", "26740", "26742", "26745", "26746", "26748", "26750", "26753", "26755", "26756", "26757", "26758", "26759", "26760", "26762", "26763", "26764", "26767", "26768", "26769", "26770", "26772", "26774", "26776", "26777", "26778", "26780", "26782", "26784", "26785", "26788", "26789", "26793", "26794", "26795", "26800", "26801", "26803", "26805", "26806", "26807", "26808", "26810", "26811", "26814", "26815", "26818", "26819", "26822", "26823", "26824", "26825", "26828", "26829", "26831", "26837", "26838", "26839", "26842", "26843", "26844", "26846", "26849", "26850", "26852", "26853", "26854", "26857", "26861", "26863", "26864", "26865", "26866", "26867", "26868", "26870", "26873", "26875", "26877", "26878", "26880", "26884", "26888", "26891", "26892", "26895", "26896", "26897", "26899", "26901", "26906", "26907", "26908", "26909", "26910", "26912", "26917", "26918", "26919", "26920", "26923", "26927", "26929", "26930", "26934", "26937", "26939", "26941", "26944", "26945", "26947", "26950", "26952", "26956", "26958", "26959", "26960", "26961", "26963", "26966", "26969", "26970", "26971", "26975", "26976", "26978", "26981", "26985", "26988", "26989", "26990", "26991", "26992", "26994", "26995", "26996", "26997", "26998", "26999", "27001", "27002", "27004", "27005", "27006", "27007", "27012", "27016", "27019", "27022", "27023", "27028", "27030", "27031", "27032", "27033", "27035", "27036", "27037", "27041", "27043", "27044", "27047", "27048", "27049", "27051", "27052", "27053", "27054", "27058", "27059", "27060", "27063", "27066", "27069", "27073", "27075", "27076", "27078", "27080", "27081", "27082", "27085", "27089", "27091", "27093", "27094", "27095", "27098", "27100", "27101", "27106", "27107", "27108", "27111", "27114", "27116", "27120", "27121", "27122", "27123", "27124", "27125", "27126", "27128", "27133", "27134", "27136", "27137", "27138", "27139", "27140", "27141", "27142", "27146", "27148", "27149", "27150", "27151", "27153", "27154", "27155", "27157", "27163", "27164", "27169", "27170", "27171", "27172", "27174", "27176", "27177", "27182", "27184", "27185", "27186", "27187", "27188", "27190", "27192", "27195", "27198", "27200", "27204", "27209", "27210", "27211", "27213", "27215", "27217", "27218", "27219", "27220", "27221", "27227", "27228", "27230", "27233", "27235", "27237", "27240", "27242", "27244", "27248", "27252", "27253", "27256", "27258", "27259", "27260", "27262", "27263", "27265", "27266", "27272", "27275", "27277", "27279", "27280", "27282", "27286", "27287", "27288", "27291", "27298", "27300", "27302", "27303", "27304", "27306", "27307", "27308", "27310", "27311", "27320", "27321", "27325", "27326", "27328", "27334", "27336", "27346", "27348", "27350", "27352", "27353", "27358", "27360", "27361", "27363", "27366", "27371", "27373", "27375", "27377", "27379", "27384", "27388", "27389", "27390", "27391", "27392", "27395", "27398", "27402", "27403", "27404", "27405", "27411", "27413", "27415", "27420", "27422", "27430", "27431", "27433", "27435", "27437", "27441", "27442", "27444", "27450", "27454", "27456", "27463", "27467", "27474", "27475", "27477", "27478", "27479", "27480", "27483", "27484", "27485", "27488", "27489", "27490", "27491", "27492", "27493", "27494", "27495", "27497", "27499", "27502", "27504", "27507", "27514", "27515", "27516", "27517", "27521", "27523", "27525", "27527", "27528", "27529", "27531", "27533", "27535", "27536", "27537", "27539", "27540", "27542", "27543", "27547", "27549", "27556", "27557", "27558", "27562", "27569", "27570", "27573", "27574", "27576", "27580", "27582", "27584", "27588", "27589", "27590", "27591", "27592", "27593", "27598", "27601", "27603", "27606", "27608", "27610", "27612", "27613", "27618", "27620", "27624", "27625", "27626", "27629", "27630", "27632", "27633", "27634", "27636", "27637", "27643", "27646", "27647", "27652", "27655", "27657", "27659", "27661", "27665", "27667", "27668", "27669", "27671", "27673", "27675", "27676", "27680", "27681", "27683", "27684", "27686", "27687", "27690", "27691", "27692", "27693", "27695", "27699", "27701", "27705", "27707", "27708", "27709", "27710", "27711", "27713", "27716", "27717", "27724", "27725", "27728", "27729", "27730", "27731", "27732", "27733", "27739", "27743", "27745", "27746", "27747", "27751", "27753", "27755", "27759", "27760", "27761", "27763", "27764", "27765", "27766", "27767", "27769", "27770", "27771", "27772", "27773", "27774", "27777", "27778", "27779", "27783", "27784", "27788", "27791", "27792", "27793", "27794", "27795", "27796", "27798", "27799", "27800", "27804", "27805", "27810", "27811", "27812", "27814", "27815", "27819", "27821", "27823", "27824", "27825", "27827", "27831", "27833", "27834", "27836", "27840", "27841", "27842", "27844", "27845", "27848", "27849", "27850", "27853", "27855", "27856", "27858", "27859", "27860", "27861", "27862", "27870", "27871", "27874", "27875", "27877", "27880", "27881", "27884", "27885", "27886", "27889", "27890", "27894", "27896", "27900", "27901", "27902", "27904", "27907", "27910", "27912", "27918", "27919", "27920", "27921", "27926", "27928", "27931", "27937", "27939", "27940", "27941", "27946", "27947", "27948", "27949", "27950", "27951", "27958", "27959", "27960", "27961", "27962", "27963", "27966", "27967", "27968", "27969", "27970", "27971", "27972", "27974", "27978", "27981", "27983", "27984", "27985", "27986", "27987", "27989", "27990", "27991", "27992", "27997", "28002", "28012", "28014", "28016", "28018", "28020", "28024", "28025", "28026", "28027", "28028", "28031", "28032", "28033", "28034", "28037", "28039", "28041", "28042", "28043", "28045", "28051", "28054", "28056", "28059", "28060", "28062", "28064", "28070", "28071", "28074", "28075", "28077", "28080", "28081", "28082", "28084", "28085", "28087", "28089", "28092", "28093", "28096", "28097", "28098", "28100", "28101", "28102", "28109", "28114", "28115", "28116", "28117", "28118", "28122", "28123", "28124", "28127", "28135", "28138", "28139", "28140", "28141", "28146", "28148", "28151", "28152", "28153", "28155", "28157", "28158", "28161", "28162", "28163", "28164", "28165", "28166", "28167", "28170", "28172", "28177", "28179", "28182", "28185", "28188", "28189", "28190", "28191", "28194", "28196", "28200", "28202", "28203", "28206", "28207", "28209", "28210", "28211", "28215", "28216", "28217", "28220", "28221", "28223", "28224", "28225", "28228", "28230", "28233", "28236", "28237", "28242", "28247", "28249", "28251", "28256", "28257", "28265", "28267", "28269", "28271", "28275", "28277", "28286", "28292", "28293", "28295", "28298", "28301", "28306", "28310", "28311", "28312", "28313", "28314", "28315", "28321", "28322", "28325", "28328", "28329", "28330", "28331", "28332", "28333", "28334", "28335", "28338", "28340", "28341", "28342", "28344", "28346", "28347", "28349", "28350", "28352", "28353", "28354", "28355", "28356", "28358", "28361", "28363", "28366", "28367", "28370", "28371", "28372", "28375", "28377", "28378", "28380", "28381", "28384", "28386", "28388", "28389", "28390", "28391", "28394", "28397", "28398", "28401", "28404", "28405", "28406", "28409", "28410", "28414", "28419", "28420", "28422", "28423", "28424", "28426", "28427", "28428", "28429", "28430", "28435", "28441", "28442", "28444", "28449", "28450", "28451", "28452", "28453", "28454", "28455", "28456", "28457", "28460", "28463", "28465", "28466", "28467", "28468", "28471", "28472", "28475", "28476", "28477", "28478", "28480", "28481", "28482", "28483", "28487", "28488", "28489", "28490", "28494", "28495", "28497", "28500", "28501", "28503", "28508", "28509", "28511", "28512", "28514", "28515", "28516", "28518", "28522", "28525", "28530", "28532", "28534", "28536", "28538", "28541", "28542", "28543", "28544", "28546", "28548", "28549", "28550", "28551", "28555", "28557", "28559", "28561", "28563", "28565", "28567", "28569", "28570", "28573", "28574", "28575", "28578", "28579", "28582", "28585", "28586", "28587", "28588", "28590", "28591", "28594", "28595", "28596", "28597", "28599", "28603", "28610", "28611", "28612", "28613", "28614", "28615", "28616", "28618", "28620", "28622", "28623", "28624", "28626", "28632", "28633", "28634", "28635", "28638", "28639", "28641", "28643", "28644", "28645", "28648", "28651", "28657", "28659", "28661", "28662", "28663", "28666", "28667", "28669", "28671", "28674", "28677", "28680", "28681", "28683", "28685", "28688", "28689", "28692", "28694", "28701", "28702", "28703", "28704", "28705", "28706", "28709", "28710", "28711", "28716", "28717", "28721", "28724", "28726", "28727", "28728", "28729", "28731", "28732", "28733", "28735", "28737", "28738", "28740", "28741", "28742", "28743", "28744", "28749", "28750", "28752", "28754", "28755", "28757", "28758", "28760", "28761", "28762", "28764", "28765", "28768", "28770", "28771", "28772", "28773", "28774", "28778", "28779", "28780", "28781", "28784", "28787", "28788", "28790", "28792", "28797", "28801", "28803", "28804", "28805", "28807", "28809", "28812", "28815", "28819", "28821", "28823", "28824", "28826", "28827", "28828", "28829", "28833", "28834", "28839", "28840", "28842", "28844", "28845", "28846", "28848", "28849", "28852", "28855", "28856", "28858", "28860", "28863", "28865", "28869", "28871", "28874", "28875", "28878", "28880", "28881", "28884", "28887", "28890", "28892", "28896", "28899", "28900", "28901", "28905", "28907", "28908", "28913", "28915", "28921", "28924", "28925", "28927", "28928", "28930", "28931", "28937", "28944", "28945", "28947", "28952", "28953", "28954", "28955", "28958", "28959", "28961", "28963", "28964", "28965", "28967", "28969", "28970", "28972", "28973", "28974", "28978", "28981", "28982", "28983", "28984", "28985", "28991", "28992", "28993", "28994", "28995", "28997", "29001", "29003", "29004", "29005", "29006", "29008", "29011", "29012", "29017", "29021", "29022", "29023", "29025", "29027", "29028", "29032", "29033", "29035", "29039", "29040", "29041", "29042", "29043", "29044", "29046", "29047", "29049", "29051", "29054", "29055", "29063", "29064", "29065", "29072", "29073", "29074", "29076", "29079", "29081", "29083", "29085", "29087", "29089", "29091", "29092", "29093", "29096", "29100", "29101", "29102", "29104", "29110", "29111", "29112", "29115", "29116", "29117", "29120", "29122", "29123", "29125", "29126", "29127", "29128", "29129", "29133", "29135", "29137", "29141", "29142", "29143", "29144", "29145", "29147", "29151", "29153", "29154", "29156", "29157", "29159", "29160", "29161", "29165", "29169", "29170", "29171", "29172", "29174", "29178", "29180", "29185", "29186", "29187", "29188", "29191", "29193", "29194", "29195", "29196", "29197", "29200", "29202", "29204", "29205", "29206", "29209", "29215", "29216", "29217", "29218", "29221", "29223", "29225", "29226", "29228", "29233", "29235", "29238", "29247", "29249", "29251", "29255", "29258", "29260", "29261", "29262", "29263", "29265", "29269", "29272", "29273", "29276", "29277", "29281", "29282", "29284", "29286", "29287", "29291", "29292", "29293", "29296", "29300", "29301", "29304", "29306", "29309", "29311", "29313", "29314", "29318", "29320", "29321", "29324", "29327", "29328", "29329", "29332", "29333", "29334", "29335", "29343", "29344", "29346", "29347", "29350", "29351", "29352", "29355", "29356", "29358", "29360", "29363", "29364", "29366", "29368", "29369", "29371", "29372", "29373", "29374", "29375", "29377", "29379", "29382", "29386", "29387", "29388", "29390", "29394", "29399", "29400", "29401", "29402", "29405", "29406", "29410", "29413", "29415", "29416", "29418", "29419", "29420", "29421", "29423", "29424", "29425", "29427", "29428", "29432", "29435", "29436", "29439", "29440", "29442", "29445", "29448", "29449", "29450", "29451", "29453", "29454", "29456", "29459", "29467", "29468", "29470", "29472", "29473", "29476", "29477", "29479", "29480", "29481", "29482", "29483", "29485", "29487", "29488", "29490", "29491", "29492", "29493", "29496", "29497", "29499", "29503", "29504", "29507", "29508", "29509", "29510", "29511", "29512", "29513", "29514", "29517", "29518", "29519", "29520", "29521", "29522", "29524", "29525", "29527", "29528", "29532", "29533", "29534", "29541", "29542", "29545", "29546", "29547", "29548", "29550", "29553", "29556", "29557", "29561", "29562", "29564", "29570", "29572", "29573", "29576", "29577", "29578", "29579", "29580", "29582", "29583", "29584", "29585", "29591", "29595", "29598", "29600", "29601", "29602", "29607", "29609", "29610", "29616", "29617", "29618", "29621", "29623", "29624", "29631", "29633", "29634", "29635", "29637", "29639", "29648", "29649", "29650", "29656", "29657", "29661", "29663", "29665", "29669", "29674", "29678", "29680", "29682", "29684", "29688", "29691", "29693", "29694", "29698", "29701", "29702", "29706", "29707", "29709", "29710", "29712", "29713", "29714", "29715", "29718", "29721", "29722", "29723", "29726", "29727", "29728", "29730", "29731", "29733", "29736", "29737", "29738", "29741", "29742", "29745", "29746", "29748", "29750", "29751", "29752", "29754", "29756", "29757", "29758", "29760", "29761", "29763", "29765", "29766", "29768", "29769", "29770", "29771", "29775", "29778", "29780", "29781", "29784", "29785", "29786", "29788", "29792", "29796", "29797", "29802", "29806", "29807", "29808", "29814", "29818", "29820", "29821", "29825", "29826", "29827", "29829", "29833", "29835", "29836", "29839", "29840", "29850", "29853", "29855", "29856", "29857", "29860", "29861", "29862", "29863", "29864", "29865", "29866", "29868", "29872", "29873", "29875", "29876", "29879", "29880", "29883", "29885", "29886", "29889", "29890", "29892", "29901", "29906", "29909", "29910", "29912", "29913", "29915", "29917", "29918", "29922", "29923", "29927", "29929", "29930", "29935", "29937", "29938", "29939", "29943", "29945", "29946", "29947", "29948", "29949", "29950", "29951", "29952", "29954", "29955", "29956", "29961", "29963", "29964", "29970", "29972", "29974", "29975", "29980", "29981", "29982", "29983", "29985", "29986", "29988", "29989", "29995", "29996", "29999", "30002", "30004", "30007", "30008", "30009", "30010", "30015", "30022", "30023", "30025", "30028", "30032", "30036", "30037", "30038", "30041", "30043", "30046", "30047", "30049", "30056", "30057", "30059", "30060", "30063", "30066", "30069", "30070", "30071", "30073", "30076", "30080", "30082", "30083", "30087", "30089", "30092", "30093", "30094", "30097", "30098", "30103", "30104", "30105", "30106", "30108", "30109", "30110", "30113", "30118", "30119", "30122", "30123", "30125", "30126", "30127", "30128", "30129", "30130", "30131", "30132", "30133", "30134", "30137", "30139", "30140", "30141", "30142", "30144", "30148", "30154", "30156", "30157", "30158", "30169", "30170", "30173", "30174", "30175", "30176", "30177", "30178", "30183", "30184", "30187", "30188", "30189", "30190", "30191", "30192", "30193", "30194", "30195", "30196", "30197", "30200", "30201", "30204", "30205", "30206", "30207", "30208", "30210", "30212", "30213", "30215", "30218", "30219", "30221", "30222", "30223", "30224", "30225", "30226", "30228", "30229", "30231", "30233", "30234", "30238", "30239", "30240", "30241", "30243", "30246", "30247", "30248", "30249", "30250", "30253", "30255", "30259", "30264", "30265", "30266", "30267", "30268", "30269", "30270", "30272", "30273", "30276", "30277", "30282", "30283", "30287", "30288", "30291", "30292", "30293", "30299", "30301", "30302", "30305", "30307", "30308", "30311", "30312", "30313", "30319", "30320", "30322", "30323", "30324", "30325", "30329", "30330", "30333", "30334", "30338", "30341", "30344", "30345", "30350", "30351", "30354", "30355", "30357", "30358", "30359", "30360", "30361", "30362", "30363", "30368", "30369", "30371", "30373", "30384", "30386", "30387", "30390", "30391", "30393", "30394", "30395", "30398", "30400", "30402", "30407", "30409", "30415", "30416", "30419", "30420", "30421", "30426", "30427", "30428", "30429", "30431", "30432", "30433", "30435", "30437", "30440", "30442", "30443", "30445", "30446", "30448", "30450", "30451", "30453", "30454", "30455", "30458", "30459", "30460", "30461", "30462", "30463", "30465", "30467", "30469", "30470", "30471", "30474", "30475", "30476", "30477", "30480", "30483", "30485", "30493", "30494", "30497", "30498", "30500", "30503", "30509", "30512", "30513", "30516", "30517", "30520", "30522", "30525", "30527", "30528", "30529", "30531", "30535", "30536", "30539", "30540", "30541", "30542", "30543", "30544", "30549", "30560", "30563", "30566", "30567", "30569", "30571", "30575", "30576", "30578", "30579", "30580", "30583", "30588", "30592", "30593", "30594", "30595", "30597", "30599", "30600", "30601", "30602", "30604", "30609", "30611", "30614", "30616", "30618", "30619", "30620", "30624", "30625", "30626", "30627", "30631", "30632", "30633", "30635", "30636", "30639", "30641", "30642", "30643", "30646", "30648", "30649", "30652", "30653", "30657", "30659", "30660", "30661", "30663", "30665", "30667", "30670", "30672", "30673", "30675", "30676", "30681", "30682", "30683", "30685", "30686", "30688", "30694", "30695", "30696", "30698", "30700", "30708", "30709", "30710", "30711", "30712", "30713", "30716", "30719", "30721", "30722", "30723", "30724", "30725", "30726", "30727", "30728", "30731", "30732", "30743", "30744", "30748", "30749", "30752", "30753", "30754", "30755", "30759", "30761", "30762", "30765", "30766", "30767", "30768", "30770", "30772", "30773", "30774", "30777", "30778", "30780", "30782", "30784", "30787", "30788", "30790", "30791", "30792", "30793", "30797", "30798", "30800", "30802", "30803", "30805", "30807", "30811", "30812", "30813", "30818", "30819", "30824", "30825", "30826", "30829", "30831", "30833", "30836", "30837", "30839", "30841", "30843", "30844", "30847", "30848", "30849", "30850", "30852", "30853", "30857", "30858", "30859", "30861", "30869", "30871", "30872", "30876", "30878", "30881", "30884", "30886", "30887", "30892", "30895", "30896", "30901", "30904", "30906", "30907", "30908", "30909", "30911", "30915", "30916", "30918", "30919", "30920", "30922", "30923", "30924", "30927", "30929", "30931", "30933", "30934", "30935", "30937", "30941", "30946", "30948", "30950", "30953", "30954", "30956", "30959", "30961", "30962", "30965", "30966", "30971", "30973", "30977", "30979", "30982", "30984", "30986", "30987", "30991", "30997", "31000", "31003", "31004", "31008", "31010", "31011", "31012", "31013", "31015", "31016", "31017", "31018", "31019", "31020", "31021", "31023", "31025", "31028", "31030", "31031", "31033", "31035", "31038", "31039", "31041", "31044", "31045", "31046", "31049", "31050", "31051", "31052", "31054", "31055", "31057", "31058", "31060", "31069", "31070", "31071", "31072", "31073", "31074", "31076", "31077", "31079", "31081", "31084", "31087", "31088", "31091", "31093", "31095", "31098", "31100", "31101", "31102", "31104", "31105", "31108", "31109", "31110", "31111", "31112", "31114", "31115", "31118", "31119", "31120", "31121", "31122", "31124", "31127", "31128", "31129", "31130", "31131", "31134", "31135", "31139", "31140", "31143", "31144", "31146", "31147", "31149", "31150", "31151", "31152", "31153", "31154", "31155", "31158", "31165", "31166", "31170", "31171", "31173", "31176", "31177", "31180", "31181", "31189", "31191", "31192", "31193", "31194", "31195", "31197", "31198", "31199", "31200", "31203", "31210", "31211", "31215", "31217", "31220", "31221", "31222", "31223", "31225", "31228", "31229", "31231", "31237", "31240", "31242", "31244", "31245", "31246", "31247", "31248", "31251", "31252", "31253", "31254", "31255", "31256", "31260", "31262", "31263", "31265", "31266", "31268", "31270", "31271", "31273", "31274", "31275", "31277", "31279", "31280", "31281", "31282", "31283", "31288", "31291", "31292", "31294", "31297", "31299", "31301", "31302", "31307", "31309", "31311", "31312", "31313", "31315", "31316", "31319", "31321", "31323", "31324", "31326", "31327", "31328", "31330", "31331", "31334", "31335", "31337", "31339", "31340", "31345", "31348", "31349", "31351", "31353", "31354", "31355", "31356", "31357", "31359", "31361", "31363", "31364", "31365", "31369", "31370", "31371", "31372", "31374", "31375", "31376", "31377", "31378", "31379", "31383", "31385", "31386", "31391", "31392", "31393", "31395", "31396", "31399", "31400", "31401", "31403", "31405", "31407", "31408", "31410", "31411", "31412", "31413", "31415", "31417", "31419", "31422", "31423", "31425", "31428", "31429", "31430", "31432", "31435", "31436", "31438", "31439", "31440", "31442", "31450", "31452", "31455", "31457", "31461", "31463", "31464", "31465", "31467", "31468", "31470", "31472", "31475", "31476", "31479", "31481", "31483", "31486", "31491", "31492", "31496", "31498", "31500", "31501", "31503", "31504", "31506", "31507", "31509", "31510", "31513", "31517", "31519", "31521", "31524", "31526", "31529", "31533", "31538", "31539", "31540", "31544", "31546", "31548", "31552", "31553", "31554", "31560", "31563", "31566", "31567", "31568", "31569", "31573", "31575", "31576", "31577", "31578", "31579", "31581", "31582", "31583", "31584", "31585", "31586", "31587", "31588", "31589", "31590", "31592", "31594", "31596", "31597", "31599", "31602", "31604", "31607", "31609", "31611", "31612", "31615", "31616", "31617", "31618", "31619", "31620", "31622", "31623", "31624", "31625", "31626", "31631", "31632", "31633", "31643", "31645", "31650", "31651", "31652", "31654", "31656", "31657", "31660", "31665", "31666", "31667", "31669", "31670", "31671", "31672", "31673", "31674", "31676", "31679", "31680", "31682", "31685", "31688", "31689", "31692", "31695", "31697", "31699", "31700", "31701", "31704", "31705", "31706", "31708", "31711", "31713", "31714", "31716", "31720", "31721", "31723", "31724", "31725", "31727", "31728", "31729", "31731", "31733", "31734", "31736", "31739", "31744", "31746", "31747", "31748", "31749", "31750", "31751", "31752", "31756", "31759", "31761", "31762", "31763", "31764", "31765", "31770", "31771", "31773", "31777", "31779", "31780", "31781", "31782", "31783", "31786", "31790", "31791", "31792", "31794", "31795", "31800", "31801", "31805", "31810", "31812", "31814", "31817", "31820", "31822", "31823", "31825", "31827", "31829", "31832", "31833", "31834", "31835", "31836", "31839", "31841", "31844", "31845", "31848", "31849", "31850", "31852", "31853", "31854", "31855", "31856", "31857", "31860", "31863", "31864", "31867", "31868", "31871", "31872", "31873", "31874", "31875", "31876", "31877", "31878", "31880", "31882", "31883", "31885", "31886", "31887", "31888", "31894", "31895", "31898", "31899", "31900", "31901", "31902", "31903", "31905", "31906", "31907", "31909", "31910", "31911", "31914", "31915", "31917", "31918", "31919", "31921", "31923", "31924", "31925", "31926", "31927", "31928", "31933", "31934", "31936", "31937", "31941", "31944", "31945", "31950", "31952", "31953", "31956", "31962", "31963", "31965", "31966", "31970", "31972", "31974", "31975", "31976", "31977", "31979", "31981", "31984", "31987", "31988", "31992", "31993", "31994", "31997", "31998", "32000", "32006", "32007", "32008", "32012", "32014", "32015", "32016", "32017", "32020", "32022", "32023", "32024", "32025", "32027", "32032", "32033", "32034", "32036", "32037", "32039", "32040", "32042", "32044", "32054", "32055", "32056", "32057", "32059", "32060", "32061", "32063", "32065", "32066", "32069", "32071", "32073", "32075", "32076", "32077", "32084", "32086", "32088", "32089", "32091", "32093", "32094", "32095", "32097", "32098", "32100", "32102", "32104", "32105", "32106", "32108", "32109", "32110", "32111", "32113", "32114", "32115", "32116", "32118", "32121", "32122", "32124", "32125", "32126", "32131", "32133", "32134", "32135", "32138", "32143", "32144", "32146", "32147", "32150", "32151", "32158", "32160", "32161", "32164", "32165", "32167", "32171", "32174", "32175", "32177", "32178", "32181", "32182", "32185", "32188", "32189", "32192", "32193", "32196", "32199", "32200", "32201", "32202", "32203", "32205", "32206", "32208", "32209", "32212", "32216", "32218", "32222", "32223", "32225", "32229", "32232", "32233", "32234", "32235", "32236", "32237", "32238", "32241", "32242", "32244", "32245", "32248", "32250", "32254", "32259", "32260", "32263", "32265", "32266", "32267", "32268", "32269", "32274", "32276", "32277", "32278", "32279", "32281", "32283", "32285", "32286", "32288", "32291", "32292", "32293", "32297", "32299", "32301", "32302", "32303", "32304", "32306", "32308", "32309", "32310", "32311", "32312", "32314", "32315", "32316", "32317", "32318", "32322", "32323", "32325", "32326", "32328", "32330", "32333", "32335", "32338", "32340", "32342", "32343", "32344", "32345", "32348", "32349", "32350", "32352", "32354", "32355", "32356", "32357", "32359", "32361", "32362", "32363", "32365", "32366", "32368", "32370", "32371", "32377", "32378", "32380", "32382", "32383", "32384", "32386", "32387", "32388", "32389", "32394", "32395", "32398", "32400", "32402", "32403", "32407", "32408", "32409", "32411", "32413", "32414", "32415", "32418", "32421", "32422", "32423", "32425", "32426", "32427", "32429", "32430", "32433", "32436", "32439", "32444", "32445", "32447", "32448", "32449", "32451", "32452", "32453", "32454", "32455", "32457", "32458", "32460", "32462", "32463", "32465", "32468", "32469", "32470", "32472", "32473", "32474", "32475", "32477", "32479", "32480", "32486", "32490", "32491", "32494", "32497", "32501", "32502", "32503", "32505", "32507", "32508", "32509", "32510", "32511", "32512", "32515", "32516", "32517", "32518", "32519", "32521", "32522", "32527", "32530", "32533", "32534", "32535", "32537", "32540", "32543", "32544", "32545", "32546", "32547", "32548", "32549", "32554", "32556", "32557", "32558", "32560", "32562", "32563", "32564", "32565", "32568", "32574", "32577", "32579", "32582", "32583", "32585", "32586", "32591", "32592", "32593", "32595", "32596", "32599", "32602", "32604", "32606", "32607", "32608", "32610", "32611", "32612", "32613", "32615", "32621", "32622", "32623", "32624", "32625", "32626", "32627", "32629", "32630", "32631", "32635", "32637", "32638", "32640", "32642", "32644", "32645", "32646", "32651", "32654", "32659", "32662", "32663", "32664", "32667", "32668", "32669", "32671", "32673", "32677", "32680", "32682", "32684", "32692", "32693", "32697", "32698", "32700", "32701", "32702", "32703", "32705", "32707", "32708", "32709", "32712", "32713", "32716", "32719", "32720", "32723", "32724", "32726", "32729", "32732", "32735", "32737", "32739", "32741", "32742", "32743", "32744", "32746", "32747", "32748", "32751", "32755", "32757", "32760", "32765", "32766", "32767", "32768", "32769", "32770", "32771", "32773", "32774", "32775", "32776", "32778", "32779", "32784", "32785", "32786", "32788", "32789", "32794", "32795", "32796", "32797", "32799", "32801", "32802", "32803", "32808", "32811", "32812", "32814", "32820", "32821", "32823", "32824", "32826", "32827", "32832", "32835", "32838", "32839", "32842", "32843", "32844", "32845", "32846", "32847", "32851", "32855", "32857", "32858", "32860", "32861", "32863", "32864", "32869", "32870", "32877", "32878", "32879", "32880", "32884", "32890", "32891", "32892", "32894", "32896", "32898", "32899", "32905", "32906", "32907", "32910", "32912", "32913", "32914", "32916", "32917", "32918", "32919", "32922", "32924", "32925", "32926", "32928", "32930", "32931", "32934", "32935", "32938", "32940", "32941", "32942", "32943", "32944", "32945", "32946", "32948", "32949", "32950", "32952", "32953", "32954", "32955", "32957", "32958", "32959", "32963", "32969", "32970", "32972", "32975", "32976", "32977", "32978", "32979", "32980", "32981", "32982", "32983", "32985", "32986", "32990", "32991", "32995", "32999", "33000", "33002", "33003", "33004", "33006", "33007", "33010", "33012", "33013", "33014", "33015", "33016", "33017", "33021", "33022", "33025", "33026", "33027", "33029", "33031", "33035", "33036", "33040", "33041", "33043", "33045", "33047", "33048", "33050", "33051", "33056", "33057", "33061", "33063", "33064", "33069", "33070", "33077", "33079", "33080", "33082", "33085", "33087", "33090", "33094", "33095", "33097", "33098", "33099", "33100", "33101", "33102", "33103", "33105", "33108", "33111", "33112", "33116", "33124", "33127", "33128", "33130", "33131", "33132", "33133", "33136", "33140", "33141", "33144", "33145", "33147", "33149", "33150", "33152", "33155", "33157", "33161", "33163", "33166", "33170", "33173", "33176", "33178", "33179", "33180", "33188", "33191", "33192", "33193", "33195", "33196", "33197", "33200", "33202", "33205", "33209", "33213", "33214", "33215", "33216", "33217", "33221", "33226", "33232", "33234", "33235", "33242", "33245", "33248", "33251", "33252", "33254", "33257", "33258", "33260", "33263", "33265", "33266", "33270", "33271", "33273", "33275", "33277", "33281", "33282", "33284", "33291", "33293", "33295", "33296", "33299", "33305", "33306", "33307", "33308", "33311", "33312", "33313", "33315", "33320", "33321", "33326", "33327", "33330", "33331", "33334", "33336", "33337", "33340", "33343", "33345", "33347", "33352", "33353", "33354", "33355", "33361", "33362", "33367", "33369", "33374", "33379", "33380", "33382", "33383", "33385", "33388", "33389", "33390", "33392", "33394", "33395", "33396", "33398", "33399", "33401", "33403", "33404", "33406", "33408", "33409", "33411", "33414", "33415", "33418", "33419", "33423", "33428", "33432", "33433", "33436", "33438", "33439", "33442", "33444", "33445", "33447", "33449", "33450", "33452", "33454", "33456", "33459", "33461", "33464", "33465", "33466", "33470", "33471", "33472", "33473", "33477", "33481", "33483", "33487", "33488", "33490", "33491", "33492", "33494", "33496", "33500", "33502", "33506", "33507", "33514", "33516", "33518", "33519", "33520", "33523", "33524", "33525", "33526", "33527", "33532", "33533", "33534", "33535", "33538", "33539", "33541", "33545", "33546", "33547", "33548", "33557", "33563", "33565", "33568", "33569", "33570", "33571", "33572", "33577", "33579", "33581", "33585", "33586", "33587", "33588", "33593", "33596", "33597", "33600", "33601", "33603", "33604", "33605", "33608", "33609", "33610", "33611", "33613", "33614", "33615", "33616", "33617", "33618", "33621", "33622", "33623", "33627", "33628", "33630", "33631", "33632", "33634", "33635", "33636", "33638", "33639", "33641", "33642", "33644", "33645", "33646", "33648", "33649", "33653", "33655", "33656", "33657", "33658", "33659", "33661", "33662", "33667", "33669", "33670", "33671", "33674", "33675", "33677", "33684", "33687", "33689", "33693", "33694", "33696", "33697", "33699", "33700", "33702", "33705", "33706", "33707", "33711", "33714", "33716", "33717", "33718", "33721", "33722", "33728", "33729", "33731", "33734", "33735", "33736", "33737", "33738", "33740", "33741", "33745", "33748", "33749", "33755", "33758", "33759", "33760", "33761", "33762", "33763", "33766", "33767", "33769", "33770", "33771", "33774", "33775", "33776", "33780", "33781", "33785", "33786", "33787", "33789", "33790", "33791", "33793", "33797", "33802", "33803", "33805", "33806", "33807", "33808", "33809", "33810", "33811", "33813", "33814", "33817", "33818", "33819", "33820", "33821", "33822", "33823", "33830", "33831", "33835", "33837", "33838", "33841", "33843", "33846", "33847", "33849", "33850", "33852", "33853", "33855", "33859", "33860", "33862", "33863", "33864", "33865", "33869", "33870", "33872", "33875", "33877", "33878", "33879", "33883", "33884", "33885", "33889", "33890", "33891", "33892", "33893", "33894", "33895", "33896", "33901", "33903", "33904", "33905", "33907", "33908", "33911", "33916", "33919", "33921", "33923", "33926", "33933", "33934", "33935", "33937", "33940", "33943", "33944", "33945", "33949", "33950", "33951", "33952", "33953", "33961", "33962", "33963", "33964", "33965", "33966", "33968", "33969", "33970", "33973", "33975", "33976", "33979", "33981", "33982", "33986", "33989", "33991", "33992", "33995", "33996", "33997", "33998", "34000", "34002", "34005", "34006", "34007", "34008", "34009", "34011", "34014", "34015", "34016", "34018", "34019", "34020", "34021", "34022", "34024", "34025", "34028", "34030", "34031", "34034", "34035", "34038", "34039", "34040", "34043", "34046", "34048", "34055", "34056", "34059", "34060", "34061", "34062", "34064", "34067", "34068", "34069", "34071", "34073", "34077", "34082", "34084", "34087", "34088", "34093", "34094", "34096", "34098", "34099", "34100", "34112", "34115", "34117", "34118", "34122", "34124", "34128", "34129", "34134", "34136", "34137", "34138", "34139", "34140", "34142", "34144", "34145", "34146", "34148", "34149", "34153", "34154", "34156", "34159", "34163", "34164", "34167", "34168", "34169", "34171", "34174", "34175", "34176", "34177", "34178", "34179", "34181", "34185", "34186", "34188", "34189", "34190", "34191", "34192", "34193", "34195", "34196", "34200", "34201", "34204", "34206", "34212", "34214", "34216", "34217", "34218", "34220", "34224", "34226", "34227", "34229", "34230", "34231", "34234", "34238", "34241", "34243", "34245", "34249", "34250", "34253", "34255", "34256", "34257", "34258", "34259", "34260", "34263", "34269", "34270", "34272", "34278", "34280", "34281", "34283", "34285", "34288", "34289", "34292", "34294", "34295", "34298", "34301", "34305", "34306", "34307", "34309", "34315", "34318", "34319", "34320", "34325", "34328", "34334", "34336", "34338", "34340", "34342", "34344", "34350", "34352", "34354", "34355", "34357", "34358", "34359", "34361", "34362", "34365", "34367", "34368", "34369", "34371", "34374", "34376", "34381", "34386", "34388", "34389", "34390", "34392", "34394", "34399", "34405", "34409", "34412", "34413", "34414", "34415", "34418", "34420", "34422", "34425", "34426", "34429", "34436", "34437", "34439", "34440", "34443", "34444", "34445", "34449", "34450", "34451", "34454", "34455", "34459", "34466", "34467", "34468", "34471", "34476", "34478", "34479", "34485", "34486", "34489", "34491", "34494", "34496", "34498", "34499", "34500", "34502", "34504", "34506", "34510", "34512", "34513", "34514", "34516", "34517", "34518", "34519", "34520", "34521", "34523", "34533", "34534", "34535", "34539", "34543", "34544", "34546", "34547", "34548", "34554", "34555", "34556", "34557", "34558", "34561", "34564", "34565", "34566", "34567", "34568", "34569", "34571", "34574", "34575", "34576", "34578", "34579", "34582", "34583", "34586", "34587", "34589", "34590", "34591", "34592", "34594", "34595", "34596", "34597", "34598", "34601", "34602", "34603", "34605", "34606", "34608", "34610", "34614", "34616", "34617", "34619", "34621", "34623", "34626", "34627", "34628", "34632", "34633", "34634", "34636", "34640", "34643", "34644", "34645", "34646", "34648", "34650", "34654", "34655", "34657", "34658", "34659", "34660", "34665", "34667", "34668", "34669", "34670", "34672", "34673", "34674", "34676", "34677", "34678", "34680", "34681", "34682", "34683", "34686", "34687", "34689", "34690", "34692", "34693", "34694", "34696", "34698", "34699", "34701", "34704", "34705", "34708", "34709", "34710", "34711", "34712", "34716", "34717", "34719", "34720", "34721", "34722", "34725", "34727", "34728", "34729", "34730", "34732", "34733", "34734", "34735", "34737", "34738", "34739", "34740", "34742", "34743", "34744", "34745", "34748", "34749", "34750", "34753", "34755", "34757", "34759", "34761", "34762", "34768", "34769", "34770", "34771", "34774", "34775", "34776", "34780", "34781", "34783", "34784", "34787", "34788", "34791", "34794", "34796", "34797", "34799", "34800", "34801", "34803", "34805", "34806", "34808", "34809", "34810", "34812", "34815", "34816", "34822", "34824", "34825", "34826", "34830", "34831", "34837", "34838", "34840", "34842", "34843", "34844", "34845", "34847", "34849", "34850", "34852", "34854", "34855", "34856", "34859", "34862", "34864", "34867", "34868", "34869", "34871", "34872", "34877", "34878", "34879", "34880", "34881", "34883", "34887", "34888", "34889", "34890", "34891", "34894", "34895", "34899", "34902", "34903", "34904", "34905", "34907", "34909", "34910", "34911", "34915", "34919", "34920", "34923", "34924", "34926", "34927", "34929", "34931", "34933", "34934", "34935", "34937", "34938", "34939", "34940", "34943", "34944", "34945", "34946", "34949", "34951", "34952", "34954", "34955", "34956", "34957", "34959", "34963", "34965", "34967", "34970", "34975", "34978", "34980", "34982", "34983", "34985", "34986", "34987", "34989", "34990", "34991", "34992", "34993", "34995", "34997", "35006", "35008", "35009", "35010", "35011", "35014", "35016", "35017", "35018", "35019", "35020", "35023", "35025", "35026", "35027", "35028", "35030", "35031", "35032", "35033", "35035", "35036", "35037", "35038", "35044", "35046", "35048", "35052", "35054", "35061", "35062", "35066", "35067", "35068", "35070", "35071", "35073", "35076", "35077", "35078", "35080", "35081", "35082", "35083", "35085", "35089", "35090", "35091", "35093", "35094", "35098", "35103", "35106", "35107", "35109", "35111", "35118", "35119", "35120", "35124", "35125", "35127", "35130", "35133", "35135", "35136", "35137", "35139", "35144", "35146", "35148", "35150", "35151", "35158", "35159", "35161", "35162", "35163", "35164", "35166", "35168", "35171", "35173", "35175", "35177", "35178", "35180", "35181", "35182", "35185", "35187", "35188", "35191", "35192", "35193", "35195", "35196", "35199", "35201", "35203", "35204", "35205", "35206", "35208", "35211", "35214", "35217", "35218", "35219", "35221", "35222", "35224", "35227", "35228", "35231", "35232", "35233", "35234", "35237", "35238", "35240", "35241", "35242", "35246", "35247", "35249", "35250", "35251", "35252", "35257", "35260", "35264", "35268", "35271", "35272", "35273", "35274", "35276", "35277", "35278", "35279", "35280", "35282", "35284", "35286", "35287", "35289", "35293", "35296", "35299", "35300", "35301", "35304", "35306", "35311", "35312", "35314", "35316", "35317", "35319", "35322", "35323", "35324", "35329", "35330", "35331", "35332", "35334", "35335", "35336", "35337", "35339", "35340", "35342", "35343", "35344", "35345", "35346", "35347", "35349", "35351", "35354", "35355", "35356", "35357", "35359", "35362", "35365", "35366", "35367", "35373", "35380", "35382", "35384", "35386", "35388", "35391", "35392", "35393", "35397", "35400", "35402", "35404", "35405", "35406", "35407", "35408", "35411", "35414", "35415", "35416", "35417", "35422", "35423", "35424", "35430", "35432", "35433", "35434", "35436", "35438", "35442", "35443", "35444", "35446", "35447", "35450", "35454", "35457", "35458", "35459", "35460", "35461", "35466", "35467", "35469", "35470", "35471", "35472", "35475", "35480", "35481", "35484", "35486", "35487", "35488", "35489", "35490", "35496", "35497", "35498", "35499", "35500", "35501", "35504", "35505", "35506", "35507", "35508", "35509", "35512", "35514", "35518", "35521", "35525", "35528", "35529", "35530", "35531", "35533", "35535", "35537", "35541", "35542", "35545", "35547", "35548", "35550", "35551", "35553", "35555", "35556", "35557", "35558", "35559", "35561", "35562", "35568", "35569", "35572", "35573", "35575", "35576", "35577", "35582", "35586", "35587", "35588", "35597", "35598", "35600", "35601", "35605", "35607", "35609", "35610", "35612", "35613", "35615", "35616", "35619", "35620", "35621", "35622", "35623", "35632", "35636", "35637", "35640", "35642", "35648", "35650", "35651", "35654", "35655", "35656", "35660", "35661", "35662", "35663", "35665", "35669", "35671", "35673", "35674", "35676", "35677", "35678", "35679", "35680", "35682", "35683", "35684", "35685", "35689", "35690", "35692", "35694", "35695", "35697", "35701", "35702", "35704", "35707", "35713", "35714", "35715", "35716", "35718", "35720", "35721", "35722", "35724", "35726", "35729", "35730", "35731", "35732", "35739", "35742", "35743", "35746", "35747", "35750", "35754", "35755", "35757", "35758", "35760", "35761", "35763", "35765", "35766", "35767", "35768", "35769", "35773", "35775", "35776", "35779", "35780", "35781", "35782", "35784", "35791", "35793", "35795", "35796", "35798", "35799", "35800", "35803", "35806", "35810", "35813", "35814", "35816", "35818", "35819", "35821", "35822", "35824", "35827", "35829", "35830", "35832", "35833", "35835", "35836", "35838", "35840", "35843", "35844", "35845", "35847", "35849", "35850", "35853", "35855", "35857", "35858", "35859", "35863", "35865", "35868", "35870", "35872", "35873", "35875", "35880", "35882", "35884", "35885", "35889", "35891", "35892", "35893", "35896", "35899", "35900", "35905", "35906", "35909", "35912", "35914", "35920", "35922", "35923", "35924", "35927", "35928", "35929", "35930", "35936", "35938", "35940", "35941", "35943", "35945", "35946", "35948", "35952", "35957", "35959", "35960", "35963", "35964", "35966", "35967", "35968", "35969", "35970", "35972", "35973", "35975", "35976", "35977", "35978", "35979", "35981", "35982", "35984", "35985", "35986", "35993", "35995", "35996", "35998", "36007", "36008", "36009", "36010", "36011", "36012", "36013", "36016", "36018", "36021", "36023", "36024", "36025", "36026", "36027", "36029", "36037", "36038", "36039", "36042", "36043", "36046", "36050", "36052", "36053", "36055", "36056", "36057", "36060", "36064", "36065", "36067", "36071", "36073", "36076", "36078", "36079", "36084", "36085", "36092", "36093", "36094", "36095", "36096", "36097", "36098", "36100", "36102", "36104", "36105", "36106", "36107", "36112", "36114", "36116", "36117", "36118", "36120", "36122", "36123", "36125", "36127", "36128", "36129", "36131", "36133", "36138", "36139", "36140", "36144", "36145", "36146", "36147", "36148", "36150", "36153", "36154", "36156", "36157", "36159", "36160", "36161", "36162", "36164", "36165", "36168", "36169", "36175", "36177", "36178", "36179", "36181", "36182", "36184", "36185", "36186", "36187", "36193", "36194", "36196", "36199", "36206", "36210", "36211", "36214", "36216", "36218", "36219", "36220", "36221", "36222", "36225", "36226", "36228", "36231", "36232", "36233", "36238", "36239", "36241", "36244", "36245", "36247", "36248", "36249", "36250", "36251", "36252", "36254", "36255", "36256", "36257", "36258", "36259", "36260", "36261", "36263", "36265", "36266", "36268", "36273", "36275", "36276", "36278", "36279", "36281", "36285", "36286", "36287", "36290", "36292", "36293", "36294", "36295", "36296", "36298", "36299", "36306", "36311", "36312", "36315", "36317", "36320", "36323", "36326", "36328", "36330", "36331", "36333", "36334", "36335", "36337", "36339", "36342", "36344", "36345", "36348", "36349", "36353", "36356", "36357", "36358", "36360", "36362", "36366", "36367", "36368", "36369", "36371", "36375", "36382", "36383", "36387", "36388", "36389", "36398", "36399", "36405", "36406", "36407", "36409", "36412", "36414", "36416", "36418", "36419", "36420", "36422", "36425", "36427", "36429", "36433", "36436", "36437", "36438", "36440", "36442", "36444", "36450", "36453", "36454", "36455", "36456", "36460", "36462", "36464", "36465", "36468", "36469", "36475", "36476", "36478", "36479", "36480", "36481", "36484", "36485", "36487", "36488", "36491", "36492", "36494", "36506", "36507", "36508", "36509", "36514", "36516", "36520", "36521", "36522", "36523", "36525", "36527", "36528", "36529", "36531", "36532", "36537", "36538", "36540", "36542", "36544", "36547", "36549", "36551", "36561", "36562", "36564", "36571", "36572", "36575", "36579", "36580", "36582", "36585", "36586", "36587", "36588", "36589", "36590", "36591", "36592", "36593", "36596", "36598", "36599", "36601", "36602", "36604", "36606", "36611", "36612", "36614", "36616", "36618", "36619", "36620", "36624", "36626", "36628", "36631", "36632", "36634", "36638", "36641", "36642", "36644", "36645", "36648", "36649", "36650", "36651", "36652", "36662", "36663", "36664", "36665", "36666", "36669", "36671", "36673", "36674", "36676", "36677", "36679", "36680", "36682", "36684", "36687", "36689", "36691", "36692", "36695", "36697", "36700", "36701", "36702", "36707", "36709", "36713", "36716", "36717", "36719", "36722", "36723", "36724", "36725", "36727", "36728", "36731", "36732", "36738", "36740", "36745", "36747", "36748", "36749", "36750", "36753", "36754", "36755", "36756", "36762", "36764", "36766", "36767", "36769", "36772", "36774", "36775", "36777", "36779", "36780", "36782", "36783", "36785", "36786", "36792", "36798", "36799", "36800", "36803", "36804", "36805", "36806", "36807", "36808", "36809", "36810", "36812", "36814", "36817", "36818", "36819", "36822", "36824", "36826", "36828", "36831", "36834", "36835", "36837", "36838", "36840", "36842", "36844", "36847", "36848", "36849", "36852", "36853", "36859", "36861", "36865", "36868", "36869", "36874", "36879", "36880", "36882", "36883", "36884", "36885", "36886", "36889", "36890", "36891", "36892", "36893", "36896", "36901", "36904", "36905", "36906", "36916", "36918", "36919", "36926", "36929", "36930", "36931", "36932", "36934", "36936", "36940", "36941", "36943", "36945", "36948", "36949", "36950", "36953", "36956", "36958", "36959", "36962", "36963", "36965", "36967", "36968", "36969", "36971", "36972", "36973", "36974", "36976", "36977", "36980", "36981", "36983", "36984", "36986", "36990", "36993", "36995", "36996", "37002", "37003", "37004", "37007", "37008", "37011", "37016", "37020", "37022", "37024", "37025", "37028", "37030", "37031", "37032", "37037", "37045", "37047", "37049", "37050", "37053", "37055", "37056", "37058", "37060", "37062", "37063", "37065", "37068", "37069", "37071", "37072", "37073", "37075", "37078", "37079", "37080", "37082", "37085", "37088", "37093", "37095", "37096", "37097", "37098", "37099", "37102", "37103", "37104", "37105", "37109", "37111", "37115", "37117", "37118", "37119", "37120", "37123", "37124", "37126", "37132", "37135", "37137", "37141", "37142", "37145", "37146", "37149", "37150", "37152", "37155", "37156", "37159", "37160", "37162", "37165", "37168", "37170", "37173", "37175", "37176", "37180", "37181", "37183", "37186", "37189", "37196", "37198", "37200", "37202", "37204", "37206", "37208", "37209", "37212", "37215", "37216", "37218", "37221", "37223", "37225", "37227", "37232", "37233", "37235", "37236", "37237", "37238", "37243", "37244", "37248", "37251", "37252", "37254", "37256", "37257", "37258", "37259", "37260", "37262", "37264", "37266", "37267", "37268", "37274", "37275", "37281", "37282", "37284", "37285", "37286", "37291", "37293", "37294", "37295", "37301", "37304", "37306", "37308", "37309", "37312", "37315", "37316", "37317", "37320", "37321", "37322", "37324", "37326", "37327", "37328", "37330", "37333", "37335", "37336", "37338", "37339", "37340", "37341", "37342", "37345", "37346", "37348", "37353", "37354", "37355", "37356", "37357", "37359", "37360", "37361", "37362", "37366", "37367", "37374", "37377", "37378", "37380", "37381", "37383", "37384", "37388", "37389", "37391", "37393", "37394", "37395", "37396", "37397", "37398", "37399", "37400", "37401", "37405", "37407", "37409", "37414", "37415", "37417", "37420", "37422", "37423", "37425", "37428", "37429", "37430", "37431", "37432", "37433", "37435", "37436", "37440", "37442", "37444", "37446", "37448", "37449", "37450", "37453", "37454", "37456", "37460", "37465", "37466", "37467", "37468", "37469", "37473", "37475", "37476", "37477", "37479", "37480", "37482", "37483", "37484", "37485", "37486", "37487", "37489", "37491", "37494", "37497", "37499", "37503", "37504", "37505", "37512", "37513", "37514", "37516", "37519", "37521", "37523", "37524", "37528", "37530", "37532", "37538", "37539", "37543", "37546", "37548", "37549", "37550", "37552", "37556", "37557", "37559", "37560", "37562", "37565", "37566", "37567", "37568", "37569", "37570", "37571", "37572", "37574", "37575", "37576", "37577", "37582", "37583", "37587", "37588", "37591", "37592", "37593", "37595", "37597", "37598", "37599", "37601", "37603", "37604", "37607", "37611", "37614", "37615", "37618", "37622", "37623", "37624", "37625", "37626", "37631", "37632", "37634", "37635", "37636", "37641", "37642", "37644", "37645", "37647", "37649", "37650", "37651", "37652", "37653", "37654", "37656", "37657", "37659", "37660", "37661", "37663", "37665", "37666", "37671", "37672", "37674", "37675", "37676", "37677", "37678", "37679", "37683", "37685", "37688", "37689", "37691", "37692", "37693", "37694", "37699", "37701", "37705", "37706", "37707", "37711", "37715", "37718", "37719", "37722", "37727", "37728", "37733", "37734", "37735", "37736", "37737", "37739", "37741", "37744", "37745", "37746", "37747", "37748", "37750", "37751", "37752", "37754", "37756", "37758", "37761", "37762", "37763", "37764", "37768", "37772", "37774", "37779", "37781", "37784", "37787", "37790", "37794", "37796", "37797", "37798", "37799", "37802", "37803", "37804", "37806", "37807", "37809", "37810", "37811", "37813", "37822", "37823", "37824", "37825", "37827", "37830", "37831", "37832", "37834", "37837", "37838", "37841", "37842", "37844", "37845", "37846", "37849", "37853", "37855", "37857", "37859", "37861", "37863", "37868", "37869", "37871", "37873", "37874", "37876", "37877", "37878", "37880", "37881", "37884", "37885", "37886", "37888", "37889", "37890", "37891", "37894", "37898", "37899", "37901", "37902", "37903", "37904", "37906", "37908", "37909", "37910", "37911", "37915", "37917", "37921", "37922", "37925", "37926", "37927", "37928", "37929", "37930", "37931", "37934", "37935", "37937", "37938", "37940", "37943", "37946", "37947", "37949", "37951", "37952", "37954", "37957", "37959", "37960", "37961", "37964", "37966", "37968", "37969", "37970", "37973", "37974", "37975", "37976", "37977", "37978", "37987", "37991", "37992", "37994", "37995", "37996", "38000", "38002", "38006", "38007", "38009", "38010", "38013", "38015", "38020", "38021", "38022", "38025", "38026", "38030", "38032", "38033", "38034", "38035", "38037", "38044", "38045", "38046", "38047", "38048", "38053", "38055", "38057", "38059", "38060", "38062", "38065", "38066", "38067", "38069", "38070", "38072", "38073", "38074", "38075", "38077", "38079", "38080", "38081", "38084", "38086", "38089", "38090", "38094", "38095", "38101", "38102", "38103", "38104", "38108", "38109", "38110", "38111", "38112", "38113", "38120", "38122", "38124", "38125", "38127", "38129", "38130", "38131", "38132", "38133", "38134", "38135", "38139", "38142", "38145", "38146", "38151", "38154", "38155", "38157", "38159", "38161", "38163", "38166", "38168", "38169", "38170", "38171", "38172", "38174", "38175", "38176", "38177", "38178", "38179", "38181", "38184", "38188", "38189", "38191", "38193", "38194", "38195", "38198", "38199", "38201", "38202", "38205", "38206", "38207", "38210", "38213", "38214", "38217", "38218", "38219", "38221", "38223", "38224", "38225", "38228", "38230", "38233", "38236", "38238", "38240", "38241", "38244", "38248", "38249", "38250", "38253", "38254", "38255", "38256", "38257", "38258", "38259", "38260", "38261", "38262", "38264", "38265", "38267", "38268", "38269", "38270", "38272", "38274", "38281", "38283", "38284", "38285", "38286", "38287", "38288", "38297", "38299", "38300", "38304", "38306", "38308", "38309", "38311", "38313", "38317", "38320", "38322", "38325", "38327", "38329", "38330", "38331", "38332", "38333", "38334", "38337", "38338", "38339", "38343", "38349", "38358", "38360", "38364", "38365", "38367", "38369", "38371", "38372", "38377", "38384", "38385", "38386", "38387", "38389", "38390", "38391", "38392", "38397", "38398", "38399", "38400", "38402", "38407", "38408", "38414", "38417", "38419", "38424", "38429", "38434", "38436", "38440", "38442", "38444", "38445", "38448", "38449", "38450", "38452", "38453", "38455", "38456", "38457", "38461", "38464", "38466", "38469", "38472", "38473", "38474", "38477", "38479", "38480", "38481", "38482", "38483", "38485", "38487", "38488", "38490", "38491", "38493", "38494", "38495", "38499", "38503", "38504", "38505", "38508", "38510", "38511", "38512", "38513", "38515", "38516", "38518", "38521", "38522", "38529", "38532", "38533", "38534", "38535", "38536", "38537", "38539", "38541", "38543", "38546", "38549", "38551", "38552", "38553", "38554", "38555", "38557", "38558", "38561", "38564", "38565", "38567", "38569", "38571", "38572", "38573", "38576", "38577", "38580", "38581", "38582", "38583", "38587", "38588", "38590", "38591", "38592", "38595", "38598", "38599", "38602", "38603", "38604", "38605", "38607", "38610", "38613", "38615", "38616", "38617", "38623", "38624", "38625", "38626", "38629", "38630", "38633", "38637", "38641", "38642", "38648", "38649", "38650", "38652", "38653", "38654", "38656", "38660", "38662", "38664", "38666", "38667", "38668", "38672", "38674", "38675", "38676", "38677", "38680", "38684", "38687", "38688", "38689", "38691", "38692", "38693", "38694", "38696", "38698", "38701", "38702", "38703", "38704", "38708", "38709", "38710", "38711", "38713", "38715", "38716", "38718", "38719", "38720", "38721", "38725", "38726", "38728", "38729", "38732", "38736", "38739", "38740", "38741", "38742", "38747", "38750", "38751", "38752", "38754", "38755", "38759", "38760", "38764", "38767", "38769", "38773", "38776", "38778", "38779", "38781", "38782", "38784", "38786", "38789", "38791", "38793", "38797", "38798", "38799", "38803", "38804", "38807", "38808", "38809", "38810", "38812", "38813", "38814", "38816", "38818", "38822", "38823", "38824", "38827", "38828", "38829", "38830", "38834", "38835", "38838", "38839", "38840", "38843", "38844", "38845", "38846", "38852", "38862", "38863", "38864", "38865", "38867", "38868", "38869", "38871", "38873", "38874", "38876", "38877", "38878", "38881", "38882", "38883", "38884", "38887", "38890", "38893", "38894", "38895", "38896", "38898", "38900", "38901", "38904", "38905", "38906", "38907", "38908", "38909", "38910", "38915", "38916", "38918", "38919", "38920", "38922", "38925", "38926", "38927", "38928", "38932", "38934", "38941", "38946", "38947", "38948", "38951", "38953", "38954", "38956", "38958", "38959", "38961", "38966", "38967", "38968", "38969", "38970", "38972", "38975", "38977", "38979", "38984", "38985", "38987", "38988", "38990", "38992", "38995", "38999", "39000", "39001", "39002", "39003", "39004", "39007", "39011", "39012", "39017", "39018", "39019", "39022", "39024", "39027", "39029", "39030", "39031", "39032", "39034", "39037", "39038", "39042", "39043", "39044", "39045", "39046", "39050", "39052", "39053", "39055", "39059", "39061", "39063", "39064", "39068", "39070", "39074", "39076", "39078", "39080", "39082", "39085", "39086", "39088", "39091", "39092", "39095", "39096", "39099", "39100", "39102", "39103", "39105", "39106", "39111", "39120", "39121", "39123", "39124", "39126", "39127", "39132", "39134", "39135", "39136", "39137", "39138", "39139", "39145", "39146", "39150", "39151", "39156", "39157", "39161", "39162", "39168", "39173", "39174", "39179", "39184", "39185", "39187", "39189", "39192", "39194", "39195", "39196", "39197", "39199", "39200", "39201", "39206", "39209", "39211", "39212", "39216", "39218", "39219", "39221", "39223", "39224", "39226", "39227", "39231", "39234", "39236", "39238", "39239", "39240", "39242", "39244", "39245", "39247", "39248", "39252", "39253", "39257", "39258", "39262", "39265", "39266", "39267", "39268", "39273", "39275", "39277", "39278", "39280", "39282", "39286", "39287", "39293", "39295", "39296", "39299", "39301", "39304", "39305", "39306", "39308", "39309", "39310", "39312", "39314", "39317", "39318", "39319", "39320", "39323", "39328", "39329", "39330", "39331", "39333", "39335", "39339", "39340", "39341", "39342", "39343", "39345", "39347", "39348", "39349", "39352", "39356", "39358", "39359", "39360", "39362", "39363", "39364", "39365", "39368", "39369", "39371", "39372", "39374", "39376", "39378", "39381", "39383", "39384", "39389", "39390", "39391", "39393", "39394", "39395", "39399", "39400", "39401", "39402", "39403", "39404", "39410", "39411", "39412", "39417", "39418", "39420", "39422", "39426", "39427", "39429", "39432", "39433", "39434", "39435", "39439", "39441", "39442", "39445", "39446", "39447", "39454", "39457", "39460", "39461", "39462", "39463", "39465", "39467", "39470", "39474", "39475", "39477", "39479", "39480", "39482", "39483", "39486", "39487", "39491", "39494", "39498", "39499", "39500", "39501", "39502", "39503", "39508", "39509", "39512", "39513", "39514", "39515", "39520", "39521", "39522", "39523", "39524", "39526", "39527", "39532", "39533", "39534", "39536", "39543", "39544", "39545", "39553", "39554", "39557", "39558", "39561", "39563", "39566", "39567", "39569", "39573", "39574", "39576", "39578", "39580", "39582", "39585", "39587", "39588", "39589", "39593", "39597", "39598", "39599", "39602", "39604", "39605", "39607", "39610", "39612", "39613", "39616", "39617", "39620", "39621", "39623", "39625", "39626", "39627", "39628", "39634", "39645", "39647", "39648", "39649", "39650", "39651", "39652", "39656", "39658", "39660", "39661", "39662", "39664", "39668", "39671", "39672", "39674", "39675", "39676", "39677", "39680", "39682", "39684", "39685", "39687", "39688", "39691", "39692", "39695", "39696", "39697", "39698", "39700", "39701", "39704", "39705", "39706", "39708", "39709", "39711", "39716", "39717", "39719", "39721", "39723", "39727", "39729", "39730", "39731", "39733", "39735", "39738", "39740", "39744", "39745", "39749", "39751", "39753", "39754", "39755", "39757", "39758", "39762", "39763", "39768", "39769", "39770", "39776", "39778", "39780", "39781", "39785", "39787", "39789", "39791", "39792", "39794", "39795", "39796", "39797", "39801", "39803", "39804", "39805", "39806", "39808", "39810", "39812", "39816", "39817", "39820", "39822", "39824", "39825", "39826", "39828", "39829", "39831", "39832", "39833", "39834", "39835", "39841", "39842", "39844", "39846", "39848", "39849", "39851", "39852", "39854", "39857", "39858", "39860", "39862", "39863", "39864", "39865", "39869", "39871", "39873", "39874", "39875", "39878", "39879", "39886", "39887", "39888", "39889", "39890", "39892", "39895", "39898", "39899", "39900", "39904", "39905", "39907", "39909", "39910", "39913", "39914", "39915", "39916", "39917", "39918", "39919", "39920", "39923", "39924", "39926", "39927", "39928", "39930", "39933", "39934", "39935", "39938", "39939", "39941", "39943", "39945", "39946", "39948", "39949", "39951", "39953", "39954", "39955", "39956", "39959", "39961", "39963", "39967", "39968", "39969", "39971", "39972", "39974", "39975", "39976", "39980", "39981", "39984", "39985", "39988", "39989", "39990", "39991", "39992", "39994", "39995", "39996", "39997", "40000", "40001", "40002", "40003", "40004", "40007", "40008", "40009", "40011", "40012", "40014", "40016", "40018", "40019", "40022", "40023", "40024", "40026", "40034", "40036", "40037", "40039", "40046", "40047", "40049", "40052", "40053", "40055", "40056", "40057", "40060", "40063", "40064", "40065", "40066", "40067", "40068", "40069", "40074", "40075", "40077", "40079", "40082", "40083", "40084", "40085", "40088", "40090", "40092", "40094", "40097", "40098", "40099", "40100", "40102", "40105", "40106", "40107", "40108", "40110", "40111", "40112", "40113", "40114", "40115", "40116", "40118", "40119", "40124", "40126", "40129", "40130", "40132", "40134", "40135", "40136", "40138", "40140", "40141", "40147", "40148", "40149", "40156", "40157", "40158", "40159", "40161", "40164", "40165", "40168", "40169", "40172", "40177", "40179", "40185", "40188", "40191", "40193", "40194", "40195", "40196", "40197", "40199", "40203", "40204", "40206", "40207", "40209", "40211", "40212", "40213", "40215", "40218", "40220", "40221", "40223", "40224", "40225", "40226", "40227", "40228", "40229", "40232", "40233", "40236", "40238", "40239", "40242", "40245", "40247", "40248", "40249", "40252", "40263", "40265", "40267", "40270", "40271", "40273", "40275", "40276", "40277", "40278", "40279", "40280", "40281", "40282", "40283", "40291", "40294", "40299", "40300", "40303", "40304", "40305", "40307", "40309", "40312", "40314", "40318", "40320", "40323", "40329", "40330", "40333", "40334", "40335", "40336", "40338", "40340", "40342", "40343", "40347", "40348", "40351", "40352", "40359", "40362", "40363", "40364", "40365", "40367", "40369", "40370", "40371", "40374", "40375", "40380", "40381", "40383", "40384", "40385", "40386", "40387", "40388", "40389", "40391", "40392", "40393", "40395", "40396", "40397", "40399", "40400", "40401", "40409", "40411", "40412", "40414", "40415", "40419", "40423", "40424", "40432", "40435", "40439", "40440", "40445", "40450", "40453", "40455", "40456", "40458", "40462", "40463", "40467", "40468", "40470", "40474", "40475", "40479", "40480", "40484", "40486", "40487", "40489", "40490", "40493", "40496", "40499", "40500", "40501", "40502", "40505", "40506", "40507", "40508", "40511", "40512", "40513", "40519", "40520", "40522", "40525", "40526", "40528", "40532", "40533", "40534", "40536", "40538", "40539", "40544", "40545", "40547", "40548", "40549", "40550", "40554", "40556", "40557", "40559", "40560", "40564", "40566", "40567", "40568", "40569", "40571", "40572", "40577", "40583", "40584", "40586", "40587", "40592", "40593", "40594", "40596", "40599", "40600", "40602", "40603", "40604", "40611", "40612", "40613", "40615", "40616", "40619", "40622", "40625", "40626", "40627", "40629", "40635", "40638", "40639", "40642", "40643", "40644", "40650", "40651", "40652", "40654", "40656", "40660", "40661", "40662", "40668", "40677", "40683", "40684", "40687", "40690", "40691", "40693", "40697", "40702", "40705", "40706", "40707", "40711", "40713", "40716", "40717", "40719", "40721", "40722", "40725", "40729", "40731", "40733", "40734", "40738", "40740", "40741", "40743", "40744", "40749", "40752", "40753", "40755", "40757", "40758", "40759", "40762", "40763", "40764", "40765", "40766", "40773", "40774", "40779", "40782", "40784", "40789", "40790", "40791", "40792", "40797", "40798", "40801", "40806", "40807", "40808", "40810", "40812", "40813", "40814", "40816", "40817", "40820", "40821", "40823", "40829", "40830", "40832", "40834", "40835", "40836", "40842", "40844", "40845", "40847", "40848", "40849", "40851", "40853", "40858", "40861", "40866", "40867", "40868", "40870", "40871", "40874", "40875", "40876", "40878", "40879", "40881", "40882", "40883", "40893", "40895", "40896", "40898", "40900", "40904", "40905", "40908", "40909", "40910", "40911", "40916", "40918", "40921", "40926", "40930", "40931", "40934", "40935", "40936", "40937", "40939", "40940", "40941", "40942", "40943", "40947", "40948", "40953", "40954", "40955", "40957", "40958", "40959", "40961", "40965", "40968", "40970", "40971", "40974", "40975", "40977", "40978", "40981", "40985", "40986", "40987", "40989", "40990", "40993", "40995", "40998", "40999", "41001", "41002", "41003", "41005", "41006", "41007", "41009", "41010", "41011", "41014", "41017", "41020", "41023", "41027", "41028", "41032", "41033", "41034", "41037", "41038", "41040", "41042", "41043", "41045", "41047", "41053", "41059", "41060", "41062", "41063", "41066", "41067", "41069", "41070", "41074", "41076", "41080", "41083", "41086", "41087", "41088", "41092", "41093", "41095", "41101", "41102", "41103", "41104", "41105", "41109", "41111", "41113", "41117", "41119", "41121", "41123", "41124", "41130", "41133", "41134", "41135", "41137", "41140", "41142", "41144", "41145", "41146", "41150", "41151", "41153", "41157", "41159", "41160", "41162", "41165", "41166", "41175", "41176", "41179", "41182", "41183", "41185", "41187", "41188", "41189", "41192", "41193", "41194", "41195", "41199", "41205", "41207", "41209", "41210", "41212", "41213", "41215", "41219", "41221", "41222", "41224", "41231", "41234", "41239", "41241", "41243", "41244", "41245", "41247", "41248", "41249", "41252", "41256", "41257", "41258", "41262", "41263", "41267", "41269", "41272", "41274", "41275", "41278", "41280", "41282", "41283", "41285", "41286", "41287", "41288", "41289", "41292", "41293", "41294", "41296", "41297", "41298", "41299", "41300", "41303", "41304", "41305", "41307", "41308", "41310", "41312", "41315", "41321", "41322", "41323", "41324", "41326", "41327", "41328", "41330", "41331", "41335", "41337", "41340", "41343", "41349", "41350", "41353", "41355", "41356", "41357", "41358", "41359", "41361", "41363", "41365", "41367", "41371", "41373", "41374", "41375", "41376", "41379", "41380", "41381", "41382", "41384", "41386", "41387", "41388", "41390", "41392", "41395", "41397", "41398", "41401", "41403", "41404", "41407", "41409", "41410", "41412", "41414", "41419", "41420", "41424", "41426", "41428", "41429", "41432", "41433", "41434", "41435", "41438", "41440", "41441", "41444", "41445", "41448", "41452", "41454", "41457", "41458", "41459", "41460", "41462", "41463", "41464", "41465", "41466", "41467", "41468", "41470", "41473", "41474", "41476", "41479", "41480", "41483", "41485", "41486", "41488", "41489", "41491", "41494", "41495", "41497", "41498", "41503", "41506", "41509", "41510", "41511", "41512", "41513", "41519", "41521", "41522", "41523", "41526", "41527", "41528", "41529", "41530", "41531", "41533", "41534", "41535", "41541", "41545", "41546", "41547", "41548", "41549", "41555", "41560", "41562", "41564", "41567", "41570", "41571", "41573", "41575", "41576", "41580", "41581", "41582", "41583", "41584", "41585", "41589", "41591", "41592", "41593", "41596", "41597", "41602", "41606", "41607", "41609", "41615", "41616", "41617", "41618", "41619", "41620", "41621", "41622", "41625", "41627", "41630", "41631", "41633", "41634", "41635", "41638", "41639", "41644", "41645", "41646", "41648", "41651", "41652", "41653", "41656", "41657", "41662", "41664", "41665", "41667", "41668", "41672", "41673", "41674", "41676", "41677", "41681", "41682", "41683", "41685", "41687", "41690", "41691", "41692", "41693", "41695", "41696", "41699", "41700", "41701", "41704", "41707", "41708", "41709", "41710", "41712", "41713", "41715", "41716", "41717", "41718", "41719", "41722", "41724", "41725", "41726", "41730", "41733", "41735", "41736", "41739", "41742", "41743", "41745", "41748", "41750", "41753", "41755", "41756", "41761", "41762", "41763", "41764", "41766", "41767", "41768", "41774", "41775", "41776", "41778", "41780", "41781", "41782", "41785", "41787", "41789", "41790", "41795", "41797", "41798", "41799", "41803", "41805", "41806", "41807", "41810", "41811", "41813", "41814", "41815", "41817", "41818", "41819", "41820", "41823", "41824", "41825", "41826", "41827", "41830", "41831", "41832", "41833", "41835", "41837", "41838", "41839", "41840", "41841", "41842", "41843", "41846", "41847", "41848", "41849", "41852", "41853", "41856", "41857", "41859", "41860", "41864", "41865", "41866", "41867", "41868", "41869", "41871", "41874", "41876", "41877", "41878", "41879", "41881", "41882", "41883", "41884", "41885", "41887", "41890", "41892", "41895", "41896", "41898", "41899", "41904", "41906", "41908", "41910", "41911", "41912", "41913", "41919", "41920", "41921", "41922", "41923", "41924", "41926", "41929", "41931", "41933", "41935", "41936", "41937", "41939", "41940", "41941", "41945", "41948", "41950", "41951", "41953", "41955", "41956", "41957", "41959", "41961", "41962", "41963", "41964", "41968", "41970", "41972", "41973", "41974", "41976", "41980", "41983", "41984", "41985", "41986", "41987", "41988", "41989", "41991", "41992", "41994", "41995", "41996", "41997", "42000", "42001", "42002", "42005", "42006", "42008", "42012", "42013", "42014", "42015", "42017", "42018", "42019", "42024", "42025", "42026", "42027", "42029", "42030", "42032", "42038", "42039", "42040", "42041", "42043", "42044", "42045", "42051", "42052", "42053", "42057", "42058", "42059", "42061", "42062", "42064", "42066", "42067", "42070", "42071", "42072", "42076", "42077", "42079", "42080", "42084", "42085", "42086", "42091", "42092", "42093", "42097", "42103", "42104", "42106", "42107", "42108", "42110", "42111", "42112", "42116", "42121", "42123", "42125", "42126", "42127", "42128", "42131", "42132", "42133", "42134", "42135", "42136", "42137", "42138", "42140", "42141", "42143", "42145", "42147", "42149", "42150", "42151", "42154", "42155", "42164", "42166", "42168", "42170", "42171", "42174", "42175", "42176", "42178", "42180", "42181", "42182", "42184", "42185", "42186", "42188", "42190", "42192", "42193", "42198", "42200", "42201", "42202", "42205", "42206", "42207", "42208", "42213", "42216", "42218", "42220", "42222", "42226", "42229", "42230", "42232", "42235", "42237", "42238", "42240", "42241", "42242", "42243", "42244", "42248", "42253", "42254", "42255", "42256", "42259", "42260", "42261", "42262", "42263", "42264", "42267", "42270", "42274", "42275", "42280", "42281", "42283", "42284", "42285", "42287", "42288", "42290", "42291", "42292", "42294", "42296", "42299", "42302", "42304", "42305", "42306", "42307", "42308", "42312", "42314", "42316", "42317", "42318", "42319", "42320", "42322", "42325", "42328", "42329", "42332", "42335", "42337", "42338", "42340", "42341", "42343", "42348", "42349", "42351", "42353", "42357", "42358", "42360", "42361", "42364", "42366", "42367", "42369", "42370", "42371", "42372", "42373", "42376", "42377", "42383", "42384", "42387", "42390", "42391", "42392", "42395", "42400", "42401", "42402", "42403", "42406", "42408", "42409", "42411", "42412", "42414", "42415", "42416", "42417", "42419", "42420", "42421", "42424", "42426", "42427", "42429", "42430", "42431", "42433", "42434", "42435", "42436", "42440", "42443", "42444", "42446", "42450", "42452", "42453", "42455", "42457", "42460", "42461", "42464", "42466", "42467", "42468", "42469", "42472", "42473", "42476", "42479", "42481", "42482", "42484", "42487", "42488", "42494", "42495", "42501", "42502", "42503", "42505", "42506", "42508", "42510", "42512", "42516", "42517", "42520", "42521", "42522", "42524", "42529", "42530", "42531", "42532", "42533", "42535", "42537", "42538", "42540", "42542", "42543", "42545", "42548", "42549", "42552", "42553", "42556", "42559", "42562", "42565", "42566", "42567", "42570", "42573", "42580", "42583", "42585", "42588", "42589", "42590", "42594", "42595", "42598", "42599", "42600", "42601", "42603", "42610", "42611", "42614", "42620", "42621", "42622", "42623", "42624", "42626", "42627", "42628", "42629", "42630", "42632", "42633", "42636", "42637", "42639", "42640", "42642", "42643", "42648", "42649", "42651", "42652", "42653", "42657", "42661", "42662", "42667", "42672", "42675", "42676", "42678", "42679", "42681", "42682", "42683", "42685", "42686", "42688", "42690", "42696", "42702", "42703", "42704", "42707", "42708", "42711", "42713", "42715", "42716", "42718", "42722", "42723", "42725", "42726", "42728", "42732", "42734", "42736", "42737", "42744", "42745", "42751", "42752", "42755", "42759", "42760", "42767", "42768", "42770", "42772", "42773", "42774", "42777", "42779", "42780", "42781", "42783", "42785", "42786", "42788", "42789", "42790", "42792", "42797", "42799", "42801", "42802", "42805", "42806", "42807", "42808", "42809", "42811", "42815", "42816", "42817", "42819", "42821", "42823", "42824", "42826", "42830", "42831", "42833", "42837", "42840", "42841", "42844", "42846", "42848", "42849", "42851", "42853", "42856", "42858", "42867", "42868", "42869", "42870", "42871", "42872", "42873", "42874", "42876", "42880", "42882", "42883", "42884", "42885", "42887", "42888", "42889", "42890", "42891", "42895", "42898", "42900", "42905", "42907", "42908", "42909", "42910", "42912", "42915", "42917", "42919", "42920", "42921", "42922", "42923", "42925", "42926", "42927", "42929", "42930", "42931", "42933", "42936", "42938", "42939", "42942", "42945", "42946", "42948", "42949", "42952", "42953", "42954", "42955", "42956", "42957", "42958", "42959", "42960", "42961", "42964", "42965", "42967", "42968", "42969", "42970", "42971", "42979", "42980", "42982", "42987", "42988", "42990", "42992", "42994", "42995", "42996", "42997", "42998", "42999", "43003", "43008", "43009", "43012", "43017", "43018", "43019", "43025", "43026", "43032", "43033", "43034", "43035", "43040", "43048", "43049", "43050", "43052", "43053", "43057", "43059", "43060", "43061", "43063", "43064", "43067", "43069", "43070", "43072", "43074", "43075", "43076", "43078", "43079", "43081", "43083", "43085", "43086", "43087", "43089", "43092", "43093", "43094", "43095", "43096", "43098", "43100", "43103", "43104", "43105", "43108", "43110", "43111", "43112", "43113", "43114", "43115", "43116", "43120", "43122", "43126", "43127", "43128", "43132", "43133", "43139", "43142", "43144", "43145", "43147", "43148", "43149", "43150", "43151", "43154", "43156", "43161", "43162", "43163", "43164", "43166", "43169", "43170", "43175", "43176", "43177", "43178", "43179", "43181", "43182", "43183", "43184", "43185", "43187", "43188", "43189", "43190", "43191", "43192", "43195", "43200", "43201", "43203", "43204", "43205", "43206", "43207", "43208", "43209", "43213", "43215", "43217", "43218", "43219", "43221", "43222", "43223", "43225", "43226", "43229", "43230", "43233", "43234", "43236", "43238", "43239", "43240", "43242", "43243", "43244", "43246", "43249", "43252", "43255", "43256", "43257", "43258", "43259", "43260", "43263", "43264", "43265", "43266", "43267", "43268", "43269", "43275", "43279", "43280", "43281", "43283", "43286", "43288", "43292", "43293", "43296", "43297", "43300", "43304", "43308", "43310", "43313", "43315", "43316", "43319", "43321", "43324", "43325", "43326", "43327", "43329", "43330", "43331", "43332", "43333", "43334", "43335", "43337", "43342", "43343", "43349", "43353", "43354", "43357", "43358", "43359", "43361", "43362", "43365", "43366", "43367", "43368", "43371", "43372", "43378", "43379", "43382", "43384", "43386", "43387", "43388", "43389", "43392", "43393", "43394", "43395", "43398", "43399", "43401", "43402", "43404", "43409", "43412", "43414", "43415", "43416", "43417", "43419", "43421", "43422", "43423", "43424", "43425", "43427", "43430", "43431", "43435", "43436", "43437", "43438", "43439", "43441", "43442", "43446", "43448", "43452", "43454", "43456", "43458", "43459", "43463", "43465", "43466", "43470", "43471", "43472", "43478", "43480", "43481", "43482", "43483", "43485", "43488", "43491", "43492", "43494", "43496", "43497", "43498", "43499", "43501", "43502", "43504", "43510", "43512", "43513", "43517", "43518", "43519", "43525", "43531", "43532", "43535", "43536", "43537", "43541", "43544", "43545", "43546", "43547", "43549", "43552", "43553", "43554", "43556", "43558", "43559", "43562", "43566", "43573", "43575", "43576", "43578", "43579", "43581", "43587", "43591", "43593", "43596", "43597", "43603", "43605", "43608", "43609", "43610", "43611", "43614", "43617", "43618", "43622", "43623", "43625", "43627", "43629", "43630", "43634", "43636", "43637", "43639", "43640", "43643", "43644", "43646", "43647", "43649", "43652", "43653", "43655", "43656", "43657", "43658", "43659", "43663", "43665", "43666", "43668", "43669", "43670", "43671", "43673", "43674", "43677", "43682", "43687", "43688", "43690", "43692", "43693", "43694", "43695", "43697", "43698", "43699", "43701", "43702", "43703", "43704", "43706", "43708", "43709", "43710", "43711", "43712", "43715", "43718", "43721", "43722", "43723", "43725", "43727", "43728", "43729", "43731", "43732", "43734", "43735", "43736", "43737", "43742", "43743", "43744", "43745", "43747", "43749", "43750", "43756", "43759", "43760", "43761", "43762", "43763", "43764", "43765", "43766", "43774", "43776", "43779", "43781", "43782", "43784", "43786", "43787", "43789", "43790", "43791", "43792", "43796", "43797", "43799", "43800", "43801", "43802", "43804", "43806", "43807", "43808", "43809", "43810", "43814", "43815", "43817", "43818", "43821", "43822", "43823", "43824", "43826", "43827", "43828", "43830", "43832", "43836", "43837", "43839", "43840", "43845", "43848", "43850", "43853", "43854", "43855", "43856", "43857", "43859", "43861", "43866", "43867", "43868", "43871", "43872", "43875", "43877", "43879", "43883", "43885", "43888", "43889", "43891", "43893", "43896", "43897", "43898", "43899", "43902", "43903", "43905", "43908", "43909", "43911", "43913", "43914", "43918", "43920", "43921", "43922", "43924", "43925", "43927", "43929", "43939", "43940", "43941", "43944", "43947", "43948", "43950", "43951", "43952", "43953", "43954", "43955", "43959", "43963", "43964", "43965", "43966", "43968", "43970", "43971", "43972", "43974", "43975", "43979", "43980", "43981", "43983", "43984", "43985", "43987", "43988", "43989", "43990", "43991", "43993", "43994", "43996", "44001", "44005", "44006", "44007", "44014", "44015", "44016", "44018", "44019", "44020", "44023", "44024", "44025", "44029", "44030", "44031", "44033", "44034", "44035", "44037", "44038", "44042", "44044", "44045", "44047", "44051", "44052", "44053", "44054", "44056", "44057", "44059", "44060", "44061", "44062", "44063", "44068", "44075", "44076", "44077", "44078", "44079", "44081", "44082", "44084", "44087", "44091", "44092", "44093", "44094", "44096", "44098", "44108", "44111", "44112", "44114", "44115", "44117", "44118", "44121", "44122", "44124", "44127", "44131", "44133", "44135", "44138", "44139", "44146", "44147", "44148", "44149", "44152", "44153", "44158", "44159", "44164", "44166", "44167", "44169", "44170", "44176", "44177", "44179", "44180", "44181", "44182", "44186", "44189", "44190", "44191", "44192", "44194", "44196", "44197", "44199", "44200", "44201", "44202", "44204", "44207", "44214", "44217", "44218", "44219", "44220", "44221", "44226", "44227", "44228", "44230", "44231", "44234", "44235", "44236", "44238", "44240", "44243", "44244", "44245", "44247", "44248", "44249", "44250", "44251", "44253", "44255", "44256", "44257", "44258", "44260", "44262", "44265", "44266", "44268", "44269", "44272", "44273", "44277", "44278", "44279", "44288", "44289", "44290", "44294", "44296", "44300", "44304", "44305", "44312", "44314", "44316", "44317", "44318", "44322", "44323", "44324", "44327", "44329", "44330", "44331", "44332", "44333", "44335", "44337", "44339", "44344", "44345", "44348", "44349", "44350", "44351", "44352", "44354", "44356", "44357", "44358", "44363", "44365", "44366", "44370", "44374", "44375", "44376", "44378", "44381", "44382", "44384", "44385", "44388", "44390", "44392", "44395", "44396", "44397", "44399", "44400", "44405", "44408", "44410", "44412", "44413", "44415", "44418", "44420", "44422", "44423", "44424", "44427", "44428", "44429", "44430", "44431", "44432", "44434", "44435", "44438", "44439", "44441", "44443", "44444", "44446", "44449", "44450", "44453", "44454", "44455", "44456", "44458", "44459", "44460", "44465", "44467", "44468", "44470", "44473", "44475", "44476", "44477", "44478", "44481", "44485", "44487", "44488", "44489", "44490", "44493", "44494", "44495", "44499", "44501", "44503", "44504", "44505", "44507", "44512", "44513", "44515", "44517", "44518", "44519", "44521", "44525", "44526", "44527", "44528", "44530", "44532", "44533", "44534", "44536", "44541", "44544", "44545", "44546", "44547", "44548", "44549", "44550", "44551", "44557", "44558", "44560", "44562", "44564", "44568", "44570", "44573", "44574", "44575", "44578", "44579", "44581", "44583", "44584", "44589", "44590", "44592", "44593", "44595", "44602", "44603", "44606", "44607", "44611", "44613", "44614", "44617", "44618", "44619", "44620", "44621", "44623", "44625", "44628", "44629", "44630", "44631", "44632", "44634", "44636", "44637", "44640", "44641", "44643", "44644", "44645", "44647", "44648", "44653", "44658", "44659", "44662", "44664", "44665", "44667", "44670", "44672", "44673", "44674", "44676", "44677", "44679", "44683", "44690", "44694", "44699", "44700", "44701", "44704", "44708", "44709", "44711", "44712", "44715", "44716", "44718", "44722", "44723", "44724", "44725", "44730", "44731", "44732", "44734", "44736", "44737", "44738", "44740", "44742", "44743", "44744", "44747", "44749", "44751", "44756", "44758", "44761", "44762", "44764", "44765", "44771", "44774", "44775", "44780", "44781", "44782", "44786", "44791", "44798", "44799", "44800", "44802", "44803", "44804", "44806", "44807", "44808", "44815", "44816", "44817", "44821", "44822", "44824", "44828", "44829", "44831", "44833", "44834", "44837", "44840", "44841", "44845", "44847", "44848", "44849", "44850", "44852", "44853", "44855", "44859", "44860", "44862", "44863", "44864", "44865", "44869", "44871", "44874", "44875", "44876", "44877", "44879", "44883", "44884", "44886", "44887", "44893", "44896", "44897", "44899", "44901", "44902", "44906", "44908", "44911", "44912", "44913", "44917", "44921", "44927", "44928", "44929", "44932", "44933", "44934", "44936", "44937", "44938", "44940", "44941", "44943", "44944", "44949", "44950", "44961", "44962", "44965", "44966", "44967", "44970", "44971", "44972", "44973", "44982", "44983", "44986", "44989", "44990", "44992", "44993", "44994", "44995", "44997", "45000", "45001", "45003", "45004", "45007", "45009", "45011", "45015", "45019", "45020", "45021", "45022", "45025", "45027", "45030", "45031", "45032", "45033", "45034", "45035", "45037", "45039", "45040", "45041", "45044", "45045", "45049", "45051", "45052", "45055", "45057", "45062", "45063", "45065", "45067", "45068", "45069", "45072", "45073", "45081", "45084", "45085", "45086", "45094", "45097", "45100", "45102", "45104", "45105", "45106", "45107", "45108", "45109", "45113", "45115", "45117", "45118", "45119", "45122", "45124", "45125", "45126", "45127", "45129", "45133", "45135", "45136", "45140", "45141", "45143", "45148", "45149", "45156", "45159", "45160", "45161", "45162", "45165", "45166", "45168", "45169", "45170", "45171", "45172", "45173", "45174", "45175", "45176", "45178", "45179", "45181", "45182", "45184", "45185", "45186", "45187", "45189", "45191", "45193", "45194", "45195", "45198", "45201", "45203", "45206", "45207", "45208", "45209", "45210", "45211", "45213", "45215", "45216", "45218", "45220", "45221", "45222", "45223", "45224", "45225", "45226", "45228", "45229", "45235", "45237", "45240", "45243", "45248", "45251", "45260", "45261", "45262", "45263", "45264", "45265", "45266", "45267", "45268", "45272", "45273", "45275", "45278", "45281", "45282", "45283", "45284", "45287", "45288", "45289", "45291", "45294", "45296", "45297", "45300", "45306", "45308", "45311", "45312", "45313", "45316", "45317", "45318", "45319", "45320", "45321", "45322", "45323", "45324", "45325", "45328", "45331", "45332", "45333", "45334", "45335", "45336", "45338", "45342", "45343", "45344", "45345", "45346", "45347", "45350", "45352", "45353", "45356", "45357", "45359", "45361", "45362", "45365", "45366", "45369", "45370", "45373", "45374", "45376", "45378", "45380", "45383", "45384", "45385", "45388", "45389", "45390", "45394", "45395", "45397", "45399", "45401", "45402", "45406", "45407", "45408", "45410", "45411", "45412", "45414", "45415", "45416", "45417", "45422", "45423", "45425", "45427", "45428", "45430", "45432", "45434", "45435", "45436", "45437", "45438", "45440", "45442", "45443", "45444", "45445", "45446", "45449", "45451", "45453", "45457", "45459", "45463", "45467", "45468", "45472", "45473", "45475", "45478", "45480", "45481", "45482", "45483", "45486", "45490", "45491", "45494", "45496", "45498", "45499", "45500", "45502", "45503", "45505", "45506", "45509", "45513", "45514", "45515", "45518", "45519", "45521", "45522", "45524", "45525", "45528", "45531", "45535", "45539", "45541", "45542", "45545", "45546", "45548", "45551", "45552", "45556", "45558", "45559", "45564", "45568", "45569", "45570", "45573", "45575", "45579", "45581", "45583", "45584", "45588", "45591", "45593", "45595", "45596", "45598", "45600", "45604", "45605", "45609", "45610", "45613", "45616", "45617", "45618", "45619", "45624", "45625", "45629", "45631", "45634", "45635", "45636", "45639", "45640", "45642", "45646", "45649", "45652", "45653", "45657", "45660", "45661", "45665", "45667", "45669", "45670", "45671", "45674", "45675", "45677", "45679", "45681", "45682", "45684", "45685", "45688", "45691", "45692", "45696", "45697", "45698", "45701", "45702", "45704", "45707", "45708", "45710", "45711", "45713", "45714", "45717", "45719", "45720", "45721", "45723", "45725", "45726", "45732", "45733", "45734", "45735", "45736", "45737", "45738", "45739", "45740", "45743", "45744", "45745", "45748", "45753", "45754", "45756", "45757", "45758", "45760", "45761", "45762", "45764", "45765", "45766", "45767", "45771", "45773", "45776", "45780", "45782", "45783", "45784", "45787", "45788", "45793", "45798", "45799", "45800", "45801", "45803", "45806", "45808", "45813", "45814", "45817", "45820", "45822", "45823", "45825", "45830", "45834", "45836", "45837", "45841", "45848", "45849", "45851", "45852", "45853", "45854", "45855", "45856", "45858", "45860", "45861", "45862", "45864", "45868", "45872", "45873", "45875", "45878", "45880", "45881", "45885", "45886", "45887", "45888", "45890", "45892", "45893", "45894", "45895", "45899", "45901", "45904", "45906", "45907", "45909", "45911", "45912", "45913", "45914", "45917", "45918", "45919", "45920", "45922", "45925", "45928", "45929", "45930", "45935", "45936", "45940", "45941", "45942", "45943", "45944", "45949", "45950", "45951", "45953", "45954", "45955", "45959", "45961", "45962", "45964", "45965", "45966", "45969", "45971", "45973", "45975", "45977", "45980", "45981", "45982", "45983", "45984", "45985", "45987", "45988", "45990", "45993", "45995", "45996", "45999", "46007", "46011", "46015", "46016", "46017", "46018", "46019", "46021", "46022", "46025", "46029", "46030", "46031", "46032", "46035", "46040", "46041", "46046", "46049", "46053", "46054", "46057", "46059", "46061", "46062", "46063", "46065", "46067", "46068", "46071", "46079", "46080", "46081", "46083", "46084", "46086", "46087", "46088", "46090", "46093", "46096", "46102", "46103", "46104", "46105", "46107", "46108", "46109", "46110", "46111", "46113", "46116", "46117", "46119", "46123", "46125", "46126", "46130", "46132", "46135", "46137", "46138", "46141", "46142", "46143", "46144", "46148", "46151", "46152", "46154", "46160", "46163", "46166", "46170", "46171", "46172", "46173", "46174", "46175", "46176", "46179", "46183", "46184", "46189", "46190", "46192", "46194", "46195", "46197", "46198", "46201", "46206", "46207", "46208", "46209", "46210", "46211", "46213", "46214", "46215", "46218", "46222", "46226", "46229", "46231", "46232", "46237", "46239", "46240", "46241", "46242", "46244", "46245", "46250", "46251", "46252", "46256", "46257", "46258", "46261", "46262", "46264", "46266", "46267", "46268", "46269", "46271", "46273", "46276", "46278", "46280", "46281", "46282", "46283", "46284", "46285", "46287", "46288", "46291", "46294", "46296", "46297", "46298", "46299", "46300", "46301", "46303", "46304", "46309", "46310", "46321", "46322", "46323", "46324", "46325", "46328", "46330", "46332", "46334", "46337", "46342", "46344", "46345", "46346", "46347", "46350", "46351", "46354", "46357", "46362", "46363", "46366", "46367", "46369", "46374", "46376", "46377", "46378", "46379", "46382", "46383", "46386", "46387", "46388", "46389", "46390", "46391", "46392", "46394", "46396", "46399", "46400", "46405", "46406", "46408", "46410", "46412", "46413", "46414", "46415", "46419", "46421", "46423", "46425", "46428", "46429", "46433", "46434", "46435", "46439", "46440", "46442", "46444", "46445", "46448", "46455", "46459", "46460", "46463", "46464", "46466", "46467", "46468", "46469", "46471", "46473", "46475", "46478", "46479", "46484", "46485", "46486", "46487", "46488", "46490", "46491", "46492", "46493", "46495", "46497", "46499", "46501", "46502", "46505", "46511", "46512", "46513", "46514", "46517", "46518", "46519", "46520", "46526", "46527", "46529", "46536", "46538", "46544", "46545", "46546", "46550", "46554", "46556", "46558", "46560", "46561", "46564", "46568", "46570", "46571", "46572", "46573", "46576", "46578", "46579", "46580", "46581", "46582", "46583", "46584", "46588", "46591", "46592", "46595", "46596", "46597", "46599", "46600", "46603", "46604", "46605", "46607", "46609", "46611", "46614", "46625", "46626", "46627", "46628", "46629", "46630", "46633", "46634", "46635", "46636", "46637", "46639", "46640", "46642", "46644", "46646", "46647", "46648", "46649", "46652", "46656", "46657", "46659", "46660", "46662", "46664", "46665", "46666", "46667", "46668", "46670", "46672", "46673", "46677", "46680", "46682", "46687", "46688", "46689", "46690", "46691", "46692", "46693", "46696", "46697", "46698", "46701", "46702", "46704", "46706", "46708", "46709", "46711", "46714", "46715", "46716", "46717", "46718", "46719", "46721", "46722", "46724", "46725", "46726", "46727", "46729", "46730", "46732", "46733", "46735", "46736", "46737", "46738", "46740", "46741", "46743", "46744", "46745", "46746", "46749", "46752", "46754", "46759", "46760", "46762", "46765", "46766", "46770", "46771", "46773", "46774", "46776", "46777", "46779", "46781", "46782", "46787", "46788", "46791", "46793", "46796", "46797", "46799", "46802", "46803", "46805", "46806", "46808", "46809", "46811", "46812", "46815", "46816", "46817", "46818", "46823", "46825", "46829", "46833", "46834", "46837", "46845", "46846", "46850", "46851", "46852", "46853", "46857", "46859", "46860", "46861", "46862", "46865", "46866", "46867", "46871", "46874", "46875", "46877", "46878", "46879", "46883", "46885", "46892", "46894", "46895", "46897", "46898", "46900", "46901", "46904", "46905", "46909", "46910", "46911", "46914", "46916", "46918", "46925", "46928", "46929", "46934", "46936", "46939", "46940", "46943", "46945", "46946", "46948", "46949", "46952", "46953", "46958", "46959", "46961", "46962", "46964", "46965", "46969", "46970", "46973", "46974", "46976", "46977", "46980", "46981", "46982", "46984", "46985", "46986", "46987", "46990", "46992", "46993", "46994", "46995", "46998", "46999", "47000", "47003", "47005", "47006", "47010", "47013", "47018", "47020", "47022", "47023", "47024", "47025", "47026", "47028", "47031", "47032", "47033", "47036", "47038", "47039", "47041", "47045", "47046", "47048", "47049", "47050", "47054", "47056", "47057", "47058", "47059", "47060", "47061", "47062", "47065", "47067", "47072", "47073", "47074", "47077", "47080", "47082", "47083", "47087", "47089", "47090", "47091", "47094", "47097", "47098", "47101", "47103", "47104", "47106", "47110", "47111", "47112", "47114", "47115", "47116", "47117", "47118", "47122", "47123", "47126", "47129", "47132", "47134", "47136", "47137", "47141", "47142", "47143", "47146", "47148", "47151", "47153", "47154", "47159", "47160", "47161", "47162", "47167", "47174", "47175", "47176", "47180", "47181", "47182", "47183", "47187", "47189", "47191", "47192", "47194", "47195", "47197", "47202", "47203", "47204", "47206", "47207", "47208", "47209", "47210", "47211", "47212", "47215", "47216", "47217", "47218", "47220", "47223", "47224", "47225", "47228", "47229", "47232", "47235", "47236", "47237", "47241", "47248", "47249", "47251", "47252", "47253", "47254", "47255", "47256", "47259", "47260", "47262", "47263", "47264", "47265", "47266", "47267", "47268", "47270", "47274", "47275", "47276", "47277", "47278", "47280", "47281", "47283", "47284", "47286", "47289", "47292", "47294", "47295", "47296", "47301", "47302", "47303", "47304", "47307", "47308", "47310", "47313", "47316", "47318", "47319", "47322", "47323", "47324", "47326", "47327", "47328", "47332", "47335", "47337", "47339", "47347", "47350", "47351", "47352", "47357", "47358", "47361", "47365", "47366", "47367", "47374", "47376", "47377", "47381", "47382", "47383", "47387", "47389", "47393", "47394", "47398", "47399", "47400", "47405", "47406", "47409", "47412", "47413", "47414", "47415", "47416", "47417", "47421", "47423", "47424", "47428", "47429", "47430", "47431", "47432", "47434", "47435", "47439", "47441", "47444", "47445", "47448", "47452", "47453", "47454", "47455", "47459", "47461", "47462", "47463", "47464", "47465", "47466", "47468", "47469", "47471", "47472", "47474", "47475", "47479", "47480", "47481", "47482", "47483", "47485", "47486", "47487", "47490", "47492", "47493", "47494", "47497", "47498", "47499", "47500", "47501", "47504", "47505", "47506", "47508", "47512", "47513", "47517", "47518", "47521", "47522", "47527", "47529", "47530", "47532", "47533", "47534", "47538", "47542", "47547", "47552", "47553", "47556", "47557", "47561", "47565", "47570", "47571", "47574", "47575", "47576", "47577", "47578", "47580", "47584", "47585", "47586", "47588", "47590", "47591", "47592", "47594", "47596", "47600", "47601", "47602", "47603", "47607", "47612", "47613", "47616", "47617", "47619", "47621", "47622", "47623", "47628", "47629", "47630", "47631", "47633", "47636", "47638", "47640", "47641", "47642", "47643", "47644", "47648", "47650", "47652", "47653", "47655", "47656", "47661", "47663", "47667", "47668", "47670", "47671", "47672", "47673", "47675", "47676", "47677", "47679", "47681", "47683", "47684", "47685", "47686", "47690", "47691", "47692", "47696", "47697", "47703", "47705", "47706", "47707", "47710", "47711", "47713", "47714", "47716", "47718", "47720", "47721", "47724", "47725", "47726", "47727", "47728", "47729", "47730", "47732", "47734", "47740", "47741", "47744", "47747", "47749", "47750", "47751", "47752", "47753", "47754", "47757", "47758", "47760", "47764", "47766", "47768", "47769", "47779", "47780", "47781", "47782", "47783", "47784", "47785", "47793", "47794", "47796", "47798", "47799", "47801", "47803", "47805", "47806", "47809", "47811", "47812", "47813", "47814", "47815", "47816", "47817", "47818", "47820", "47822", "47823", "47824", "47830", "47831", "47832", "47833", "47837", "47838", "47841", "47842", "47843", "47844", "47845", "47846", "47847", "47848", "47849", "47850", "47851", "47852", "47853", "47854", "47857", "47858", "47860", "47863", "47864", "47866", "47872", "47873", "47876", "47879", "47880", "47885", "47886", "47888", "47894", "47897", "47898", "47899", "47903", "47904", "47907", "47908", "47909", "47910", "47911", "47912", "47913", "47914", "47917", "47918", "47922", "47926", "47927", "47930", "47931", "47932", "47936", "47937", "47939", "47940", "47942", "47946", "47947", "47949", "47953", "47960", "47961", "47963", "47964", "47965", "47966", "47967", "47968", "47969", "47972", "47974", "47977", "47978", "47981", "47983", "47990", "47991", "47992", "47993", "47994", "47995", "47997", "48001", "48002", "48004", "48005", "48008", "48009", "48010", "48012", "48013", "48019", "48023", "48028", "48030", "48034", "48037", "48038", "48039", "48040", "48044", "48047", "48049", "48052", "48053", "48054", "48055", "48056", "48057", "48059", "48060", "48061", "48062", "48068", "48069", "48070", "48072", "48075", "48078", "48079", "48083", "48084", "48086", "48087", "48088", "48091", "48092", "48093", "48094", "48095", "48100", "48101", "48103", "48105", "48110", "48112", "48113", "48114", "48115", "48116", "48120", "48122", "48124", "48126", "48128", "48129", "48130", "48132", "48133", "48135", "48136", "48138", "48140", "48141", "48144", "48146", "48148", "48151", "48153", "48154", "48156", "48157", "48158", "48161", "48162", "48163", "48164", "48165", "48166", "48167", "48170", "48175", "48177", "48178", "48179", "48181", "48183", "48187", "48194", "48195", "48197", "48200", "48201", "48202", "48203", "48205", "48206", "48207", "48209", "48210", "48214", "48216", "48219", "48223", "48225", "48226", "48227", "48228", "48230", "48231", "48233", "48237", "48241", "48243", "48244", "48245", "48246", "48251", "48252", "48253", "48255", "48258", "48259", "48261", "48262", "48264", "48266", "48269", "48271", "48272", "48273", "48274", "48276", "48277", "48280", "48282", "48285", "48288", "48289", "48291", "48292", "48295", "48296", "48298", "48299", "48300", "48302", "48305", "48306", "48308", "48311", "48313", "48314", "48315", "48317", "48319", "48320", "48325", "48326", "48328", "48330", "48331", "48332", "48333", "48335", "48337", "48339", "48340", "48342", "48346", "48348", "48349", "48350", "48351", "48352", "48353", "48354", "48355", "48356", "48357", "48358", "48359", "48361", "48368", "48369", "48370", "48371", "48372", "48373", "48374", "48378", "48380", "48382", "48383", "48388", "48389", "48395", "48396", "48400", "48401", "48404", "48406", "48408", "48409", "48412", "48413", "48416", "48419", "48420", "48421", "48429", "48430", "48431", "48432", "48436", "48437", "48439", "48441", "48442", "48444", "48448", "48450", "48451", "48452", "48453", "48454", "48456", "48458", "48459", "48462", "48464", "48466", "48470", "48472", "48475", "48476", "48477", "48479", "48480", "48481", "48482", "48484", "48486", "48489", "48495", "48496", "48499", "48500", "48501", "48502", "48504", "48506", "48508", "48509", "48511", "48513", "48515", "48516", "48518", "48519", "48522", "48523", "48524", "48526", "48528", "48529", "48531", "48532", "48533", "48534", "48535", "48536", "48537", "48538", "48539", "48540", "48541", "48542", "48543", "48546", "48551", "48553", "48556", "48559", "48566", "48567", "48568", "48570", "48572", "48573", "48574", "48575", "48576", "48577", "48578", "48581", "48582", "48584", "48585", "48590", "48591", "48593", "48595", "48596", "48598", "48601", "48602", "48605", "48606", "48608", "48609", "48610", "48611", "48612", "48613", "48614", "48616", "48619", "48622", "48623", "48628", "48629", "48632", "48634", "48637", "48640", "48641", "48643", "48645", "48647", "48652", "48654", "48655", "48657", "48658", "48661", "48663", "48666", "48667", "48672", "48678", "48680", "48687", "48689", "48691", "48692", "48693", "48695", "48704", "48707", "48713", "48715", "48716", "48717", "48719", "48721", "48722", "48723", "48725", "48726", "48727", "48728", "48729", "48731", "48734", "48740", "48742", "48744", "48745", "48747", "48748", "48749", "48751", "48752", "48755", "48760", "48761", "48762", "48763", "48766", "48767", "48768", "48769", "48770", "48771", "48777", "48780", "48781", "48782", "48783", "48784", "48786", "48787", "48789", "48793", "48795", "48796", "48799", "48805", "48806", "48807", "48808", "48809", "48810", "48811", "48812", "48813", "48815", "48816", "48819", "48822", "48825", "48827", "48829", "48830", "48831", "48832", "48833", "48834", "48836", "48838", "48839", "48845", "48846", "48848", "48849", "48850", "48852", "48856", "48858", "48864", "48865", "48866", "48868", "48869", "48870", "48874", "48876", "48882", "48885", "48889", "48892", "48894", "48896", "48899", "48902", "48903", "48908", "48910", "48912", "48914", "48916", "48917", "48918", "48920", "48922", "48923", "48924", "48926", "48928", "48930", "48932", "48933", "48935", "48937", "48938", "48939", "48940", "48943", "48945", "48948", "48951", "48952", "48954", "48956", "48958", "48960", "48963", "48965", "48966", "48968", "48971", "48975", "48977", "48978", "48981", "48982", "48986", "48987", "48988", "48991", "48993", "48999", "49002", "49003", "49007", "49012", "49015", "49016", "49017", "49018", "49021", "49028", "49031", "49032", "49033", "49040", "49041", "49046", "49048", "49053", "49055", "49057", "49058", "49062", "49063", "49064", "49066", "49071", "49072", "49073", "49079", "49083", "49084", "49085", "49086", "49087", "49088", "49090", "49094", "49097", "49100", "49105", "49107", "49110", "49111", "49112", "49113", "49116", "49117", "49121", "49124", "49131", "49134", "49135", "49136", "49138", "49140", "49142", "49144", "49147", "49153", "49156", "49157", "49160", "49162", "49165", "49170", "49171", "49173", "49174", "49175", "49177", "49178", "49183", "49187", "49188", "49189", "49191", "49192", "49193", "49194", "49195", "49198", "49200", "49201", "49204", "49205", "49207", "49216", "49217", "49219", "49222", "49224", "49225", "49227", "49228", "49230", "49232", "49233", "49234", "49236", "49238", "49240", "49241", "49242", "49243", "49244", "49245", "49248", "49250", "49252", "49254", "49256", "49258", "49261", "49262", "49263", "49264", "49265", "49266", "49267", "49268", "49269", "49271", "49272", "49273", "49274", "49275", "49280", "49282", "49283", "49284", "49285", "49286", "49289", "49291", "49293", "49295", "49298", "49299", "49301", "49303", "49304", "49305", "49306", "49309", "49311", "49312", "49314", "49315", "49317", "49318", "49319", "49321", "49322", "49323", "49324", "49325", "49326", "49330", "49331", "49333", "49335", "49338", "49339", "49343", "49344", "49345", "49349", "49351", "49353", "49355", "49361", "49363", "49367", "49369", "49371", "49373", "49374", "49376", "49378", "49380", "49381", "49383", "49389", "49392", "49393", "49394", "49398", "49400", "49402", "49409", "49410", "49411", "49413", "49414", "49416", "49417", "49422", "49423", "49427", "49433", "49434", "49436", "49437", "49439", "49440", "49441", "49442", "49443", "49445", "49447", "49448", "49449", "49452", "49455", "49456", "49462", "49465", "49468", "49471", "49472", "49477", "49478", "49479", "49484", "49486", "49492", "49494", "49495", "49496", "49497", "49500", "49503", "49504", "49506", "49509", "49515", "49516", "49518", "49520", "49524", "49526", "49527", "49528", "49529", "49532", "49536", "49538", "49539", "49543", "49544", "49545", "49546", "49547", "49548", "49551", "49552", "49556", "49557", "49558", "49559", "49560", "49561", "49564", "49565", "49568", "49571", "49577", "49581", "49584", "49586", "49588", "49589", "49590", "49592", "49593", "49596", "49597", "49598", "49600", "49604", "49605", "49606", "49608", "49609", "49611", "49614", "49615", "49616", "49618", "49620", "49621", "49622", "49624", "49625", "49627", "49628", "49629", "49630", "49632", "49633", "49636", "49637", "49641", "49642", "49643", "49644", "49645", "49646", "49647", "49654", "49657", "49662", "49666", "49667", "49669", "49670", "49671", "49672", "49673", "49674", "49677", "49679", "49680", "49683", "49686", "49687", "49689", "49690", "49691", "49692", "49694", "49695", "49696", "49697", "49699", "49700", "49702", "49703", "49708", "49712", "49714", "49715", "49716", "49719", "49724", "49727", "49732", "49736", "49738", "49739", "49741", "49743", "49744", "49746", "49749", "49753", "49754", "49755", "49756", "49757", "49758", "49764", "49765", "49769", "49775", "49778", "49781", "49783", "49784", "49787", "49788", "49795", "49796", "49799", "49800", "49804", "49807", "49809", "49810", "49811", "49812", "49813", "49814", "49815", "49816", "49818", "49821", "49825", "49828", "49831", "49832", "49835", "49839", "49840", "49841", "49842", "49843", "49845", "49846", "49849", "49850", "49853", "49857", "49860", "49861", "49864", "49866", "49868", "49870", "49872", "49875", "49876", "49878", "49879", "49881", "49882", "49885", "49887", "49889", "49890", "49891", "49893", "49897", "49898", "49901", "49905", "49906", "49907", "49908", "49912", "49915", "49916", "49918", "49919", "49921", "49923", "49924", "49925", "49928", "49929", "49933", "49935", "49936", "49939", "49941", "49944", "49947", "49948", "49949", "49953", "49954", "49956", "49957", "49958", "49962", "49963", "49964", "49966", "49967", "49968", "49969", "49972", "49975", "49979", "49980", "49985", "49986", "49987", "49988", "49989", "49991", "49993", "49994", "49995", "49998", "50000", "50002", "50005", "50007", "50008", "50011", "50015", "50018", "50022", "50029", "50032", "50033", "50034", "50037", "50038", "50039", "50040", "50041", "50042", "50045", "50048", "50050", "50051", "50052", "50053", "50054", "50056", "50057", "50061", "50067", "50069", "50070", "50071", "50077", "50082", "50083", "50084", "50085", "50086", "50087", "50088", "50089", "50092", "50093", "50095", "50097", "50098", "50099", "50100", "50102", "50103", "50105", "50106", "50107", "50108", "50109", "50110", "50111", "50112", "50113", "50115", "50116", "50117", "50118", "50121", "50122", "50124", "50126", "50127", "50128", "50129", "50131", "50133", "50135", "50136", "50137", "50138", "50139", "50143", "50145", "50148", "50149", "50150", "50154", "50157", "50160", "50163", "50168", "50170", "50172", "50173", "50174", "50176", "50182", "50183", "50186", "50187", "50190", "50191", "50193", "50195", "50197", "50202", "50206", "50207", "50211", "50213", "50217", "50218", "50222", "50224", "50226", "50229", "50230", "50231", "50232", "50234", "50236", "50237", "50243", "50247", "50253", "50254", "50258", "50260", "50261", "50262", "50263", "50267", "50268", "50270", "50274", "50277", "50278", "50279", "50280", "50282", "50286", "50288", "50289", "50290", "50291", "50293", "50298", "50303", "50307", "50311", "50312", "50316", "50317", "50320", "50323", "50325", "50329", "50330", "50333", "50335", "50337", "50338", "50340", "50341", "50342", "50344", "50348", "50352", "50354", "50356", "50359", "50360", "50361", "50365", "50367", "50368", "50369", "50370", "50371", "50372", "50378", "50380", "50382", "50384", "50385", "50387", "50389", "50391", "50393", "50395", "50397", "50398", "50399", "50400", "50402", "50403", "50404", "50406", "50407", "50408", "50409", "50411", "50415", "50419", "50424", "50426", "50428", "50431", "50433", "50434", "50435", "50437", "50438", "50439", "50443", "50446", "50454", "50456", "50459", "50461", "50465", "50469", "50471", "50475", "50477", "50478", "50480", "50482", "50483", "50485", "50487", "50491", "50492", "50494", "50499", "50501", "50502", "50503", "50504", "50506", "50507", "50509", "50510", "50511", "50513", "50514", "50515", "50516", "50517", "50524", "50525", "50526", "50527", "50528", "50529", "50530", "50533", "50535", "50538", "50540", "50541", "50542", "50543", "50545", "50546", "50547", "50549", "50550", "50551", "50552", "50553", "50554", "50556", "50557", "50558", "50560", "50561", "50562", "50563", "50564", "50565", "50566", "50567", "50570", "50571", "50572", "50575", "50577", "50578", "50584", "50587", "50590", "50591", "50592", "50596", "50597", "50598", "50599", "50602", "50605", "50607", "50608", "50609", "50610", "50615", "50617", "50618", "50619", "50620", "50621", "50624", "50625", "50626", "50630", "50632", "50636", "50642", "50643", "50644", "50646", "50647", "50648", "50650", "50651", "50654", "50655", "50661", "50664", "50667", "50669", "50671", "50675", "50679", "50680", "50682", "50683", "50688", "50689", "50691", "50692", "50693", "50694", "50695", "50697", "50700", "50706", "50708", "50709", "50710", "50712", "50713", "50714", "50715", "50716", "50719", "50721", "50726", "50728", "50731", "50732", "50733", "50734", "50739", "50741", "50745", "50746", "50748", "50754", "50757", "50758", "50761", "50763", "50766", "50767", "50768", "50773", "50774", "50775", "50781", "50782", "50784", "50787", "50789", "50790", "50791", "50793", "50795", "50796", "50798", "50799", "50802", "50804", "50806", "50807", "50808", "50810", "50812", "50813", "50814", "50815", "50817", "50822", "50823", "50826", "50828", "50830", "50833", "50840", "50841", "50842", "50845", "50850", "50852", "50853", "50854", "50855", "50861", "50863", "50865", "50867", "50868", "50869", "50871", "50872", "50874", "50878", "50880", "50881", "50882", "50885", "50886", "50888", "50892", "50893", "50895", "50897", "50899", "50901", "50902", "50905", "50906", "50907", "50910", "50911", "50914", "50916", "50917", "50918", "50920", "50921", "50923", "50924", "50925", "50926", "50927", "50928", "50931", "50932", "50934", "50936", "50939", "50941", "50942", "50950", "50952", "50953", "50955", "50960", "50961", "50964", "50965", "50968", "50969", "50970", "50971", "50975", "50976", "50979", "50981", "50984", "50986", "50987", "50988", "50991", "50992", "50993", "50994", "50996", "50997", "51000", "51003", "51004", "51009", "51010", "51011", "51013", "51014", "51021", "51023", "51024", "51031", "51032", "51035", "51037", "51038", "51039", "51040", "51042", "51045", "51047", "51048", "51049", "51051", "51053", "51055", "51057", "51058", "51060", "51063", "51065", "51070", "51073", "51074", "51075", "51076", "51078", "51079", "51082", "51083", "51084", "51086", "51087", "51089", "51090", "51092", "51094", "51096", "51097", "51104", "51106", "51107", "51110", "51114", "51115", "51119", "51123", "51124", "51125", "51127", "51128", "51131", "51132", "51139", "51142", "51145", "51146", "51147", "51149", "51150", "51152", "51154", "51155", "51156", "51157", "51159", "51162", "51163", "51166", "51167", "51168", "51171", "51172", "51175", "51178", "51180", "51181", "51185", "51186", "51188", "51191", "51193", "51194", "51199", "51205", "51207", "51209", "51210", "51215", "51218", "51221", "51223", "51225", "51226", "51227", "51230", "51232", "51235", "51237", "51239", "51240", "51244", "51245", "51246", "51250", "51251", "51255", "51257", "51259", "51261", "51264", "51268", "51270", "51271", "51277", "51278", "51279", "51280", "51285", "51286", "51289", "51290", "51291", "51292", "51294", "51295", "51296", "51298", "51299", "51300", "51305", "51307", "51310", "51311", "51312", "51313", "51314", "51315", "51316", "51317", "51318", "51320", "51321", "51322", "51323", "51328", "51330", "51332", "51333", "51335", "51336", "51340", "51343", "51344", "51345", "51347", "51350", "51351", "51352", "51353", "51354", "51357", "51359", "51360", "51361", "51362", "51365", "51366", "51368", "51373", "51378", "51388", "51389", "51393", "51394", "51395", "51397", "51398", "51399", "51400", "51401", "51402", "51403", "51404", "51405", "51406", "51407", "51410", "51411", "51413", "51414", "51416", "51418", "51420", "51425", "51430", "51433", "51434", "51435", "51436", "51438", "51440", "51442", "51444", "51447", "51450", "51453", "51455", "51464", "51465", "51467", "51468", "51469", "51471", "51472", "51473", "51476", "51478", "51479", "51482", "51484", "51487", "51489", "51492", "51495", "51496", "51497", "51498", "51499", "51503", "51505", "51506", "51507", "51508", "51511", "51513", "51516", "51517", "51518", "51521", "51522", "51523", "51524", "51525", "51526", "51529", "51531", "51532", "51534", "51538", "51539", "51541", "51546", "51547", "51549", "51556", "51557", "51560", "51564", "51565", "51569", "51571", "51574", "51577", "51582", "51583", "51585", "51586", "51587", "51589", "51592", "51593", "51596", "51598", "51599", "51600", "51602", "51605", "51606", "51608", "51609", "51610", "51612", "51616", "51617", "51618", "51619", "51620", "51622", "51623", "51624", "51626", "51628", "51630", "51631", "51635", "51636", "51637", "51639", "51641", "51642", "51643", "51644", "51645", "51646", "51647", "51652", "51654", "51656", "51658", "51660", "51661", "51663", "51664", "51669", "51670", "51672", "51673", "51675", "51679", "51680", "51684", "51685", "51690", "51692", "51695", "51698", "51702", "51704", "51705", "51706", "51708", "51709", "51710", "51712", "51714", "51716", "51717", "51721", "51723", "51724", "51727", "51728", "51729", "51730", "51732", "51733", "51734", "51735", "51737", "51738", "51739", "51740", "51741", "51742", "51744", "51748", "51755", "51756", "51760", "51761", "51762", "51763", "51769", "51770", "51771", "51772", "51774", "51779", "51780", "51785", "51786", "51787", "51788", "51790", "51792", "51795", "51796", "51799", "51801", "51802", "51805", "51806", "51808", "51809", "51810", "51813", "51817", "51820", "51822", "51823", "51827", "51830", "51832", "51834", "51838", "51841", "51843", "51844", "51845", "51847", "51848", "51850", "51851", "51852", "51854", "51858", "51859", "51862", "51863", "51864", "51865", "51867", "51873", "51874", "51879", "51880", "51883", "51886", "51889", "51890", "51892", "51893", "51896", "51897", "51899", "51900", "51905", "51906", "51907", "51911", "51912", "51913", "51914", "51916", "51917", "51918", "51920", "51923", "51924", "51925", "51927", "51932", "51934", "51935", "51942", "51944", "51945", "51947", "51948", "51949", "51950", "51953", "51954", "51955", "51956", "51959", "51960", "51962", "51964", "51966", "51967", "51968", "51969", "51970", "51971", "51972", "51973", "51974", "51975", "51977", "51982", "51983", "51984", "51985", "51986", "51987", "51990", "51996", "52001", "52002", "52003", "52004", "52005", "52006", "52008", "52009", "52010", "52011", "52016", "52017", "52020", "52021", "52022", "52023", "52024", "52025", "52026", "52027", "52030", "52032", "52033", "52040", "52045", "52046", "52049", "52054", "52055", "52057", "52058", "52059", "52060", "52061", "52064", "52065", "52066", "52067", "52068", "52071", "52073", "52074", "52075", "52077", "52078", "52083", "52088", "52089", "52096", "52099", "52100", "52103", "52104", "52105", "52112", "52113", "52114", "52116", "52117", "52119", "52121", "52123", "52124", "52126", "52127", "52131", "52132", "52133", "52138", "52141", "52143", "52147", "52148", "52149", "52151", "52152", "52155", "52156", "52158", "52159", "52160", "52161", "52162", "52163", "52166", "52168", "52170", "52171", "52172", "52173", "52175", "52177", "52178", "52179", "52180", "52182", "52183", "52184", "52187", "52188", "52191", "52192", "52199", "52202", "52203", "52207", "52210", "52212", "52213", "52216", "52220", "52221", "52223", "52225", "52226", "52227", "52229", "52231", "52233", "52237", "52238", "52239", "52240", "52241", "52245", "52246", "52248", "52249", "52250", "52251", "52252", "52253", "52254", "52256", "52262", "52264", "52267", "52271", "52273", "52274", "52276", "52278", "52280", "52281", "52282", "52283", "52286", "52287", "52289", "52291", "52292", "52295", "52300", "52303", "52307", "52308", "52310", "52311", "52313", "52314", "52315", "52320", "52322", "52326", "52328", "52332", "52334", "52337", "52340", "52342", "52343", "52345", "52346", "52349", "52350", "52351", "52355", "52361", "52363", "52366", "52368", "52370", "52371", "52373", "52377", "52379", "52381", "52382", "52383", "52385", "52386", "52387", "52392", "52394", "52395", "52398", "52399", "52400", "52401", "52403", "52408", "52410", "52412", "52413", "52415", "52416", "52417", "52418", "52421", "52422", "52424", "52426", "52429", "52431", "52435", "52437", "52439", "52440", "52441", "52442", "52443", "52444", "52445", "52446", "52447", "52451", "52452", "52454", "52457", "52458", "52467", "52469", "52472", "52473", "52475", "52477", "52480", "52482", "52483", "52485", "52486", "52488", "52490", "52491", "52492", "52493", "52494", "52499", "52502", "52503", "52504", "52505", "52507", "52509", "52510", "52512", "52515", "52518", "52520", "52521", "52522", "52524", "52526", "52528", "52530", "52532", "52534", "52537", "52538", "52540", "52541", "52543", "52544", "52547", "52548", "52553", "52559", "52563", "52565", "52567", "52573", "52576", "52579", "52583", "52585", "52589", "52590", "52592", "52594", "52601", "52602", "52603", "52606", "52609", "52611", "52612", "52615", "52616", "52617", "52618", "52622", "52623", "52625", "52626", "52627", "52629", "52631", "52635", "52636", "52637", "52638", "52641", "52642", "52644", "52646", "52647", "52648", "52650", "52652", "52653", "52655", "52656", "52657", "52658", "52659", "52662", "52663", "52665", "52666", "52669", "52670", "52671", "52672", "52676", "52677", "52680", "52681", "52683", "52684", "52687", "52688", "52689", "52690", "52699", "52700", "52703", "52705", "52708", "52711", "52713", "52717", "52718", "52720", "52722", "52723", "52725", "52727", "52729", "52730", "52731", "52734", "52735", "52736", "52737", "52740", "52742", "52743", "52744", "52745", "52748", "52749", "52750", "52754", "52755", "52757", "52758", "52759", "52761", "52763", "52768", "52769", "52772", "52775", "52777", "52779", "52780", "52783", "52784", "52785", "52787", "52789", "52790", "52791", "52793", "52801", "52804", "52805", "52806", "52807", "52809", "52812", "52816", "52820", "52821", "52822", "52833", "52834", "52835", "52836", "52837", "52838", "52840", "52841", "52843", "52845", "52847", "52849", "52850", "52852", "52853", "52855", "52856", "52857", "52859", "52860", "52864", "52865", "52868", "52873", "52874", "52878", "52879", "52881", "52885", "52887", "52889", "52894", "52896", "52898", "52904", "52907", "52908", "52909", "52911", "52915", "52916", "52919", "52921", "52922", "52923", "52927", "52932", "52936", "52937", "52938", "52939", "52940", "52943", "52944", "52948", "52949", "52954", "52956", "52959", "52960", "52961", "52966", "52967", "52968", "52969", "52971", "52972", "52974", "52977", "52978", "52979", "52983", "52987", "52989", "52990", "52991", "52996", "52997", "53001", "53002", "53004", "53005", "53006", "53007", "53009", "53011", "53012", "53017", "53018", "53021", "53026", "53028", "53029", "53032", "53034", "53036", "53038", "53039", "53040", "53043", "53045", "53047", "53051", "53052", "53053", "53055", "53058", "53060", "53062", "53066", "53067", "53068", "53069", "53070", "53071", "53072", "53073", "53074", "53079", "53080", "53081", "53084", "53085", "53087", "53090", "53091", "53092", "53097", "53100", "53104", "53105", "53106", "53107", "53110", "53111", "53112", "53114", "53115", "53116", "53119", "53120", "53121", "53122", "53123", "53125", "53126", "53128", "53129", "53130", "53132", "53134", "53136", "53137", "53139", "53142", "53143", "53144", "53145", "53146", "53151", "53152", "53153", "53154", "53155", "53156", "53157", "53158", "53159", "53160", "53161", "53162", "53163", "53164", "53165", "53166", "53167", "53168", "53177", "53179", "53180", "53181", "53182", "53183", "53190", "53192", "53194", "53196", "53198", "53199", "53200", "53202", "53203", "53204", "53206", "53207", "53208", "53209", "53212", "53215", "53219", "53220", "53223", "53227", "53229", "53230", "53233", "53238", "53239", "53240", "53241", "53242", "53243", "53244", "53246", "53250", "53253", "53254", "53255", "53256", "53257", "53259", "53260", "53263", "53266", "53268", "53269", "53274", "53275", "53278", "53279", "53287", "53288", "53291", "53293", "53295", "53296", "53297", "53298", "53299", "53301", "53302", "53306", "53308", "53311", "53312", "53313", "53314", "53317", "53322", "53323", "53324", "53326", "53328", "53330", "53333", "53336", "53339", "53342", "53344", "53347", "53348", "53349", "53351", "53352", "53355", "53357", "53358", "53359", "53361", "53364", "53365", "53370", "53372", "53375", "53378", "53379", "53382", "53383", "53385", "53388", "53391", "53397", "53398", "53401", "53403", "53404", "53405", "53406", "53410", "53412", "53414", "53415", "53417", "53418", "53421", "53422", "53423", "53425", "53426", "53428", "53430", "53431", "53432", "53435", "53437", "53440", "53441", "53443", "53445", "53450", "53454", "53455", "53456", "53457", "53461", "53462", "53465", "53468", "53469", "53470", "53471", "53472", "53474", "53475", "53478", "53479", "53480", "53481", "53498", "53501", "53502", "53504", "53505", "53506", "53508", "53509", "53514", "53517", "53518", "53522", "53523", "53525", "53528", "53529", "53532", "53534", "53535", "53536", "53540", "53542", "53545", "53546", "53548", "53549", "53550", "53557", "53561", "53562", "53565", "53568", "53569", "53571", "53573", "53575", "53576", "53577", "53578", "53580", "53581", "53584", "53586", "53587", "53588", "53589", "53590", "53594", "53596", "53597", "53598", "53604", "53612", "53614", "53615", "53616", "53617", "53618", "53622", "53624", "53626", "53629", "53631", "53632", "53633", "53635", "53636", "53637", "53643", "53644", "53646", "53647", "53650", "53653", "53654", "53655", "53657", "53662", "53664", "53668", "53671", "53674", "53675", "53677", "53678", "53679", "53680", "53681", "53685", "53686", "53687", "53693", "53694", "53695", "53697", "53698", "53704", "53705", "53708", "53710", "53712", "53714", "53715", "53716", "53717", "53722", "53723", "53724", "53726", "53727", "53728", "53731", "53737", "53738", "53740", "53746", "53748", "53750", "53753", "53754", "53755", "53757", "53758", "53759", "53760", "53762", "53764", "53768", "53771", "53773", "53774", "53777", "53780", "53781", "53782", "53785", "53786", "53789", "53790", "53792", "53794", "53795", "53796", "53797", "53798", "53801", "53807", "53808", "53809", "53810", "53814", "53818", "53819", "53820", "53822", "53823", "53825", "53830", "53834", "53835", "53836", "53837", "53839", "53840", "53841", "53842", "53846", "53847", "53848", "53849", "53853", "53854", "53855", "53856", "53857", "53858", "53859", "53860", "53865", "53867", "53868", "53869", "53870", "53871", "53872", "53873", "53874", "53877", "53878", "53879", "53882", "53884", "53890", "53896", "53897", "53900", "53902", "53903", "53904", "53905", "53907", "53911", "53913", "53916", "53917", "53919", "53922", "53923", "53924", "53925", "53927", "53929", "53931", "53932", "53934", "53936", "53946", "53947", "53948", "53951", "53955", "53956", "53961", "53962", "53964", "53965", "53966", "53968", "53971", "53975", "53977", "53982", "53983", "53984", "53985", "53986", "53988", "53989", "53991", "53992", "53995", "53996", "54001", "54003", "54009", "54011", "54014", "54021", "54024", "54027", "54028", "54029", "54030", "54032", "54034", "54035", "54036", "54037", "54039", "54040", "54042", "54043", "54045", "54050", "54052", "54055", "54056", "54058", "54059", "54060", "54063", "54065", "54066", "54069", "54073", "54075", "54077", "54078", "54079", "54084", "54085", "54086", "54087", "54090", "54091", "54099", "54100", "54106", "54107", "54108", "54109", "54111", "54119", "54126", "54127", "54133", "54134", "54137", "54139", "54141", "54142", "54144", "54145", "54147", "54150", "54151", "54153", "54157", "54159", "54160", "54162", "54164", "54165", "54167", "54169", "54170", "54179", "54182", "54183", "54184", "54188", "54189", "54190", "54191", "54192", "54193", "54195", "54197", "54198", "54200", "54202", "54205", "54207", "54209", "54213", "54217", "54218", "54219", "54220", "54221", "54223", "54225", "54228", "54231", "54234", "54236", "54237", "54239", "54242", "54244", "54245", "54246", "54248", "54249", "54251", "54255", "54258", "54262", "54264", "54265", "54267", "54269", "54270", "54271", "54272", "54273", "54274", "54275", "54276", "54277", "54281", "54286", "54287", "54289", "54294", "54295", "54297", "54300", "54302", "54303", "54304", "54305", "54306", "54307", "54308", "54311", "54312", "54315", "54317", "54318", "54319", "54321", "54323", "54325", "54326", "54331", "54333", "54334", "54335", "54336", "54340", "54341", "54342", "54343", "54344", "54345", "54347", "54349", "54350", "54351", "54352", "54356", "54358", "54360", "54361", "54363", "54369", "54373", "54379", "54382", "54385", "54386", "54389", "54392", "54393", "54397", "54399", "54400", "54401", "54402", "54403", "54404", "54406", "54407", "54408", "54410", "54412", "54415", "54416", "54421", "54422", "54423", "54425", "54426", "54428", "54430", "54433", "54440", "54441", "54442", "54443", "54445", "54449", "54450", "54454", "54455", "54456", "54457", "54460", "54461", "54462", "54463", "54464", "54468", "54469", "54472", "54473", "54474", "54476", "54478", "54486", "54488", "54491", "54493", "54494", "54496", "54497", "54498", "54499", "54501", "54502", "54504", "54505", "54506", "54509", "54512", "54513", "54514", "54517", "54519", "54527", "54530", "54531", "54533", "54534", "54535", "54537", "54538", "54539", "54541", "54543", "54545", "54552", "54553", "54554", "54555", "54557", "54558", "54559", "54561", "54562", "54563", "54565", "54566", "54568", "54570", "54571", "54573", "54574", "54575", "54578", "54582", "54583", "54584", "54588", "54589", "54590", "54592", "54593", "54595", "54600", "54601", "54605", "54611", "54613", "54615", "54618", "54623", "54624", "54627", "54629", "54630", "54631", "54632", "54634", "54635", "54636", "54637", "54639", "54640", "54641", "54645", "54646", "54647", "54649", "54651", "54652", "54654", "54655", "54658", "54662", "54665", "54667", "54670", "54673", "54674", "54676", "54677", "54678", "54682", "54683", "54684", "54687", "54689", "54690", "54691", "54692", "54693", "54697", "54698", "54699", "54700", "54704", "54705", "54708", "54710", "54711", "54712", "54717", "54719", "54722", "54724", "54725", "54727", "54728", "54731", "54732", "54737", "54738", "54739", "54741", "54743", "54744", "54745", "54746", "54751", "54753", "54755", "54758", "54760", "54762", "54766", "54769", "54770", "54773", "54775", "54777", "54778", "54781", "54784", "54786", "54788", "54789", "54790", "54793", "54794", "54795", "54796", "54801", "54803", "54805", "54806", "54807", "54809", "54810", "54812", "54813", "54814", "54815", "54817", "54818", "54819", "54821", "54822", "54823", "54824", "54826", "54827", "54829", "54832", "54833", "54835", "54836", "54837", "54838", "54840", "54841", "54842", "54847", "54848", "54849", "54850", "54855", "54857", "54858", "54859", "54864", "54865", "54866", "54867", "54868", "54870", "54871", "54872", "54877", "54881", "54888", "54889", "54893", "54894", "54895", "54896", "54898", "54902", "54903", "54905", "54906", "54907", "54909", "54910", "54911", "54913", "54914", "54917", "54921", "54926", "54927", "54929", "54930", "54936", "54938", "54939", "54940", "54944", "54945", "54947", "54948", "54949", "54950", "54951", "54952", "54955", "54959", "54960", "54961", "54965", "54966", "54967", "54969", "54973", "54976", "54983", "54985", "54986", "54987", "54992", "54994", "54995", "54997", "54998", "55000", "55004", "55006", "55007", "55009", "55010", "55012", "55019", "55020", "55021", "55022", "55023", "55025", "55028", "55029", "55032", "55035", "55036", "55038", "55040", "55044", "55046", "55048", "55051", "55052", "55053", "55054", "55055", "55056", "55057", "55059", "55060", "55061", "55065", "55066", "55067", "55071", "55075", "55076", "55077", "55078", "55084", "55086", "55087", "55089", "55090", "55094", "55095", "55096", "55098", "55100", "55102", "55103", "55104", "55105", "55106", "55107", "55108", "55109", "55111", "55114", "55115", "55116", "55119", "55122", "55123", "55125", "55126", "55129", "55131", "55132", "55134", "55136", "55142", "55143", "55144", "55145", "55146", "55147", "55148", "55150", "55151", "55153", "55154", "55155", "55159", "55161", "55164", "55165", "55167", "55168", "55169", "55170", "55172", "55174", "55183", "55186", "55188", "55191", "55193", "55194", "55197", "55198", "55199", "55200", "55201", "55202", "55204", "55207", "55208", "55211", "55213", "55214", "55217", "55219", "55220", "55222", "55224", "55225", "55226", "55227", "55228", "55230", "55233", "55237", "55242", "55244", "55248", "55252", "55254", "55255", "55257", "55259", "55261", "55264", "55266", "55271", "55272", "55274", "55275", "55276", "55278", "55279", "55280", "55283", "55285", "55286", "55288", "55293", "55297", "55298", "55299", "55301", "55308", "55312", "55313", "55315", "55316", "55319", "55323", "55328", "55329", "55330", "55334", "55335", "55338", "55341", "55342", "55343", "55344", "55347", "55348", "55349", "55350", "55352", "55353", "55354", "55356", "55357", "55358", "55359", "55360", "55361", "55363", "55365", "55368", "55369", "55370", "55371", "55372", "55377", "55378", "55379", "55381", "55384", "55385", "55389", "55391", "55394", "55398", "55401", "55404", "55405", "55406", "55408", "55412", "55413", "55414", "55416", "55417", "55418", "55422", "55425", "55427", "55430", "55431", "55434", "55438", "55440", "55441", "55442", "55444", "55446", "55447", "55448", "55450", "55451", "55452", "55457", "55458", "55462", "55464", "55465", "55468", "55469", "55471", "55474", "55475", "55477", "55479", "55480", "55483", "55487", "55491", "55492", "55494", "55496", "55497", "55499", "55501", "55503", "55504", "55506", "55507", "55513", "55514", "55518", "55519", "55520", "55521", "55524", "55527", "55529", "55530", "55531", "55532", "55533", "55534", "55535", "55536", "55537", "55538", "55539", "55542", "55545", "55546", "55548", "55549", "55550", "55551", "55553", "55554", "55555", "55556", "55559", "55566", "55567", "55568", "55570", "55571", "55572", "55574", "55577", "55580", "55581", "55582", "55583", "55589", "55590", "55591", "55592", "55602", "55604", "55607", "55608", "55610", "55612", "55619", "55620", "55622", "55626", "55629", "55632", "55634", "55639", "55640", "55641", "55642", "55643", "55645", "55646", "55650", "55652", "55653", "55654", "55656", "55657", "55659", "55660", "55661", "55666", "55672", "55673", "55675", "55676", "55677", "55678", "55679", "55682", "55684", "55688", "55692", "55695", "55696", "55698", "55700", "55702", "55703", "55704", "55706", "55707", "55709", "55710", "55711", "55712", "55713", "55714", "55717", "55718", "55721", "55722", "55724", "55728", "55730", "55735", "55736", "55738", "55740", "55745", "55746", "55748", "55749", "55752", "55754", "55755", "55756", "55759", "55760", "55764", "55767", "55774", "55775", "55777", "55780", "55785", "55786", "55789", "55792", "55794", "55796", "55800", "55801", "55803", "55806", "55808", "55809", "55810", "55811", "55813", "55815", "55817", "55818", "55823", "55825", "55826", "55831", "55835", "55836", "55837", "55838", "55840", "55843", "55846", "55848", "55853", "55856", "55857", "55859", "55860", "55863", "55864", "55865", "55866", "55867", "55868", "55870", "55871", "55872", "55873", "55874", "55875", "55878", "55882", "55883", "55884", "55887", "55888", "55889", "55896", "55898", "55899", "55900", "55902", "55903", "55904", "55907", "55909", "55913", "55915", "55916", "55921", "55922", "55923", "55925", "55926", "55928", "55929", "55930", "55931", "55932", "55934", "55937", "55940", "55947", "55951", "55957", "55959", "55962", "55966", "55970", "55974", "55978", "55983", "55984", "55997", "55998", "55999", "56000", "56001", "56002", "56003", "56006", "56007", "56010", "56013", "56014", "56016", "56017", "56019", "56021", "56022", "56023", "56024", "56025", "56026", "56027", "56029", "56031", "56032", "56035", "56036", "56037", "56039", "56040", "56044", "56047", "56048", "56051", "56054", "56055", "56058", "56060", "56061", "56066", "56067", "56068", "56070", "56072", "56073", "56074", "56077", "56080", "56082", "56085", "56086", "56087", "56089", "56092", "56094", "56095", "56096", "56098", "56099", "56101", "56103", "56110", "56111", "56115", "56117", "56122", "56123", "56124", "56126", "56127", "56128", "56130", "56131", "56132", "56134", "56136", "56137", "56138", "56139", "56142", "56144", "56145", "56147", "56149", "56153", "56159", "56163", "56164", "56165", "56166", "56168", "56169", "56171", "56172", "56173", "56176", "56178", "56182", "56183", "56186", "56187", "56192", "56193", "56197", "56199", "56201", "56205", "56209", "56212", "56213", "56216", "56218", "56219", "56221", "56222", "56228", "56234", "56235", "56236", "56238", "56239", "56244", "56246", "56251", "56252", "56253", "56254", "56255", "56256", "56259", "56261", "56262", "56263", "56264", "56265", "56266", "56267", "56270", "56271", "56272", "56275", "56276", "56277", "56278", "56280", "56282", "56285", "56287", "56288", "56293", "56294", "56296", "56297", "56299", "56301", "56303", "56304", "56308", "56309", "56311", "56312", "56313", "56317", "56320", "56321", "56322", "56324", "56325", "56326", "56328", "56334", "56335", "56338", "56339", "56342", "56344", "56346", "56353", "56354", "56355", "56358", "56361", "56362", "56365", "56367", "56371", "56377", "56382", "56383", "56384", "56386", "56394", "56396", "56401", "56404", "56405", "56406", "56407", "56412", "56416", "56417", "56418", "56421", "56422", "56424", "56425", "56427", "56429", "56431", "56434", "56437", "56439", "56440", "56441", "56444", "56445", "56446", "56448", "56450", "56451", "56453", "56454", "56455", "56456", "56458", "56459", "56460", "56461", "56463", "56464", "56465", "56468", "56469", "56470", "56471", "56472", "56473", "56475", "56476", "56477", "56478", "56484", "56485", "56486", "56487", "56488", "56489", "56491", "56494", "56495", "56496", "56498", "56503", "56504", "56510", "56514", "56515", "56516", "56529", "56530", "56531", "56534", "56536", "56538", "56539", "56541", "56542", "56543", "56544", "56545", "56547", "56555", "56557", "56558", "56559", "56560", "56561", "56566", "56568", "56571", "56572", "56574", "56575", "56582", "56586", "56590", "56592", "56593", "56595", "56598", "56603", "56604", "56607", "56609", "56610", "56611", "56615", "56616", "56617", "56620", "56621", "56625", "56629", "56631", "56632", "56634", "56635", "56636", "56637", "56638", "56639", "56640", "56641", "56643", "56645", "56647", "56649", "56650", "56652", "56653", "56654", "56657", "56660", "56661", "56662", "56664", "56666", "56670", "56671", "56673", "56675", "56678", "56679", "56681", "56684", "56685", "56687", "56689", "56690", "56691", "56692", "56694", "56695", "56696", "56697", "56698", "56699", "56700", "56701", "56702", "56707", "56708", "56711", "56713", "56715", "56717", "56721", "56722", "56723", "56724", "56726", "56728", "56731", "56732", "56734", "56736", "56737", "56739", "56740", "56741", "56746", "56748", "56751", "56752", "56753", "56758", "56759", "56760", "56766", "56767", "56768", "56769", "56772", "56773", "56774", "56776", "56777", "56779", "56780", "56781", "56782", "56783", "56787", "56788", "56789", "56790", "56794", "56795", "56798", "56799", "56801", "56806", "56808", "56809", "56810", "56811", "56812", "56813", "56814", "56815", "56817", "56820", "56822", "56824", "56827", "56830", "56833", "56834", "56838", "56840", "56841", "56845", "56849", "56851", "56852", "56853", "56855", "56856", "56858", "56859", "56860", "56864", "56865", "56866", "56867", "56870", "56871", "56877", "56878", "56880", "56883", "56884", "56885", "56886", "56887", "56888", "56889", "56892", "56893", "56899", "56902", "56903", "56904", "56905", "56906", "56907", "56908", "56909", "56910", "56912", "56917", "56921", "56922", "56923", "56933", "56934", "56935", "56937", "56939", "56940", "56942", "56945", "56947", "56950", "56951", "56954", "56956", "56958", "56959", "56962", "56965", "56967", "56969", "56972", "56973", "56975", "56976", "56979", "56982", "56983", "56984", "56985", "56990", "56992", "56993", "56995", "56998", "57000", "57001", "57003", "57004", "57010", "57013", "57014", "57015", "57016", "57017", "57018", "57019", "57020", "57024", "57026", "57027", "57030", "57031", "57033", "57037", "57040", "57044", "57045", "57050", "57052", "57054", "57060", "57061", "57064", "57066", "57067", "57069", "57070", "57071", "57072", "57074", "57076", "57077", "57079", "57080", "57082", "57090", "57091", "57092", "57093", "57095", "57097", "57098", "57100", "57104", "57108", "57109", "57111", "57113", "57114", "57116", "57118", "57119", "57120", "57121", "57123", "57124", "57128", "57130", "57132", "57134", "57135", "57139", "57140", "57143", "57144", "57146", "57149", "57152", "57153", "57155", "57157", "57158", "57159", "57163", "57167", "57171", "57172", "57174", "57176", "57177", "57178", "57179", "57180", "57181", "57183", "57184", "57187", "57190", "57191", "57194", "57197", "57199", "57200", "57201", "57203", "57205", "57209", "57210", "57211", "57217", "57219", "57221", "57222", "57223", "57225", "57226", "57228", "57230", "57231", "57233", "57234", "57235", "57236", "57237", "57238", "57239", "57240", "57241", "57244", "57247", "57249", "57250", "57252", "57254", "57260", "57261", "57262", "57263", "57265", "57267", "57268", "57271", "57272", "57274", "57276", "57279", "57280", "57283", "57284", "57285", "57286", "57288", "57291", "57294", "57295", "57298", "57301", "57302", "57310", "57311", "57312", "57313", "57317", "57318", "57321", "57327", "57328", "57329", "57330", "57331", "57332", "57333", "57334", "57337", "57338", "57340", "57341", "57343", "57345", "57346", "57348", "57350", "57351", "57353", "57355", "57356", "57357", "57360", "57364", "57365", "57367", "57368", "57370", "57371", "57373", "57374", "57375", "57376", "57378", "57379", "57383", "57384", "57385", "57386", "57390", "57391", "57393", "57397", "57398", "57400", "57402", "57403", "57405", "57406", "57408", "57410", "57412", "57413", "57418", "57420", "57424", "57426", "57430", "57432", "57434", "57436", "57438", "57442", "57443", "57444", "57445", "57446", "57448", "57457", "57458", "57460", "57464", "57467", "57468", "57469", "57471", "57472", "57474", "57475", "57477", "57480", "57482", "57484", "57485", "57486", "57487", "57491", "57493", "57494", "57495", "57496", "57506", "57507", "57508", "57510", "57513", "57514", "57517", "57520", "57522", "57524", "57526", "57528", "57529", "57532", "57534", "57536", "57540", "57543", "57544", "57545", "57549", "57552", "57554", "57556", "57557", "57558", "57559", "57561", "57562", "57565", "57566", "57568", "57571", "57572", "57573", "57577", "57578", "57580", "57581", "57582", "57583", "57585", "57586", "57588", "57590", "57592", "57595", "57596", "57601", "57602", "57604", "57606", "57607", "57608", "57611", "57619", "57620", "57621", "57622", "57624", "57630", "57631", "57633", "57634", "57636", "57639", "57641", "57642", "57644", "57646", "57647", "57649", "57653", "57654", "57655", "57658", "57659", "57660", "57661", "57663", "57664", "57665", "57666", "57668", "57670", "57672", "57673", "57674", "57675", "57677", "57679", "57682", "57683", "57684", "57685", "57686", "57687", "57688", "57690", "57691", "57692", "57693", "57697", "57698", "57702", "57703", "57706", "57708", "57709", "57710", "57711", "57713", "57714", "57715", "57719", "57725", "57727", "57729", "57730", "57731", "57737", "57739", "57740", "57743", "57744", "57749", "57752", "57756", "57757", "57761", "57768", "57769", "57771", "57772", "57774", "57778", "57780", "57781", "57782", "57784", "57789", "57793", "57796", "57798", "57801", "57804", "57807", "57808", "57810", "57812", "57815", "57816", "57817", "57820", "57824", "57828", "57830", "57831", "57832", "57833", "57834", "57835", "57836", "57837", "57839", "57841", "57842", "57843", "57844", "57845", "57846", "57847", "57848", "57849", "57854", "57856", "57865", "57866", "57870", "57873", "57874", "57875", "57877", "57878", "57881", "57883", "57884", "57886", "57888", "57889", "57892", "57893", "57894", "57895", "57897", "57898", "57900", "57904", "57905", "57908", "57909", "57910", "57914", "57917", "57918", "57919", "57922", "57923", "57924", "57925", "57928", "57929", "57930", "57934", "57935", "57937", "57940", "57942", "57943", "57944", "57945", "57946", "57947", "57948", "57949", "57950", "57951", "57953", "57954", "57955", "57958", "57965", "57967", "57968", "57970", "57971", "57972", "57973", "57976", "57977", "57978", "57980", "57982", "57983", "57985", "57986", "57987", "57988", "57989", "57990", "57991", "58000", "58007", "58008", "58009", "58010", "58012", "58014", "58015", "58017", "58018", "58024", "58028", "58030", "58031", "58032", "58033", "58034", "58035", "58036", "58039", "58040", "58042", "58048", "58049", "58050", "58051", "58053", "58055", "58057", "58060", "58061", "58062", "58063", "58064", "58065", "58066", "58067", "58068", "58070", "58072", "58074", "58077", "58079", "58082", "58083", "58084", "58089", "58091", "58093", "58094", "58098", "58099", "58101", "58102", "58104", "58108", "58110", "58111", "58116", "58117", "58118", "58119", "58121", "58122", "58124", "58126", "58129", "58130", "58131", "58133", "58134", "58137", "58138", "58140", "58147", "58148", "58153", "58155", "58157", "58158", "58159", "58160", "58161", "58162", "58163", "58165", "58166", "58170", "58172", "58173", "58175", "58179", "58181", "58183", "58188", "58189", "58190", "58193", "58194", "58195", "58196", "58197", "58201", "58202", "58204", "58205", "58207", "58208", "58209", "58210", "58211", "58213", "58215", "58216", "58217", "58221", "58224", "58225", "58226", "58227", "58229", "58230", "58233", "58236", "58237", "58238", "58242", "58243", "58244", "58247", "58248", "58250", "58251", "58252", "58254", "58255", "58257", "58259", "58266", "58271", "58272", "58274", "58275", "58277", "58278", "58282", "58284", "58285", "58286", "58289", "58292", "58293", "58300", "58302", "58303", "58309", "58311", "58315", "58316", "58318", "58319", "58321", "58322", "58323", "58324", "58325", "58327", "58330", "58332", "58335", "58336", "58338", "58342", "58345", "58347", "58350", "58352", "58354", "58357", "58362", "58372", "58375", "58376", "58377", "58379", "58380", "58381", "58382", "58383", "58385", "58386", "58388", "58390", "58391", "58394", "58395", "58396", "58399", "58403", "58405", "58407", "58408", "58410", "58413", "58417", "58418", "58419", "58421", "58422", "58426", "58427", "58429", "58431", "58433", "58434", "58436", "58437", "58439", "58443", "58444", "58445", "58446", "58448", "58453", "58454", "58455", "58457", "58458", "58459", "58460", "58461", "58464", "58465", "58467", "58469", "58470", "58471", "58472", "58475", "58477", "58478", "58479", "58481", "58485", "58491", "58497", "58498", "58499", "58504", "58505", "58507", "58508", "58511", "58512", "58513", "58514", "58516", "58517", "58518", "58521", "58523", "58527", "58528", "58532", "58534", "58535", "58536", "58537", "58538", "58539", "58542", "58543", "58544", "58545", "58546", "58548", "58549", "58554", "58555", "58556", "58557", "58558", "58560", "58562", "58563", "58564", "58565", "58566", "58568", "58569", "58570", "58574", "58575", "58579", "58580", "58581", "58582", "58584", "58588", "58589", "58591", "58593", "58595", "58602", "58603", "58604", "58605", "58607", "58609", "58612", "58614", "58616", "58618", "58624", "58629", "58630", "58631", "58633", "58634", "58635", "58638", "58639", "58641", "58643", "58644", "58645", "58646", "58647", "58650", "58651", "58654", "58655", "58657", "58658", "58659", "58660", "58662", "58664", "58669", "58670", "58672", "58673", "58676", "58677", "58678", "58679", "58680", "58682", "58685", "58686", "58687", "58689", "58693", "58695", "58697", "58698", "58700", "58701", "58702", "58704", "58707", "58710", "58711", "58712", "58713", "58715", "58716", "58717", "58718", "58719", "58721", "58727", "58728", "58729", "58731", "58732", "58739", "58740", "58741", "58742", "58743", "58744", "58745", "58747", "58748", "58756", "58759", "58761", "58763", "58765", "58767", "58768", "58769", "58773", "58774", "58775", "58776", "58777", "58780", "58781", "58784", "58787", "58788", "58789", "58791", "58792", "58797", "58799", "58800", "58801", "58802", "58803", "58804", "58810", "58811", "58813", "58814", "58815", "58817", "58820", "58821", "58822", "58823", "58826", "58827", "58831", "58832", "58836", "58837", "58838", "58839", "58840", "58841", "58844", "58845", "58846", "58847", "58850", "58851", "58852", "58853", "58854", "58859", "58862", "58864", "58865", "58867", "58869", "58870", "58873", "58878", "58879", "58880", "58881", "58882", "58883", "58884", "58886", "58887", "58891", "58894", "58897", "58899", "58900", "58904", "58907", "58908", "58911", "58913", "58914", "58919", "58921", "58922", "58923", "58924", "58926", "58927", "58929", "58931", "58932", "58933", "58934", "58935", "58936", "58941", "58943", "58946", "58947", "58952", "58954", "58955", "58958", "58959", "58960", "58962", "58964", "58965", "58966", "58967", "58970", "58971", "58972", "58974", "58975", "58976", "58981", "58984", "58986", "58987", "58988", "58991", "58992", "58997", "58998", "59000", "59002", "59004", "59006", "59007", "59008", "59010", "59012", "59013", "59018", "59021", "59023", "59027", "59031", "59032", "59033", "59034", "59035", "59036", "59038", "59039", "59044", "59045", "59046", "59050", "59051", "59052", "59053", "59054", "59056", "59057", "59058", "59059", "59062", "59063", "59064", "59065", "59066", "59068", "59071", "59072", "59073", "59078", "59079", "59080", "59081", "59083", "59086", "59087", "59088", "59091", "59092", "59093", "59094", "59097", "59099", "59102", "59103", "59105", "59107", "59110", "59113", "59114", "59116", "59117", "59121", "59122", "59123", "59125", "59129", "59130", "59131", "59132", "59133", "59135", "59138", "59139", "59141", "59142", "59144", "59145", "59149", "59151", "59155", "59156", "59157", "59160", "59163", "59164", "59165", "59170", "59172", "59174", "59175", "59178", "59180", "59181", "59184", "59189", "59192", "59194", "59195", "59198", "59200", "59201", "59203", "59204", "59205", "59206", "59208", "59209", "59210", "59212", "59214", "59216", "59218", "59219", "59220", "59222", "59223", "59224", "59225", "59227", "59228", "59229", "59231", "59235", "59236", "59237", "59238", "59239", "59242", "59243", "59244", "59246", "59247", "59249", "59255", "59257", "59259", "59262", "59264", "59265", "59266", "59267", "59269", "59271", "59272", "59273", "59275", "59278", "59280", "59282", "59283", "59285", "59286", "59289", "59293", "59296", "59297", "59299", "59300", "59303", "59304", "59306", "59308", "59309", "59315", "59316", "59319", "59320", "59327", "59329", "59331", "59334", "59335", "59339", "59342", "59343", "59344", "59346", "59351", "59353", "59357", "59358", "59360", "59361", "59364", "59365", "59367", "59371", "59372", "59374", "59375", "59376", "59377", "59378", "59379", "59380", "59382", "59384", "59386", "59388", "59390", "59391", "59392", "59394", "59397", "59402", "59403", "59404", "59405", "59406", "59407", "59409", "59414", "59415", "59416", "59417", "59420", "59421", "59423", "59424", "59425", "59428", "59430", "59431", "59433", "59435", "59436", "59437", "59438", "59440", "59441", "59442", "59444", "59447", "59449", "59451", "59454", "59456", "59460", "59461", "59464", "59465", "59467", "59468", "59469", "59470", "59471", "59472", "59473", "59475", "59476", "59477", "59481", "59482", "59484", "59486", "59487", "59489", "59491", "59494", "59495", "59496", "59498", "59499", "59501", "59503", "59514", "59515", "59518", "59519", "59520", "59521", "59522", "59524", "59525", "59527", "59529", "59530", "59531", "59532", "59534", "59537", "59539", "59542", "59543", "59548", "59550", "59551", "59552", "59553", "59555", "59556", "59557", "59560", "59563", "59564", "59567", "59571", "59572", "59573", "59574", "59575", "59578", "59580", "59587", "59589", "59590", "59593", "59598", "59599", "59600", "59601", "59603", "59604", "59608", "59609", "59610", "59614", "59615", "59616", "59618", "59621", "59622", "59623", "59624", "59627", "59629", "59630", "59631", "59632", "59637", "59638", "59639", "59640", "59644", "59645", "59647", "59648", "59649", "59650", "59653", "59656", "59660", "59662", "59664", "59665", "59666", "59670", "59671", "59675", "59676", "59679", "59681", "59682", "59683", "59686", "59687", "59689", "59690", "59692", "59693", "59694", "59695", "59696", "59701", "59703", "59706", "59707", "59708", "59710", "59711", "59715", "59717", "59718", "59719", "59721", "59723", "59725", "59726", "59728", "59729", "59730", "59731", "59734", "59738", "59739", "59741", "59742", "59743", "59746", "59747", "59752", "59753", "59754", "59755", "59756", "59758", "59759", "59761", "59762", "59764", "59765", "59766", "59767", "59771", "59773", "59775", "59778", "59780", "59781", "59785", "59786", "59787", "59788", "59790", "59791", "59792", "59793", "59794", "59795", "59796", "59800", "59801", "59806", "59807", "59809", "59810", "59812", "59814", "59815", "59819", "59821", "59822", "59823", "59826", "59827", "59828", "59829", "59831", "59832", "59834", "59836", "59837", "59839", "59840", "59845", "59847", "59850", "59851", "59852", "59853", "59854", "59855", "59856", "59858", "59859", "59861", "59864", "59866", "59868", "59871", "59876", "59883", "59884", "59885", "59887", "59888", "59893", "59894", "59899", "59901", "59903", "59904", "59907", "59909", "59912", "59913", "59916", "59917", "59918", "59920", "59921", "59922", "59924", "59927", "59928", "59930", "59931", "59932", "59934", "59935", "59936", "59937", "59938", "59943", "59945", "59946", "59947", "59950", "59953", "59955", "59956", "59959", "59964", "59965", "59966", "59970", "59971", "59974", "59975", "59976", "59978", "59979", "59984", "59985", "59989", "59990", "59995", "59996", "60001", "60002", "60003", "60005", "60008", "60010", "60011", "60014", "60016", "60017", "60019", "60022", "60023", "60024", "60025", "60026", "60028", "60031", "60032", "60033", "60036", "60037", "60041", "60043", "60046", "60047", "60048", "60052", "60054", "60055", "60059", "60060", "60061", "60064", "60069", "60077", "60078", "60079", "60085", "60086", "60088", "60089", "60090", "60092", "60094", "60095", "60099", "60100", "60104", "60106", "60107", "60108", "60109", "60110", "60111", "60115", "60118", "60119", "60120", "60121", "60122", "60126", "60128", "60130", "60132", "60134", "60135", "60136", "60137", "60139", "60141", "60142", "60144", "60145", "60146", "60153", "60158", "60159", "60160", "60163", "60164", "60167", "60169", "60170", "60171", "60177", "60179", "60180", "60181", "60182", "60188", "60190", "60191", "60193", "60195", "60196", "60201", "60206", "60207", "60208", "60209", "60210", "60211", "60212", "60214", "60215", "60216", "60218", "60219", "60224", "60225", "60226", "60228", "60231", "60233", "60234", "60236", "60237", "60239", "60241", "60242", "60243", "60245", "60247", "60251", "60253", "60254", "60255", "60256", "60258", "60260", "60262", "60264", "60265", "60266", "60268", "60269", "60271", "60272", "60273", "60281", "60282", "60283", "60284", "60285", "60286", "60288", "60289", "60292", "60297", "60299", "60302", "60303", "60304", "60307", "60308", "60309", "60310", "60312", "60313", "60315", "60318", "60319", "60320", "60321", "60325", "60326", "60330", "60333", "60334", "60336", "60338", "60346", "60348", "60349", "60350", "60351", "60353", "60354", "60355", "60358", "60359", "60364", "60367", "60369", "60370", "60374", "60375", "60378", "60379", "60380", "60382", "60383", "60384", "60385", "60386", "60389", "60390", "60392", "60394", "60395", "60397", "60400", "60401", "60403", "60405", "60406", "60407", "60408", "60409", "60412", "60413", "60415", "60418", "60419", "60420", "60422", "60428", "60430", "60432", "60433", "60435", "60436", "60437", "60438", "60440", "60442", "60445", "60448", "60450", "60451", "60453", "60456", "60458", "60460", "60462", "60468", "60470", "60471", "60472", "60473", "60475", "60478", "60479", "60482", "60484", "60485", "60487", "60488", "60489", "60490", "60497", "60501", "60502", "60505", "60506", "60507", "60508", "60509", "60511", "60515", "60517", "60518", "60522", "60525", "60526", "60527", "60529", "60530", "60534", "60535", "60536", "60538", "60539", "60542", "60543", "60544", "60546", "60547", "60551", "60552", "60555", "60557", "60558", "60564", "60565", "60568", "60569", "60570", "60571", "60572", "60573", "60574", "60578", "60580", "60581", "60582", "60583", "60590", "60594", "60595", "60596", "60598", "60599", "60600", "60602", "60604", "60605", "60606", "60607", "60608", "60609", "60610", "60614", "60616", "60617", "60620", "60621", "60622", "60623", "60625", "60626", "60627", "60628", "60631", "60635", "60636", "60637", "60638", "60639", "60641", "60642", "60643", "60646", "60647", "60650", "60651", "60652", "60653", "60655", "60656", "60657", "60658", "60661", "60664", "60670", "60671", "60673", "60674", "60675", "60676", "60677", "60678", "60679", "60681", "60682", "60684", "60688", "60689", "60692", "60693", "60694", "60695", "60701", "60704", "60706", "60707", "60710", "60711", "60715", "60716", "60717", "60720", "60721", "60722", "60723", "60724", "60725", "60728", "60732", "60733", "60734", "60735", "60736", "60739", "60740", "60741", "60742", "60743", "60744", "60745", "60746", "60749", "60751", "60752", "60753", "60759", "60761", "60763", "60764", "60766", "60769", "60770", "60772", "60778", "60779", "60781", "60782", "60783", "60784", "60786", "60787", "60791", "60793", "60795", "60799", "60800", "60804", "60805", "60808", "60809", "60811", "60812", "60813", "60814", "60815", "60817", "60823", "60829", "60832", "60833", "60835", "60837", "60838", "60839", "60843", "60845", "60847", "60848", "60851", "60852", "60853", "60855", "60862", "60867", "60873", "60874", "60875", "60876", "60877", "60878", "60879", "60881", "60882", "60886", "60889", "60891", "60892", "60893", "60895", "60897", "60902", "60904", "60906", "60908", "60911", "60912", "60913", "60919", "60921", "60924", "60925", "60928", "60929", "60931", "60932", "60933", "60935", "60936", "60938", "60939", "60940", "60941", "60942", "60944", "60946", "60952", "60955", "60956", "60957", "60958", "60959", "60960", "60961", "60965", "60966", "60972", "60978", "60982", "60984", "60985", "60986", "60987", "60989", "60990", "60992", "60993", "60998", "60999", "61000", "61002", "61003", "61004", "61006", "61007", "61008", "61011", "61012", "61014", "61015", "61017", "61018", "61019", "61021", "61022", "61025", "61026", "61027", "61030", "61031", "61032", "61033", "61034", "61038", "61041", "61043", "61044", "61045", "61046", "61047", "61048", "61049", "61050", "61056", "61057", "61058", "61060", "61062", "61064", "61065", "61066", "61068", "61070", "61072", "61073", "61074", "61075", "61079", "61082", "61084", "61085", "61086", "61090", "61091", "61093", "61094", "61096", "61098", "61099", "61101", "61102", "61103", "61105", "61106", "61108", "61109", "61110", "61111", "61112", "61116", "61117", "61119", "61122", "61125", "61131", "61133", "61134", "61136", "61141", "61142", "61146", "61147", "61148", "61149", "61152", "61153", "61156", "61157", "61158", "61165", "61170", "61172", "61173", "61175", "61176", "61177", "61179", "61183", "61184", "61185", "61187", "61188", "61189", "61191", "61194", "61195", "61196", "61198", "61199", "61204", "61206", "61207", "61210", "61211", "61214", "61217", "61218", "61219", "61220", "61222", "61224", "61226", "61227", "61231", "61234", "61237", "61238", "61240", "61241", "61242", "61253", "61254", "61255", "61256", "61257", "61259", "61263", "61264", "61265", "61266", "61268", "61269", "61271", "61272", "61273", "61275", "61276", "61281", "61282", "61284", "61286", "61288", "61289", "61291", "61293", "61305", "61306", "61308", "61309", "61310", "61311", "61314", "61315", "61318", "61321", "61322", "61325", "61326", "61332", "61336", "61337", "61339", "61340", "61341", "61343", "61345", "61346", "61347", "61351", "61352", "61353", "61358", "61359", "61361", "61363", "61365", "61366", "61369", "61374", "61375", "61376", "61378", "61381", "61384", "61385", "61389", "61390", "61393", "61395", "61396", "61397", "61398", "61403", "61410", "61411", "61412", "61416", "61417", "61418", "61419", "61420", "61421", "61423", "61424", "61431", "61433", "61434", "61435", "61436", "61437", "61438", "61440", "61441", "61443", "61447", "61448", "61449", "61450", "61451", "61452", "61453", "61454", "61455", "61460", "61462", "61464", "61465", "61466", "61471", "61477", "61478", "61479", "61480", "61481", "61482", "61483", "61484", "61488", "61489", "61497", "61498", "61500", "61501", "61507", "61508", "61509", "61511", "61514", "61516", "61517", "61518", "61521", "61522", "61526", "61527", "61529", "61530", "61531", "61532", "61536", "61538", "61539", "61541", "61542", "61543", "61544", "61545", "61547", "61549", "61554", "61555", "61556", "61559", "61561", "61565", "61566", "61570", "61572", "61579", "61581", "61582", "61584", "61588", "61590", "61591", "61592", "61594", "61596", "61598", "61599", "61600", "61601", "61603", "61604", "61606", "61607", "61608", "61609", "61610", "61612", "61615", "61621", "61622", "61625", "61626", "61628", "61629", "61631", "61632", "61633", "61634", "61635", "61636", "61638", "61640", "61642", "61643", "61644", "61645", "61647", "61649", "61651", "61652", "61653", "61657", "61658", "61659", "61660", "61662", "61663", "61664", "61665", "61667", "61668", "61669", "61670", "61672", "61673", "61674", "61675", "61677", "61678", "61680", "61681", "61682", "61684", "61685", "61690", "61691", "61692", "61694", "61696", "61697", "61698", "61699", "61703", "61704", "61705", "61709", "61710", "61717", "61718", "61719", "61723", "61725", "61726", "61727", "61728", "61732", "61733", "61734", "61739", "61740", "61741", "61742", "61745", "61747", "61748", "61749", "61750", "61751", "61752", "61753", "61755", "61756", "61758", "61760", "61761", "61762", "61764", "61767", "61768", "61773", "61777", "61782", "61783", "61784", "61785", "61786", "61788", "61790", "61794", "61795", "61796", "61797", "61798", "61802", "61803", "61804", "61805", "61806", "61810", "61811", "61812", "61813", "61814", "61817", "61818", "61820", "61821", "61822", "61824", "61826", "61829", "61830", "61832", "61834", "61835", "61837", "61839", "61841", "61845", "61847", "61851", "61852", "61853", "61856", "61857", "61862", "61864", "61866", "61867", "61870", "61871", "61872", "61873", "61875", "61876", "61878", "61880", "61885", "61887", "61888", "61889", "61891", "61893", "61894", "61895", "61897", "61899", "61902", "61903", "61906", "61907", "61908", "61911", "61914", "61915", "61917", "61919", "61920", "61921", "61922", "61923", "61927", "61934", "61937", "61938", "61939", "61940", "61941", "61943", "61944", "61945", "61946", "61948", "61950", "61951", "61953", "61954", "61956", "61959", "61960", "61961", "61963", "61964", "61967", "61968", "61970", "61972", "61975", "61978", "61981", "61982", "61983", "61985", "61986", "61988", "61990", "61993", "61994", "61995", "61997", "61998", "61999", "62000", "62001", "62002", "62004", "62005", "62009", "62010", "62011", "62013", "62015", "62019", "62021", "62022", "62023", "62024", "62026", "62027", "62028", "62029", "62030", "62031", "62035", "62038", "62039", "62044", "62045", "62047", "62049", "62050", "62051", "62053", "62057", "62064", "62065", "62067", "62070", "62075", "62080", "62081", "62082", "62083", "62085", "62087", "62088", "62090", "62091", "62092", "62094", "62095", "62098", "62099", "62100", "62104", "62106", "62108", "62110", "62113", "62116", "62118", "62119", "62120", "62124", "62126", "62129", "62132", "62135", "62137", "62138", "62140", "62141", "62143", "62146", "62147", "62151", "62153", "62156", "62157", "62161", "62166", "62168", "62174", "62177", "62178", "62179", "62180", "62182", "62183", "62184", "62188", "62193", "62195", "62196", "62197", "62199", "62201", "62203", "62207", "62211", "62212", "62216", "62222", "62224", "62225", "62226", "62227", "62229", "62231", "62232", "62236", "62240", "62241", "62243", "62244", "62246", "62247", "62252", "62255", "62256", "62259", "62260", "62261", "62264", "62265", "62267", "62271", "62272", "62273", "62275", "62276", "62277", "62278", "62281", "62283", "62285", "62287", "62288", "62289", "62291", "62292", "62294", "62297", "62299", "62304", "62305", "62306", "62309", "62310", "62311", "62313", "62314", "62315", "62318", "62319", "62321", "62322", "62323", "62324", "62335", "62337", "62338", "62341", "62343", "62346", "62349", "62352", "62354", "62356", "62359", "62360", "62362", "62363", "62365", "62366", "62368", "62369", "62372", "62374", "62376", "62381", "62382", "62383", "62384", "62387", "62388", "62391", "62396", "62397", "62399", "62400", "62402", "62404", "62405", "62407", "62408", "62409", "62410", "62411", "62413", "62415", "62416", "62417", "62419", "62420", "62421", "62422", "62423", "62425", "62430", "62431", "62432", "62435", "62437", "62438", "62444", "62445", "62449", "62451", "62453", "62454", "62455", "62457", "62459", "62460", "62461", "62465", "62467", "62468", "62470", "62472", "62473", "62475", "62477", "62480", "62481", "62483", "62485", "62486", "62487", "62488", "62490", "62491", "62495", "62497", "62502", "62505", "62507", "62511", "62512", "62513", "62515", "62516", "62520", "62521", "62522", "62524", "62529", "62530", "62531", "62532", "62534", "62536", "62537", "62539", "62540", "62542", "62543", "62545", "62546", "62547", "62549", "62551", "62552", "62557", "62559", "62560", "62561", "62563", "62568", "62571", "62573", "62574", "62580", "62582", "62585", "62587", "62592", "62593", "62595", "62597", "62598", "62599", "62603", "62604", "62606", "62609", "62611", "62613", "62614", "62619", "62621", "62622", "62623", "62625", "62626", "62627", "62629", "62630", "62631", "62632", "62634", "62638", "62644", "62646", "62648", "62649", "62651", "62652", "62655", "62657", "62659", "62661", "62664", "62667", "62668", "62670", "62676", "62679", "62680", "62684", "62686", "62687", "62692", "62693", "62694", "62696", "62699", "62703", "62707", "62709", "62712", "62716", "62717", "62721", "62724", "62725", "62727", "62729", "62733", "62734", "62736", "62740", "62748", "62749", "62751", "62753", "62755", "62757", "62758", "62759", "62761", "62764", "62765", "62766", "62767", "62768", "62769", "62771", "62772", "62773", "62776", "62777", "62778", "62779", "62780", "62782", "62783", "62785", "62787", "62788", "62792", "62793", "62794", "62795", "62797", "62798", "62799", "62800", "62801", "62806", "62807", "62809", "62812", "62814", "62815", "62816", "62818", "62819", "62822", "62823", "62825", "62826", "62828", "62830", "62832", "62836", "62842", "62844", "62848", "62850", "62852", "62855", "62856", "62857", "62858", "62859", "62863", "62865", "62866", "62869", "62871", "62872", "62874", "62875", "62876", "62878", "62879", "62880", "62883", "62885", "62886", "62888", "62890", "62892", "62894", "62898", "62899", "62901", "62902", "62906", "62908", "62909", "62910", "62911", "62913", "62914", "62916", "62917", "62920", "62924", "62925", "62926", "62928", "62930", "62933", "62935", "62937", "62938", "62939", "62941", "62942", "62946", "62948", "62949", "62950", "62953", "62954", "62955", "62956", "62958", "62959", "62960", "62963", "62964", "62965", "62966", "62967", "62969", "62975", "62978", "62981", "62982", "62983", "62985", "62986", "62987", "62990", "62992", "62999", "63001", "63003", "63004", "63005", "63006", "63008", "63009", "63011", "63013", "63017", "63018", "63019", "63022", "63023", "63025", "63026", "63028", "63032", "63034", "63035", "63037", "63038", "63039", "63040", "63041", "63042", "63043", "63044", "63046", "63049", "63051", "63060", "63064", "63066", "63071", "63072", "63076", "63078", "63079", "63082", "63083", "63086", "63087", "63088", "63089", "63091", "63093", "63094", "63096", "63097", "63098", "63099", "63100", "63102", "63103", "63104", "63107", "63110", "63112", "63113", "63114", "63116", "63117", "63123", "63126", "63127", "63128", "63129", "63134", "63136", "63137", "63138", "63140", "63143", "63145", "63146", "63147", "63148", "63152", "63154", "63155", "63158", "63161", "63165", "63167", "63170", "63171", "63172", "63174", "63175", "63176", "63181", "63184", "63188", "63192", "63193", "63195", "63196", "63200", "63202", "63204", "63212", "63214", "63219", "63220", "63223", "63225", "63230", "63231", "63233", "63235", "63237", "63238", "63239", "63246", "63247", "63248", "63249", "63250", "63252", "63254", "63257", "63258", "63259", "63262", "63263", "63265", "63266", "63267", "63269", "63273", "63274", "63275", "63277", "63278", "63279", "63280", "63281", "63283", "63284", "63285", "63287", "63289", "63290", "63291", "63295", "63296", "63298", "63299", "63300", "63301", "63302", "63303", "63304", "63306", "63307", "63310", "63311", "63312", "63314", "63315", "63317", "63318", "63319", "63322", "63323", "63324", "63326", "63328", "63330", "63331", "63332", "63336", "63337", "63338", "63341", "63342", "63343", "63344", "63347", "63349", "63351", "63352", "63354", "63357", "63358", "63364", "63365", "63366", "63369", "63373", "63374", "63375", "63378", "63381", "63382", "63383", "63385", "63386", "63387", "63390", "63392", "63395", "63396", "63398", "63400", "63401", "63402", "63404", "63408", "63409", "63414", "63421", "63425", "63426", "63427", "63432", "63434", "63435", "63436", "63440", "63441", "63442", "63444", "63446", "63447", "63448", "63449", "63450", "63452", "63453", "63455", "63458", "63459", "63462", "63466", "63467", "63468", "63473", "63474", "63476", "63480", "63482", "63483", "63489", "63490", "63493", "63495", "63496", "63497", "63498", "63507", "63513", "63515", "63518", "63522", "63523", "63524", "63525", "63527", "63528", "63530", "63533", "63535", "63537", "63538", "63539", "63543", "63544", "63549", "63550", "63552", "63555", "63557", "63558", "63559", "63560", "63561", "63562", "63564", "63566", "63567", "63568", "63570", "63573", "63574", "63580", "63584", "63585", "63586", "63591", "63592", "63593", "63596", "63598", "63600", "63602", "63604", "63607", "63608", "63609", "63610", "63612", "63613", "63614", "63615", "63616", "63621", "63623", "63624", "63625", "63626", "63633", "63639", "63642", "63649", "63650", "63653", "63654", "63655", "63656", "63657", "63658", "63660", "63662", "63663", "63664", "63665", "63667", "63669", "63671", "63672", "63674", "63675", "63676", "63677", "63678", "63680", "63681", "63682", "63688", "63690", "63691", "63692", "63694", "63695", "63698", "63705", "63707", "63708", "63712", "63713", "63714", "63716", "63717", "63718", "63721", "63723", "63725", "63726", "63727", "63728", "63730", "63732", "63733", "63734", "63736", "63738", "63739", "63741", "63742", "63743", "63745", "63747", "63748", "63749", "63750", "63752", "63754", "63757", "63759", "63764", "63765", "63767", "63770", "63771", "63772", "63774", "63775", "63776", "63777", "63779", "63781", "63783", "63789", "63790", "63792", "63793", "63797", "63799", "63801", "63802", "63804", "63805", "63806", "63808", "63809", "63811", "63814", "63815", "63816", "63817", "63822", "63826", "63827", "63829", "63833", "63836", "63837", "63839", "63841", "63842", "63844", "63845", "63846", "63847", "63848", "63849", "63850", "63851", "63853", "63854", "63857", "63859", "63860", "63861", "63865", "63867", "63868", "63869", "63871", "63872", "63873", "63874", "63878", "63879", "63880", "63882", "63883", "63884", "63886", "63888", "63889", "63894", "63896", "63898", "63899", "63900", "63901", "63902", "63903", "63905", "63906", "63910", "63911", "63918", "63919", "63921", "63922", "63923", "63924", "63925", "63926", "63927", "63928", "63930", "63931", "63932", "63933", "63935", "63937", "63938", "63939", "63940", "63941", "63944", "63945", "63946", "63947", "63951", "63953", "63957", "63958", "63959", "63962", "63963", "63964", "63967", "63968", "63970", "63971", "63973", "63974", "63975", "63976", "63979", "63980", "63981", "63982", "63985", "63986", "63988", "63989", "63990", "63991", "63993", "63994", "63997", "63998", "64000", "64002", "64005", "64006", "64009", "64010", "64015", "64016", "64019", "64022", "64025", "64027", "64028", "64029", "64031", "64034", "64038", "64039", "64041", "64042", "64044", "64045", "64046", "64048", "64051", "64052", "64053", "64054", "64058", "64059", "64060", "64061", "64063", "64065", "64067", "64072", "64073", "64074", "64076", "64078", "64079", "64080", "64082", "64083", "64085", "64088", "64090", "64093", "64095", "64096", "64097", "64101", "64102", "64103", "64104", "64107", "64112", "64113", "64114", "64119", "64122", "64123", "64125", "64128", "64129", "64133", "64135", "64136", "64137", "64139", "64140", "64146", "64148", "64149", "64151", "64152", "64156", "64160", "64161", "64164", "64165", "64166", "64167", "64168", "64171", "64172", "64173", "64174", "64176", "64177", "64178", "64183", "64185", "64186", "64191", "64192", "64197", "64201", "64202", "64203", "64205", "64210", "64213", "64216", "64219", "64220", "64221", "64222", "64223", "64226", "64227", "64229", "64231", "64232", "64234", "64236", "64237", "64240", "64241", "64247", "64248", "64249", "64250", "64252", "64255", "64256", "64265", "64266", "64267", "64273", "64274", "64279", "64285", "64288", "64289", "64291", "64294", "64296", "64297", "64300", "64302", "64305", "64308", "64309", "64310", "64313", "64314", "64316", "64317", "64319", "64320", "64322", "64324", "64325", "64326", "64327", "64328", "64329", "64330", "64332", "64334", "64335", "64336", "64338", "64341", "64343", "64345", "64346", "64347", "64352", "64354", "64358", "64360", "64361", "64362", "64363", "64366", "64371", "64373", "64374", "64375", "64377", "64378", "64380", "64382", "64383", "64384", "64385", "64390", "64393", "64396", "64399", "64402", "64403", "64404", "64406", "64407", "64409", "64410", "64411", "64412", "64413", "64415", "64417", "64420", "64425", "64426", "64427", "64428", "64429", "64432", "64433", "64434", "64435", "64436", "64438", "64439", "64441", "64443", "64444", "64446", "64447", "64451", "64455", "64458", "64462", "64463", "64468", "64470", "64474", "64476", "64478", "64480", "64482", "64483", "64485", "64486", "64488", "64489", "64494", "64495", "64496", "64497", "64500", "64501", "64502", "64504", "64506", "64507", "64511", "64512", "64513", "64514", "64516", "64517", "64520", "64521", "64522", "64523", "64524", "64528", "64530", "64534", "64535", "64537", "64539", "64540", "64541", "64542", "64543", "64545", "64546", "64547", "64549", "64551", "64552", "64556", "64560", "64562", "64565", "64566", "64571", "64572", "64575", "64577", "64581", "64583", "64584", "64585", "64588", "64589", "64590", "64593", "64597", "64598", "64601", "64602", "64604", "64605", "64610", "64613", "64614", "64615", "64620", "64625", "64626", "64628", "64630", "64631", "64635", "64636", "64637", "64638", "64639", "64644", "64645", "64646", "64647", "64649", "64650", "64651", "64652", "64653", "64654", "64656", "64657", "64658", "64659", "64662", "64665", "64666", "64668", "64669", "64671", "64672", "64674", "64676", "64677", "64678", "64680", "64681", "64683", "64686", "64687", "64689", "64690", "64691", "64696", "64697", "64698", "64700", "64701", "64703", "64709", "64710", "64713", "64715", "64716", "64718", "64719", "64720", "64722", "64723", "64725", "64728", "64729", "64737", "64740", "64742", "64743", "64748", "64749", "64750", "64753", "64754", "64755", "64756", "64757", "64758", "64759", "64761", "64764", "64766", "64769", "64772", "64774", "64780", "64781", "64783", "64784", "64785", "64789", "64790", "64794", "64795", "64796", "64800", "64802", "64803", "64804", "64805", "64806", "64807", "64808", "64811", "64816", "64817", "64820", "64821", "64822", "64826", "64828", "64829", "64830", "64832", "64833", "64838", "64841", "64842", "64844", "64845", "64846", "64847", "64848", "64849", "64851", "64852", "64855", "64856", "64857", "64858", "64860", "64861", "64862", "64863", "64867", "64869", "64870", "64871", "64876", "64878", "64879", "64880", "64882", "64884", "64885", "64886", "64888", "64889", "64892", "64894", "64899", "64902", "64903", "64905", "64906", "64907", "64909", "64910", "64912", "64913", "64916", "64917", "64925", "64926", "64927", "64930", "64932", "64935", "64937", "64938", "64939", "64943", "64944", "64948", "64949", "64951", "64954", "64955", "64956", "64959", "64960", "64961", "64963", "64964", "64967", "64970", "64972", "64973", "64974", "64975", "64976", "64979", "64981", "64985", "64986", "64988", "64992", "64993", "64995", "64997", "65002", "65003", "65005", "65007", "65008", "65010", "65011", "65012", "65013", "65015", "65016", "65018", "65021", "65026", "65027", "65028", "65030", "65033", "65036", "65037", "65038", "65040", "65043", "65044", "65047", "65052", "65053", "65054", "65055", "65059", "65060", "65062", "65063", "65067", "65068", "65069", "65070", "65071", "65074", "65075", "65077", "65078", "65082", "65085", "65089", "65092", "65093", "65094", "65095", "65098", "65102", "65103", "65106", "65107", "65111", "65112", "65114", "65115", "65117", "65119", "65120", "65124", "65125", "65126", "65128", "65131", "65132", "65133", "65134", "65137", "65138", "65139", "65142", "65143", "65144", "65145", "65146", "65147", "65148", "65149", "65152", "65153", "65154", "65155", "65156", "65162", "65163", "65165", "65166", "65168", "65170", "65172", "65174", "65176", "65178", "65182", "65183", "65185", "65192", "65194", "65195", "65200", "65202", "65203", "65206", "65209", "65210", "65211", "65212", "65213", "65214", "65215", "65216", "65217", "65218", "65220", "65221", "65223", "65224", "65225", "65228", "65229", "65234", "65235", "65241", "65242", "65244", "65246", "65249", "65250", "65251", "65252", "65254", "65255", "65256", "65257", "65258", "65262", "65267", "65269", "65270", "65272", "65274", "65277", "65278", "65279", "65280", "65283", "65284", "65285", "65286", "65287", "65290", "65291", "65292", "65294", "65295", "65296", "65297", "65302", "65304", "65306", "65308", "65309", "65310", "65311", "65312", "65314", "65315", "65320", "65322", "65323", "65324", "65325", "65327", "65329", "65333", "65335", "65336", "65337", "65338", "65339", "65342", "65343", "65348", "65349", "65350", "65351", "65352", "65353", "65356", "65358", "65359", "65360", "65362", "65364", "65365", "65372", "65373", "65375", "65377", "65378", "65381", "65382", "65386", "65389", "65390", "65392", "65395", "65399", "65403", "65404", "65406", "65407", "65408", "65410", "65417", "65420", "65421", "65424", "65425", "65426", "65430", "65431", "65433", "65435", "65439", "65440", "65441", "65442", "65444", "65445", "65447", "65448", "65449", "65450", "65451", "65455", "65456", "65457", "65458", "65459", "65461", "65464", "65465", "65469", "65471", "65474", "65476", "65479", "65482", "65484", "65486", "65487", "65488", "65491", "65492", "65493", "65494", "65495", "65496", "65497", "65503", "65506", "65508", "65513", "65516", "65517", "65521", "65522", "65524", "65527", "65529", "65533", "65534", "65537", "65544", "65546", "65548", "65553", "65554", "65555", "65556", "65557", "65558", "65562", "65563", "65564", "65567", "65568", "65571", "65574", "65575", "65576", "65580", "65581", "65582", "65586", "65587", "65588", "65589", "65590", "65592", "65597", "65598", "65601", "65603", "65611", "65612", "65613", "65614", "65615", "65618", "65620", "65622", "65623", "65624", "65625", "65629", "65633", "65634", "65639", "65641", "65644", "65647", "65648", "65649", "65650", "65651", "65653", "65654", "65655", "65658", "65659", "65660", "65665", "65666", "65668", "65669", "65671", "65672", "65676", "65678", "65679", "65685", "65686", "65687", "65688", "65691", "65692", "65694", "65695", "65699", "65700", "65701", "65703", "65704", "65706", "65707", "65708", "65710", "65715", "65717", "65718", "65720", "65722", "65724", "65725", "65726", "65727", "65733", "65734", "65737", "65738", "65740", "65742", "65743", "65745", "65746", "65750", "65751", "65755", "65756", "65758", "65759", "65760", "65764", "65767", "65770", "65773", "65774", "65777", "65778", "65779", "65782", "65790", "65792", "65793", "65795", "65797", "65801", "65803", "65805", "65807", "65811", "65813", "65815", "65816", "65823", "65824", "65825", "65827", "65829", "65830", "65834", "65836", "65840", "65841", "65843", "65846", "65847", "65848", "65849", "65852", "65854", "65855", "65857", "65858", "65860", "65861", "65862", "65863", "65866", "65869", "65870", "65871", "65886", "65887", "65888", "65893", "65894", "65895", "65896", "65898", "65900", "65902", "65905", "65906", "65907", "65908", "65910", "65912", "65913", "65915", "65917", "65918", "65921", "65922", "65924", "65926", "65928", "65929", "65933", "65937", "65938", "65941", "65946", "65947", "65948", "65950", "65952", "65955", "65957", "65959", "65962", "65967", "65970", "65971", "65973", "65976", "65979", "65982", "65983", "65985", "65987", "65989", "65990", "65996", "66000", "66002", "66004", "66005", "66006", "66012", "66014", "66015", "66016", "66017", "66019", "66023", "66024", "66025", "66027", "66030", "66032", "66034", "66036", "66038", "66046", "66048", "66049", "66052", "66053", "66054", "66056", "66057", "66060", "66061", "66064", "66066", "66067", "66069", "66070", "66072", "66074", "66075", "66076", "66078", "66079", "66080", "66081", "66082", "66083", "66084", "66085", "66086", "66087", "66089", "66090", "66091", "66092", "66093", "66095", "66096", "66098", "66099", "66100", "66103", "66104", "66105", "66107", "66110", "66112", "66113", "66116", "66119", "66121", "66122", "66126", "66128", "66129", "66130", "66131", "66132", "66133", "66139", "66143", "66145", "66146", "66148", "66149", "66150", "66151", "66153", "66154", "66155", "66156", "66158", "66164", "66165", "66168", "66169", "66172", "66175", "66177", "66178", "66179", "66181", "66183", "66186", "66189", "66190", "66192", "66193", "66198", "66200", "66201", "66202", "66204", "66206", "66207", "66211", "66212", "66214", "66216", "66218", "66219", "66222", "66223", "66225", "66226", "66228", "66229", "66236", "66238", "66241", "66242", "66244", "66245", "66247", "66250", "66252", "66257", "66258", "66259", "66262", "66265", "66267", "66268", "66271", "66272", "66273", "66274", "66275", "66279", "66280", "66282", "66283", "66284", "66285", "66287", "66289", "66290", "66291", "66294", "66296", "66298", "66299", "66300", "66301", "66305", "66306", "66307", "66313", "66321", "66324", "66325", "66328", "66332", "66333", "66335", "66339", "66340", "66342", "66346", "66349", "66350", "66351", "66353", "66354", "66355", "66356", "66357", "66359", "66360", "66361", "66362", "66363", "66370", "66371", "66373", "66374", "66375", "66377", "66378", "66383", "66384", "66385", "66389", "66392", "66393", "66394", "66395", "66396", "66402", "66403", "66404", "66406", "66407", "66409", "66411", "66415", "66421", "66430", "66431", "66432", "66433", "66435", "66437", "66443", "66444", "66446", "66447", "66448", "66449", "66450", "66453", "66456", "66457", "66461", "66465", "66467", "66470", "66471", "66475", "66478", "66479", "66481", "66482", "66484", "66485", "66486", "66487", "66488", "66490", "66491", "66492", "66493", "66496", "66498", "66499", "66501", "66503", "66504", "66506", "66507", "66508", "66509", "66510", "66512", "66513", "66514", "66516", "66517", "66521", "66523", "66526", "66527", "66528", "66529", "66534", "66536", "66537", "66547", "66549", "66554", "66555", "66556", "66557", "66559", "66560", "66561", "66564", "66565", "66566", "66567", "66568", "66570", "66571", "66572", "66573", "66574", "66578", "66579", "66581", "66582", "66583", "66585", "66590", "66591", "66593", "66595", "66596", "66598", "66599", "66601", "66602", "66604", "66606", "66608", "66609", "66610", "66611", "66614", "66616", "66617", "66621", "66622", "66623", "66625", "66631", "66632", "66635", "66637", "66638", "66640", "66641", "66643", "66644", "66646", "66648", "66650", "66652", "66653", "66654", "66655", "66659", "66660", "66667", "66668", "66669", "66670", "66671", "66673", "66674", "66677", "66678", "66679", "66683", "66686", "66687", "66688", "66690", "66693", "66695", "66697", "66699", "66701", "66703", "66704", "66707", "66708", "66711", "66712", "66714", "66715", "66716", "66718", "66720", "66721", "66723", "66724", "66725", "66726", "66728", "66729", "66730", "66732", "66733", "66734", "66735", "66737", "66745", "66748", "66749", "66750", "66752", "66753", "66755", "66757", "66759", "66760", "66762", "66764", "66766", "66771", "66773", "66775", "66780", "66781", "66784", "66786", "66787", "66788", "66790", "66791", "66795", "66800", "66801", "66803", "66804", "66807", "66808", "66809", "66810", "66811", "66812", "66814", "66815", "66816", "66818", "66821", "66823", "66826", "66829", "66830", "66831", "66833", "66834", "66835", "66836", "66837", "66839", "66846", "66847", "66849", "66851", "66852", "66853", "66855", "66860", "66864", "66868", "66869", "66870", "66871", "66872", "66874", "66875", "66878", "66879", "66880", "66881", "66883", "66884", "66885", "66886", "66889", "66890", "66891", "66892", "66893", "66895", "66896", "66897", "66899", "66901", "66902", "66903", "66904", "66905", "66907", "66908", "66909", "66912", "66914", "66917", "66921", "66924", "66925", "66927", "66928", "66931", "66932", "66935", "66936", "66937", "66938", "66941", "66942", "66943", "66946", "66947", "66949", "66951", "66952", "66954", "66955", "66956", "66957", "66959", "66961", "66963", "66965", "66971", "66972", "66973", "66974", "66976", "66977", "66979", "66985", "66986", "66987", "66990", "66991", "66992", "66995", "66997", "66999", "67017", "67020", "67022", "67023", "67024", "67025", "67026", "67029", "67030", "67032", "67033", "67036", "67040", "67043", "67044", "67045", "67047", "67050", "67052", "67054", "67055", "67056", "67057", "67058", "67061", "67062", "67064", "67071", "67073", "67074", "67075", "67077", "67078", "67080", "67082", "67086", "67088", "67089", "67090", "67091", "67094", "67095", "67098", "67104", "67105", "67108", "67109", "67112", "67114", "67119", "67121", "67126", "67129", "67130", "67131", "67132", "67134", "67138", "67139", "67141", "67144", "67146", "67148", "67149", "67152", "67153", "67155", "67157", "67158", "67160", "67162", "67163", "67165", "67168", "67169", "67172", "67173", "67174", "67175", "67176", "67177", "67181", "67182", "67184", "67185", "67186", "67187", "67189", "67190", "67191", "67192", "67193", "67194", "67197", "67199", "67200", "67203", "67204", "67206", "67207", "67208", "67210", "67211", "67213", "67214", "67215", "67216", "67217", "67218", "67219", "67222", "67224", "67226", "67228", "67229", "67234", "67235", "67240", "67243", "67244", "67245", "67247", "67248", "67249", "67252", "67253", "67254", "67255", "67262", "67266", "67268", "67271", "67274", "67276", "67277", "67279", "67283", "67284", "67285", "67286", "67289", "67290", "67291", "67292", "67295", "67297", "67298", "67299", "67301", "67302", "67303", "67304", "67309", "67310", "67313", "67317", "67318", "67319", "67320", "67322", "67324", "67326", "67329", "67332", "67338", "67341", "67344", "67346", "67347", "67350", "67352", "67354", "67356", "67357", "67358", "67359", "67363", "67365", "67366", "67370", "67371", "67372", "67373", "67375", "67376", "67378", "67379", "67380", "67381", "67384", "67385", "67387", "67388", "67392", "67394", "67395", "67396", "67400", "67401", "67402", "67403", "67404", "67405", "67409", "67410", "67412", "67414", "67416", "67417", "67419", "67421", "67423", "67426", "67427", "67431", "67433", "67437", "67439", "67441", "67442", "67443", "67446", "67448", "67453", "67454", "67460", "67461", "67462", "67463", "67465", "67466", "67467", "67468", "67472", "67475", "67479", "67480", "67483", "67485", "67486", "67487", "67488", "67491", "67494", "67500", "67502", "67503", "67507", "67510", "67512", "67513", "67514", "67515", "67516", "67518", "67521", "67523", "67526", "67527", "67529", "67530", "67531", "67533", "67534", "67535", "67536", "67537", "67542", "67543", "67544", "67545", "67547", "67548", "67551", "67554", "67556", "67562", "67563", "67565", "67566", "67569", "67570", "67572", "67573", "67575", "67577", "67578", "67579", "67580", "67582", "67586", "67588", "67589", "67590", "67591", "67592", "67594", "67596", "67599", "67601", "67604", "67605", "67606", "67608", "67609", "67615", "67617", "67619", "67620", "67622", "67624", "67625", "67626", "67627", "67629", "67630", "67636", "67639", "67640", "67641", "67643", "67648", "67649", "67651", "67652", "67655", "67656", "67657", "67658", "67660", "67661", "67665", "67669", "67672", "67673", "67675", "67676", "67678", "67679", "67682", "67685", "67688", "67693", "67698", "67701", "67702", "67703", "67707", "67709", "67710", "67712", "67716", "67719", "67721", "67723", "67724", "67726", "67728", "67729", "67731", "67735", "67741", "67743", "67744", "67746", "67747", "67751", "67753", "67755", "67757", "67759", "67761", "67762", "67765", "67770", "67775", "67776", "67777", "67778", "67781", "67782", "67783", "67784", "67788", "67790", "67791", "67792", "67793", "67798", "67801", "67802", "67804", "67805", "67806", "67809", "67810", "67813", "67814", "67815", "67817", "67818", "67819", "67820", "67821", "67822", "67823", "67824", "67825", "67826", "67827", "67828", "67829", "67830", "67831", "67832", "67834", "67836", "67839", "67840", "67841", "67844", "67849", "67850", "67851", "67852", "67853", "67859", "67862", "67864", "67868", "67869", "67871", "67872", "67873", "67875", "67878", "67881", "67882", "67883", "67888", "67891", "67895", "67898", "67904", "67909", "67911", "67914", "67916", "67918", "67921", "67927", "67929", "67931", "67932", "67933", "67937", "67938", "67943", "67944", "67946", "67948", "67949", "67950", "67951", "67952", "67953", "67954", "67956", "67959", "67964", "67968", "67971", "67972", "67975", "67976", "67977", "67978", "67979", "67981", "67985", "67986", "67987", "67988", "67989", "67991", "67993", "67996", "67997", "67999", "68001", "68003", "68005", "68007", "68008", "68010", "68011", "68012", "68014", "68016", "68019", "68020", "68021", "68022", "68023", "68026", "68028", "68029", "68030", "68031", "68032", "68035", "68036", "68039", "68042", "68044", "68045", "68047", "68053", "68054", "68056", "68059", "68060", "68061", "68064", "68065", "68066", "68067", "68068", "68069", "68070", "68074", "68077", "68078", "68080", "68081", "68082", "68083", "68086", "68091", "68092", "68094", "68096", "68102", "68104", "68105", "68107", "68108", "68109", "68110", "68111", "68112", "68113", "68115", "68118", "68122", "68123", "68124", "68125", "68126", "68127", "68129", "68131", "68138", "68140", "68142", "68146", "68147", "68152", "68155", "68159", "68161", "68162", "68165", "68166", "68168", "68169", "68170", "68173", "68177", "68178", "68179", "68180", "68185", "68186", "68187", "68189", "68191", "68195", "68196", "68197", "68199", "68201", "68202", "68203", "68204", "68205", "68206", "68207", "68209", "68211", "68214", "68215", "68216", "68217", "68220", "68221", "68222", "68224", "68228", "68229", "68231", "68232", "68233", "68238", "68240", "68242", "68244", "68245", "68246", "68247", "68248", "68249", "68250", "68251", "68254", "68255", "68256", "68265", "68266", "68267", "68268", "68269", "68270", "68271", "68273", "68275", "68276", "68277", "68278", "68279", "68280", "68281", "68284", "68285", "68290", "68294", "68295", "68298", "68299", "68300", "68301", "68302", "68303", "68305", "68307", "68308", "68310", "68311", "68319", "68321", "68323", "68324", "68325", "68326", "68328", "68329", "68330", "68331", "68336", "68337", "68338", "68339", "68340", "68344", "68346", "68349", "68350", "68351", "68353", "68355", "68359", "68360", "68361", "68362", "68363", "68365", "68367", "68368", "68369", "68372", "68375", "68376", "68377", "68378", "68380", "68381", "68385", "68386", "68388", "68391", "68394", "68395", "68397", "68400", "68401", "68402", "68404", "68406", "68407", "68409", "68410", "68411", "68413", "68414", "68416", "68417", "68418", "68419", "68420", "68422", "68424", "68425", "68426", "68427", "68429", "68430", "68432", "68435", "68437", "68441", "68445", "68447", "68448", "68449", "68450", "68452", "68453", "68454", "68455", "68458", "68459", "68460", "68462", "68464", "68465", "68466", "68470", "68471", "68472", "68473", "68477", "68479", "68481", "68486", "68487", "68493", "68494", "68496", "68497", "68498", "68499", "68501", "68504", "68505", "68507", "68508", "68510", "68511", "68513", "68516", "68518", "68519", "68520", "68521", "68523", "68529", "68531", "68532", "68534", "68538", "68542", "68544", "68547", "68550", "68554", "68561", "68562", "68564", "68565", "68567", "68568", "68570", "68571", "68573", "68576", "68579", "68581", "68583", "68584", "68586", "68587", "68591", "68594", "68596", "68597", "68600", "68603", "68606", "68607", "68608", "68610", "68613", "68614", "68617", "68619", "68620", "68623", "68625", "68628", "68634", "68635", "68636", "68637", "68638", "68640", "68642", "68643", "68645", "68646", "68647", "68648", "68650", "68651", "68652", "68653", "68656", "68657", "68658", "68659", "68660", "68661", "68662", "68665", "68666", "68671", "68672", "68674", "68678", "68679", "68682", "68685", "68686", "68687", "68689", "68692", "68693", "68695", "68696", "68698", "68700", "68701", "68703", "68706", "68708", "68710", "68713", "68714", "68717", "68718", "68719", "68721", "68723", "68725", "68727", "68728", "68729", "68733", "68739", "68742", "68744", "68752", "68754", "68755", "68759", "68762", "68764", "68765", "68766", "68769", "68770", "68771", "68772", "68773", "68775", "68776", "68778", "68779", "68780", "68785", "68786", "68787", "68789", "68791", "68793", "68795", "68796", "68797", "68799", "68800", "68801", "68803", "68805", "68806", "68809", "68810", "68812", "68814", "68817", "68820", "68822", "68824", "68825", "68829", "68834", "68836", "68841", "68844", "68846", "68849", "68850", "68851", "68852", "68853", "68856", "68861", "68862", "68864", "68865", "68867", "68872", "68873", "68875", "68876", "68877", "68880", "68881", "68888", "68890", "68892", "68893", "68894", "68896", "68899", "68901", "68904", "68911", "68916", "68917", "68920", "68922", "68923", "68924", "68925", "68927", "68930", "68931", "68933", "68934", "68935", "68937", "68941", "68942", "68944", "68947", "68950", "68952", "68954", "68955", "68956", "68957", "68958", "68962", "68963", "68966", "68967", "68971", "68973", "68975", "68976", "68977", "68979", "68983", "68986", "68989", "68990", "68992", "68993", "68994", "68995", "68999", "69001", "69008", "69009", "69012", "69014", "69016", "69017", "69018", "69020", "69024", "69025", "69027", "69030", "69032", "69036", "69039", "69042", "69043", "69044", "69046", "69048", "69051", "69053", "69054", "69057", "69058", "69063", "69064", "69065", "69066", "69067", "69068", "69070", "69071", "69072", "69075", "69077", "69081", "69084", "69085", "69086", "69087", "69090", "69092", "69093", "69094", "69099", "69100", "69102", "69106", "69108", "69109", "69110", "69114", "69116", "69119", "69122", "69123", "69126", "69127", "69128", "69129", "69130", "69132", "69136", "69137", "69139", "69140", "69141", "69142", "69144", "69149", "69150", "69151", "69152", "69153", "69157", "69160", "69162", "69163", "69164", "69167", "69171", "69173", "69174", "69177", "69178", "69180", "69181", "69183", "69185", "69186", "69188", "69189", "69194", "69195", "69196", "69197", "69198", "69199", "69201", "69202", "69203", "69204", "69205", "69206", "69207", "69208", "69209", "69210", "69211", "69212", "69214", "69215", "69218", "69220", "69221", "69222", "69226", "69228", "69229", "69231", "69234", "69236", "69237", "69238", "69243", "69244", "69245", "69246", "69250", "69254", "69255", "69256", "69257", "69258", "69263", "69265", "69266", "69270", "69271", "69272", "69274", "69286", "69287", "69288", "69290", "69292", "69294", "69297", "69298", "69299", "69300", "69301", "69302", "69303", "69304", "69305", "69310", "69311", "69312", "69316", "69317", "69318", "69320", "69323", "69324", "69325", "69326", "69328", "69329", "69330", "69332", "69333", "69342", "69344", "69345", "69346", "69347", "69349", "69350", "69352", "69353", "69355", "69356", "69358", "69360", "69361", "69362", "69364", "69365", "69366", "69368", "69369", "69370", "69371", "69372", "69374", "69375", "69385", "69386", "69388", "69391", "69396", "69403", "69405", "69406", "69410", "69411", "69412", "69413", "69415", "69419", "69420", "69421", "69422", "69423", "69427", "69428", "69432", "69433", "69434", "69436", "69440", "69441", "69443", "69446", "69447", "69449", "69451", "69453", "69455", "69456", "69457", "69458", "69459", "69463", "69464", "69465", "69467", "69469", "69472", "69474", "69477", "69478", "69482", "69483", "69490", "69491", "69492", "69499", "69501", "69505", "69512", "69515", "69521", "69523", "69530", "69532", "69533", "69537", "69539", "69540", "69541", "69542", "69544", "69547", "69549", "69550", "69551", "69552", "69553", "69561", "69562", "69565", "69566", "69568", "69569", "69571", "69573", "69575", "69577", "69578", "69580", "69581", "69583", "69584", "69587", "69588", "69589", "69592", "69595", "69596", "69597", "69598", "69600", "69603", "69605", "69607", "69613", "69614", "69615", "69616", "69617", "69619", "69620", "69622", "69623", "69624", "69625", "69626", "69627", "69628", "69629", "69631", "69639", "69644", "69645", "69647", "69652", "69654", "69655", "69656", "69664", "69667", "69668", "69670", "69673", "69674", "69675", "69676", "69678", "69681", "69683", "69685", "69686", "69689", "69693", "69694", "69695", "69697", "69698", "69699", "69701", "69703", "69706", "69711", "69713", "69714", "69715", "69716", "69717", "69719", "69721", "69722", "69723", "69724", "69725", "69727", "69728", "69729", "69733", "69735", "69736", "69737", "69738", "69743", "69744", "69747", "69749", "69754", "69759", "69760", "69763", "69764", "69766", "69767", "69770", "69772", "69775", "69776", "69778", "69779", "69780", "69781", "69783", "69787", "69788", "69791", "69792", "69794", "69797", "69800", "69801", "69802", "69804", "69805", "69807", "69808", "69811", "69814", "69815", "69816", "69822", "69827", "69829", "69830", "69835", "69840", "69841", "69845", "69846", "69847", "69848", "69853", "69857", "69859", "69862", "69868", "69870", "69871", "69876", "69878", "69879", "69880", "69887", "69893", "69894", "69896", "69901", "69903", "69904", "69905", "69907", "69912", "69913", "69914", "69919", "69920", "69921", "69922", "69923", "69925", "69926", "69928", "69929", "69930", "69933", "69934", "69935", "69937", "69938", "69942", "69943", "69944", "69946", "69947", "69951", "69952", "69953", "69956", "69957", "69960", "69963", "69967", "69969", "69970", "69972", "69973", "69974", "69976", "69983", "69985", "69989", "69991", "69993", "69995", "69999", "70001", "70003", "70004", "70005", "70008", "70009", "70010", "70011", "70012", "70015", "70017", "70018", "70019", "70021", "70022", "70025", "70028", "70034", "70035", "70037", "70038", "70039", "70041", "70043", "70044", "70045", "70046", "70050", "70052", "70057", "70062", "70063", "70071", "70072", "70076", "70079", "70080", "70081", "70082", "70083", "70084", "70085", "70090", "70093", "70096", "70099", "70102", "70103", "70106", "70107", "70108", "70109", "70111", "70112", "70115", "70116", "70119", "70121", "70122", "70124", "70125", "70127", "70130", "70132", "70134", "70135", "70137", "70140", "70141", "70142", "70143", "70148", "70149", "70150", "70151", "70157", "70159", "70160", "70162", "70163", "70164", "70166", "70167", "70168", "70171", "70172", "70179", "70181", "70182", "70183", "70184", "70185", "70187", "70189", "70191", "70193", "70194", "70196", "70197", "70198", "70202", "70203", "70207", "70208", "70212", "70214", "70217", "70218", "70219", "70221", "70223", "70225", "70226", "70228", "70229", "70230", "70240", "70241", "70242", "70244", "70245", "70248", "70249", "70250", "70251", "70252", "70253", "70254", "70256", "70257", "70261", "70263", "70264", "70267", "70268", "70269", "70271", "70272", "70273", "70274", "70276", "70277", "70280", "70281", "70282", "70283", "70284", "70285", "70287", "70295", "70297", "70299", "70300", "70301", "70305", "70308", "70309", "70310", "70313", "70315", "70316", "70320", "70321", "70323", "70324", "70325", "70326", "70327", "70328", "70329", "70332", "70336", "70338", "70339", "70340", "70341", "70342", "70347", "70348", "70349", "70350", "70351", "70353", "70355", "70357", "70360", "70362", "70363", "70365", "70366", "70367", "70368", "70369", "70370", "70371", "70372", "70374", "70375", "70376", "70379", "70380", "70381", "70382", "70383", "70384", "70385", "70386", "70387", "70393", "70395", "70397", "70398", "70399", "70400", "70403", "70406", "70407", "70408", "70410", "70413", "70415", "70417", "70418", "70419", "70420", "70421", "70422", "70423", "70424", "70426", "70427", "70429", "70430", "70431", "70433", "70434", "70436", "70439", "70440", "70442", "70444", "70447", "70450", "70451", "70453", "70455", "70459", "70463", "70464", "70465", "70467", "70468", "70469", "70471", "70472", "70474", "70475", "70476", "70478", "70479", "70480", "70482", "70485", "70486", "70487", "70490", "70491", "70495", "70496", "70497", "70498", "70500", "70502", "70507", "70508", "70509", "70510", "70512", "70516", "70517", "70518", "70519", "70520", "70521", "70525", "70527", "70528", "70529", "70532", "70533", "70536", "70538", "70541", "70542", "70543", "70545", "70547", "70549", "70550", "70552", "70553", "70555", "70564", "70565", "70567", "70568", "70569", "70571", "70572", "70575", "70578", "70580", "70581", "70582", "70583", "70584", "70587", "70589", "70590", "70591", "70593", "70595", "70596", "70598", "70599", "70602", "70604", "70605", "70607", "70608", "70612", "70614", "70615", "70616", "70618", "70619", "70620", "70624", "70627", "70628", "70629", "70630", "70631", "70632", "70634", "70636", "70639", "70642", "70643", "70644", "70645", "70647", "70648", "70650", "70652", "70653", "70654", "70657", "70658", "70660", "70661", "70665", "70670", "70671", "70672", "70674", "70675", "70678", "70679", "70680", "70681", "70683", "70684", "70685", "70686", "70687", "70688", "70692", "70695", "70697", "70698", "70700", "70702", "70703", "70704", "70706", "70707", "70712", "70713", "70714", "70715", "70716", "70717", "70721", "70723", "70724", "70725", "70728", "70731", "70736", "70739", "70740", "70742", "70746", "70747", "70749", "70750", "70753", "70754", "70755", "70756", "70760", "70763", "70764", "70765", "70767", "70768", "70769", "70770", "70771", "70773", "70774", "70775", "70776", "70778", "70779", "70780", "70781", "70782", "70784", "70786", "70787", "70789", "70790", "70791", "70793", "70794", "70796", "70798", "70800", "70804", "70805", "70807", "70810", "70811", "70812", "70814", "70815", "70816", "70817", "70818", "70820", "70821", "70826", "70827", "70828", "70829", "70830", "70832", "70834", "70837", "70838", "70839", "70840", "70841", "70842", "70845", "70847", "70851", "70852", "70853", "70855", "70858", "70859", "70860", "70862", "70863", "70865", "70866", "70867", "70868", "70869", "70870", "70871", "70873", "70876", "70877", "70881", "70882", "70884", "70886", "70890", "70891", "70892", "70894", "70895", "70896", "70898", "70901", "70905", "70906", "70909", "70911", "70914", "70916", "70919", "70922", "70927", "70930", "70931", "70935", "70938", "70939", "70940", "70945", "70946", "70947", "70948", "70951", "70953", "70954", "70956", "70957", "70958", "70961", "70962", "70963", "70967", "70969", "70971", "70973", "70977", "70979", "70981", "70983", "70985", "70987", "70988", "70989", "70990", "70991", "70993", "70994", "70995", "70997", "70998", "71001", "71004", "71006", "71007", "71008", "71010", "71012", "71013", "71014", "71015", "71020", "71021", "71023", "71029", "71030", "71033", "71035", "71037", "71038", "71040", "71041", "71042", "71043", "71044", "71045", "71046", "71050", "71051", "71054", "71057", "71058", "71059", "71060", "71064", "71065", "71066", "71067", "71069", "71070", "71073", "71075", "71076", "71077", "71080", "71081", "71082", "71084", "71085", "71086", "71087", "71089", "71090", "71091", "71094", "71097", "71098", "71099", "71101", "71102", "71105", "71106", "71107", "71109", "71110", "71111", "71113", "71115", "71122", "71126", "71127", "71129", "71130", "71131", "71132", "71134", "71135", "71138", "71145", "71146", "71147", "71152", "71154", "71155", "71156", "71157", "71158", "71160", "71161", "71162", "71164", "71165", "71166", "71169", "71170", "71173", "71175", "71180", "71181", "71182", "71183", "71185", "71186", "71187", "71189", "71190", "71192", "71193", "71197", "71198", "71200", "71205", "71207", "71208", "71209", "71210", "71211", "71213", "71214", "71215", "71217", "71218", "71219", "71220", "71221", "71222", "71223", "71225", "71226", "71227", "71228", "71230", "71231", "71232", "71235", "71239", "71240", "71241", "71243", "71246", "71247", "71249", "71250", "71255", "71258", "71260", "71261", "71266", "71269", "71270", "71272", "71274", "71275", "71276", "71282", "71284", "71287", "71291", "71293", "71296", "71297", "71298", "71299", "71300", "71302", "71304", "71305", "71306", "71308", "71312", "71317", "71320", "71333", "71334", "71336", "71337", "71338", "71342", "71345", "71347", "71350", "71353", "71354", "71355", "71357", "71360", "71361", "71366", "71368", "71369", "71371", "71372", "71373", "71376", "71377", "71378", "71379", "71380", "71381", "71387", "71388", "71389", "71390", "71392", "71394", "71395", "71396", "71399", "71401", "71406", "71409", "71411", "71412", "71420", "71422", "71423", "71424", "71425", "71427", "71428", "71431", "71433", "71434", "71437", "71438", "71439", "71441", "71442", "71445", "71449", "71455", "71456", "71457", "71458", "71463", "71467", "71468", "71475", "71478", "71479", "71480", "71482", "71483", "71484", "71485", "71486", "71487", "71488", "71490", "71493", "71494", "71497", "71499", "71500", "71501", "71505", "71507", "71508", "71515", "71517", "71519", "71520", "71521", "71523", "71526", "71528", "71529", "71532", "71536", "71537", "71538", "71539", "71541", "71542", "71543", "71545", "71553", "71554", "71555", "71556", "71557", "71561", "71562", "71564", "71565", "71566", "71567", "71568", "71570", "71571", "71576", "71577", "71578", "71579", "71581", "71582", "71583", "71584", "71585", "71586", "71587", "71588", "71592", "71593", "71595", "71596", "71598", "71599", "71601", "71603", "71604", "71605", "71609", "71610", "71613", "71615", "71617", "71618", "71621", "71623", "71625", "71627", "71628", "71630", "71631", "71632", "71634", "71635", "71636", "71637", "71639", "71641", "71642", "71643", "71644", "71645", "71647", "71650", "71652", "71653", "71658", "71662", "71664", "71665", "71667", "71669", "71673", "71675", "71678", "71679", "71680", "71681", "71682", "71685", "71689", "71690", "71692", "71695", "71696", "71697", "71698", "71700", "71701", "71702", "71703", "71707", "71708", "71712", "71716", "71720", "71721", "71722", "71723", "71725", "71726", "71727", "71729", "71731", "71732", "71734", "71737", "71738", "71739", "71741", "71742", "71746", "71747", "71750", "71751", "71755", "71756", "71757", "71758", "71760", "71762", "71764", "71768", "71769", "71770", "71775", "71776", "71781", "71782", "71784", "71785", "71786", "71789", "71793", "71794", "71796", "71797", "71798", "71800", "71801", "71806", "71807", "71808", "71811", "71813", "71819", "71820", "71821", "71823", "71827", "71828", "71830", "71832", "71833", "71834", "71835", "71837", "71838", "71839", "71840", "71841", "71842", "71844", "71845", "71846", "71852", "71853", "71854", "71855", "71856", "71857", "71858", "71862", "71864", "71865", "71869", "71873", "71877", "71878", "71879", "71883", "71885", "71886", "71891", "71893", "71895", "71896", "71897", "71898", "71901", "71902", "71903", "71905", "71907", "71908", "71911", "71912", "71913", "71914", "71916", "71919", "71923", "71924", "71926", "71927", "71928", "71932", "71934", "71938", "71941", "71945", "71947", "71949", "71950", "71953", "71954", "71958", "71960", "71961", "71962", "71966", "71968", "71969", "71971", "71972", "71976", "71979", "71981", "71985", "71986", "71987", "71989", "71992", "71995", "71996", "71998", "71999", "72002", "72004", "72005", "72007", "72008", "72009", "72010", "72011", "72014", "72015", "72017", "72018", "72019", "72021", "72022", "72023", "72025", "72026", "72027", "72031", "72032", "72033", "72034", "72035", "72037", "72039", "72042", "72044", "72045", "72050", "72051", "72055", "72057", "72059", "72063", "72064", "72065", "72066", "72069", "72070", "72072", "72073", "72074", "72075", "72076", "72079", "72083", "72085", "72086", "72088", "72090", "72092", "72096", "72097", "72099", "72100", "72101", "72102", "72103", "72104", "72107", "72110", "72111", "72112", "72117", "72121", "72123", "72125", "72134", "72136", "72138", "72140", "72142", "72143", "72146", "72148", "72149", "72150", "72155", "72157", "72159", "72164", "72167", "72170", "72172", "72173", "72175", "72177", "72178", "72180", "72182", "72185", "72188", "72189", "72190", "72191", "72192", "72195", "72196", "72197", "72200", "72202", "72204", "72206", "72208", "72209", "72211", "72212", "72213", "72214", "72215", "72216", "72217", "72222", "72225", "72228", "72231", "72232", "72233", "72236", "72238", "72239", "72241", "72244", "72246", "72247", "72252", "72254", "72255", "72257", "72258", "72259", "72261", "72262", "72263", "72266", "72268", "72270", "72272", "72273", "72277", "72280", "72281", "72285", "72286", "72287", "72288", "72291", "72294", "72295", "72296", "72297", "72299", "72301", "72303", "72305", "72309", "72312", "72318", "72322", "72323", "72326", "72327", "72329", "72331", "72332", "72333", "72334", "72335", "72336", "72339", "72343", "72345", "72346", "72347", "72348", "72350", "72352", "72353", "72354", "72355", "72359", "72360", "72363", "72364", "72365", "72366", "72367", "72368", "72370", "72371", "72372", "72374", "72376", "72377", "72379", "72382", "72383", "72386", "72387", "72388", "72389", "72394", "72397", "72398", "72399", "72400", "72401", "72402", "72406", "72410", "72411", "72417", "72419", "72420", "72423", "72424", "72425", "72427", "72429", "72432", "72433", "72434", "72435", "72436", "72437", "72444", "72445", "72448", "72451", "72452", "72453", "72454", "72455", "72460", "72462", "72464", "72465", "72468", "72470", "72472", "72478", "72479", "72480", "72481", "72482", "72484", "72488", "72489", "72492", "72493", "72494", "72498", "72499", "72502", "72504", "72505", "72508", "72509", "72510", "72512", "72513", "72519", "72520", "72521", "72522", "72525", "72529", "72532", "72534", "72537", "72538", "72539", "72540", "72541", "72542", "72545", "72546", "72547", "72548", "72549", "72550", "72552", "72554", "72560", "72562", "72564", "72567", "72572", "72574", "72578", "72580", "72581", "72584", "72589", "72591", "72592", "72594", "72595", "72596", "72597", "72600", "72601", "72604", "72605", "72607", "72608", "72609", "72611", "72615", "72616", "72619", "72620", "72621", "72623", "72628", "72631", "72634", "72635", "72637", "72638", "72642", "72645", "72646", "72647", "72648", "72649", "72652", "72653", "72654", "72656", "72657", "72658", "72659", "72660", "72661", "72664", "72667", "72671", "72673", "72674", "72676", "72677", "72678", "72679", "72684", "72685", "72687", "72688", "72690", "72692", "72693", "72695", "72701", "72702", "72703", "72705", "72708", "72710", "72711", "72712", "72713", "72714", "72717", "72720", "72724", "72728", "72729", "72730", "72732", "72733", "72734", "72735", "72737", "72738", "72743", "72745", "72747", "72748", "72751", "72753", "72754", "72755", "72756", "72757", "72758", "72759", "72760", "72763", "72768", "72770", "72771", "72772", "72773", "72774", "72775", "72777", "72778", "72781", "72785", "72786", "72787", "72788", "72789", "72790", "72791", "72792", "72794", "72795", "72796", "72797", "72800", "72801", "72803", "72804", "72805", "72806", "72808", "72809", "72810", "72811", "72812", "72814", "72816", "72818", "72819", "72825", "72826", "72828", "72830", "72831", "72833", "72834", "72836", "72837", "72840", "72841", "72842", "72845", "72847", "72849", "72850", "72852", "72858", "72860", "72864", "72865", "72866", "72867", "72868", "72872", "72874", "72876", "72878", "72879", "72882", "72885", "72891", "72893", "72897", "72898", "72901", "72902", "72903", "72906", "72909", "72912", "72913", "72915", "72917", "72925", "72929", "72930", "72931", "72932", "72936", "72939", "72941", "72944", "72947", "72951", "72956", "72957", "72958", "72963", "72964", "72967", "72968", "72969", "72970", "72971", "72973", "72975", "72981", "72985", "72990", "72994", "72996", "72997", "72998", "73000", "73001", "73003", "73005", "73008", "73011", "73013", "73014", "73015", "73017", "73018", "73019", "73020", "73021", "73024", "73027", "73034", "73035", "73036", "73037", "73039", "73040", "73043", "73045", "73046", "73047", "73048", "73049", "73050", "73053", "73057", "73058", "73059", "73061", "73062", "73064", "73067", "73068", "73069", "73070", "73071", "73072", "73074", "73075", "73079", "73080", "73081", "73083", "73084", "73086", "73088", "73089", "73092", "73101", "73103", "73105", "73107", "73112", "73114", "73115", "73116", "73119", "73120", "73122", "73125", "73129", "73132", "73134", "73135", "73137", "73138", "73145", "73146", "73147", "73151", "73153", "73154", "73155", "73158", "73161", "73163", "73166", "73167", "73168", "73169", "73170", "73172", "73175", "73176", "73177", "73178", "73179", "73180", "73183", "73184", "73186", "73190", "73191", "73194", "73195", "73197", "73200", "73201", "73204", "73206", "73208", "73211", "73213", "73215", "73221", "73223", "73227", "73228", "73230", "73232", "73235", "73237", "73238", "73243", "73245", "73247", "73249", "73251", "73252", "73254", "73259", "73260", "73265", "73267", "73268", "73269", "73273", "73276", "73277", "73279", "73280", "73281", "73282", "73284", "73286", "73287", "73288", "73289", "73290", "73291", "73295", "73296", "73298", "73299", "73303", "73304", "73306", "73307", "73312", "73313", "73314", "73315", "73316", "73319", "73322", "73323", "73324", "73328", "73329", "73331", "73332", "73334", "73335", "73336", "73337", "73338", "73346", "73349", "73351", "73353", "73355", "73361", "73362", "73364", "73365", "73368", "73373", "73375", "73378", "73385", "73387", "73388", "73389", "73392", "73394", "73396", "73400", "73401", "73403", "73404", "73405", "73407", "73408", "73410", "73412", "73413", "73414", "73416", "73417", "73419", "73420", "73421", "73423", "73424", "73425", "73427", "73430", "73432", "73435", "73436", "73439", "73441", "73442", "73444", "73445", "73446", "73448", "73451", "73452", "73454", "73456", "73457", "73458", "73459", "73460", "73462", "73464", "73467", "73468", "73471", "73475", "73476", "73477", "73482", "73483", "73485", "73486", "73487", "73489", "73493", "73495", "73500", "73504", "73506", "73507", "73508", "73511", "73516", "73519", "73520", "73522", "73523", "73526", "73528", "73530", "73531", "73532", "73533", "73535", "73536", "73541", "73542", "73544", "73545", "73546", "73548", "73550", "73551", "73554", "73555", "73557", "73558", "73559", "73561", "73562", "73563", "73564", "73568", "73572", "73576", "73577", "73581", "73583", "73584", "73589", "73590", "73591", "73592", "73593", "73595", "73596", "73601", "73605", "73606", "73608", "73613", "73616", "73617", "73618", "73619", "73621", "73622", "73623", "73629", "73630", "73631", "73632", "73636", "73639", "73641", "73644", "73648", "73655", "73658", "73660", "73661", "73663", "73667", "73668", "73669", "73671", "73672", "73675", "73677", "73678", "73679", "73685", "73687", "73690", "73692", "73693", "73696", "73698", "73699", "73700", "73702", "73703", "73706", "73707", "73708", "73710", "73712", "73719", "73720", "73723", "73724", "73727", "73728", "73729", "73730", "73731", "73733", "73735", "73736", "73738", "73739", "73740", "73741", "73742", "73745", "73747", "73748", "73750", "73752", "73753", "73755", "73757", "73758", "73759", "73760", "73761", "73762", "73763", "73764", "73766", "73767", "73768", "73770", "73773", "73776", "73778", "73779", "73780", "73785", "73786", "73788", "73790", "73791", "73792", "73795", "73796", "73800", "73801", "73802", "73803", "73804", "73806", "73807", "73808", "73810", "73812", "73815", "73816", "73821", "73825", "73826", "73829", "73830", "73832", "73836", "73837", "73840", "73841", "73842", "73843", "73844", "73845", "73847", "73849", "73851", "73852", "73853", "73855", "73856", "73857", "73858", "73860", "73861", "73862", "73863", "73865", "73866", "73869", "73870", "73871", "73872", "73873", "73876", "73878", "73886", "73887", "73888", "73892", "73894", "73896", "73898", "73899", "73900", "73901", "73902", "73903", "73904", "73905", "73906", "73907", "73908", "73916", "73918", "73919", "73922", "73923", "73925", "73926", "73927", "73928", "73933", "73936", "73937", "73940", "73942", "73946", "73947", "73948", "73949", "73950", "73951", "73956", "73957", "73958", "73961", "73963", "73964", "73969", "73972", "73973", "73976", "73978", "73979", "73980", "73985", "73989", "73990", "73991", "73992", "73993", "73994", "73997", "74000", "74001", "74002", "74003", "74004", "74005", "74007", "74008", "74014", "74015", "74018", "74021", "74022", "74023", "74026", "74027", "74034", "74036", "74038", "74043", "74045", "74046", "74047", "74049", "74052", "74053", "74057", "74060", "74061", "74062", "74063", "74066", "74072", "74073", "74074", "74076", "74077", "74078", "74079", "74080", "74084", "74087", "74089", "74090", "74091", "74093", "74096", "74097", "74098", "74100", "74101", "74102", "74103", "74105", "74109", "74110", "74111", "74114", "74115", "74125", "74126", "74127", "74128", "74129", "74131", "74133", "74136", "74137", "74138", "74140", "74142", "74143", "74145", "74147", "74148", "74149", "74153", "74154", "74155", "74159", "74163", "74164", "74165", "74166", "74167", "74169", "74170", "74173", "74175", "74178", "74179", "74183", "74184", "74187", "74194", "74195", "74196", "74197", "74198", "74199", "74201", "74204", "74206", "74207", "74208", "74210", "74212", "74214", "74215", "74217", "74218", "74221", "74228", "74229", "74234", "74237", "74239", "74241", "74242", "74243", "74246", "74247", "74250", "74251", "74254", "74255", "74257", "74258", "74259", "74260", "74269", "74272", "74273", "74274", "74275", "74277", "74278", "74281", "74283", "74284", "74290", "74293", "74294", "74296", "74297", "74298", "74301", "74304", "74305", "74308", "74311", "74314", "74316", "74318", "74320", "74323", "74324", "74329", "74330", "74332", "74333", "74338", "74339", "74340", "74341", "74342", "74344", "74346", "74348", "74351", "74352", "74354", "74355", "74356", "74358", "74359", "74361", "74364", "74367", "74370", "74374", "74380", "74383", "74385", "74387", "74388", "74391", "74394", "74395", "74396", "74397", "74398", "74399", "74400", "74403", "74405", "74406", "74407", "74408", "74413", "74414", "74415", "74417", "74418", "74419", "74421", "74422", "74425", "74427", "74429", "74431", "74434", "74435", "74437", "74440", "74442", "74443", "74445", "74446", "74447", "74449", "74450", "74451", "74452", "74453", "74456", "74458", "74459", "74460", "74461", "74462", "74465", "74466", "74473", "74474", "74477", "74479", "74481", "74483", "74485", "74486", "74490", "74491", "74492", "74495", "74496", "74501", "74505", "74506", "74507", "74508", "74509", "74511", "74512", "74513", "74515", "74517", "74520", "74522", "74523", "74527", "74530", "74532", "74537", "74538", "74539", "74540", "74541", "74551", "74555", "74556", "74557", "74558", "74559", "74560", "74561", "74562", "74565", "74566", "74573", "74574", "74578", "74581", "74585", "74588", "74590", "74591", "74593", "74594", "74597", "74599", "74600", "74603", "74606", "74607", "74611", "74617", "74619", "74623", "74624", "74627", "74628", "74629", "74633", "74635", "74637", "74638", "74640", "74644", "74651", "74656", "74657", "74658", "74659", "74661", "74663", "74664", "74669", "74670", "74671", "74673", "74679", "74681", "74683", "74685", "74687", "74693", "74695", "74697", "74699", "74701", "74702", "74703", "74704", "74705", "74707", "74709", "74710", "74711", "74712", "74714", "74716", "74718", "74719", "74727", "74728", "74734", "74735", "74737", "74738", "74740", "74741", "74743", "74744", "74745", "74746", "74747", "74748", "74749", "74751", "74752", "74755", "74756", "74758", "74759", "74760", "74761", "74762", "74765", "74768", "74769", "74771", "74774", "74778", "74779", "74781", "74783", "74784", "74786", "74791", "74795", "74797", "74798", "74810", "74811", "74812", "74814", "74816", "74817", "74819", "74821", "74824", "74825", "74826", "74828", "74829", "74835", "74837", "74839", "74840", "74844", "74845", "74846", "74847", "74848", "74849", "74850", "74851", "74856", "74857", "74859", "74860", "74862", "74863", "74866", "74869", "74870", "74872", "74873", "74875", "74878", "74879", "74880", "74881", "74883", "74885", "74889", "74891", "74893", "74897", "74899", "74902", "74903", "74906", "74908", "74909", "74910", "74911", "74912", "74913", "74916", "74919", "74920", "74921", "74928", "74929", "74933", "74934", "74935", "74937", "74945", "74946", "74947", "74950", "74952", "74953", "74957", "74958", "74959", "74960", "74961", "74963", "74964", "74968", "74970", "74973", "74975", "74977", "74978", "74980", "74983", "74986", "74989", "74991", "74993", "74996", "75001", "75004", "75005", "75006", "75007", "75010", "75011", "75013", "75016", "75019", "75020", "75022", "75024", "75025", "75026", "75027", "75029", "75031", "75033", "75035", "75037", "75039", "75040", "75042", "75043", "75046", "75048", "75050", "75054", "75055", "75058", "75060", "75061", "75062", "75063", "75064", "75069", "75070", "75073", "75074", "75077", "75079", "75080", "75083", "75087", "75088", "75089", "75091", "75092", "75095", "75098", "75100", "75101", "75102", "75103", "75104", "75105", "75106", "75110", "75111", "75115", "75118", "75121", "75122", "75124", "75126", "75127", "75128", "75129", "75131", "75136", "75137", "75148", "75149", "75152", "75153", "75155", "75161", "75162", "75163", "75168", "75169", "75174", "75175", "75178", "75179", "75181", "75182", "75184", "75185", "75187", "75191", "75195", "75196", "75198", "75199", "75201", "75203", "75204", "75206", "75207", "75208", "75210", "75211", "75212", "75214", "75215", "75216", "75217", "75219", "75220", "75222", "75227", "75229", "75230", "75233", "75240", "75243", "75245", "75247", "75248", "75250", "75251", "75252", "75253", "75254", "75255", "75256", "75257", "75258", "75260", "75262", "75264", "75266", "75267", "75273", "75276", "75277", "75278", "75280", "75281", "75282", "75285", "75289", "75291", "75292", "75293", "75294", "75295", "75296", "75297", "75298", "75299", "75303", "75304", "75306", "75308", "75316", "75317", "75320", "75322", "75323", "75332", "75333", "75334", "75339", "75342", "75343", "75345", "75346", "75347", "75348", "75352", "75354", "75358", "75360", "75362", "75364", "75365", "75366", "75368", "75370", "75371", "75372", "75373", "75375", "75378", "75379", "75380", "75381", "75386", "75387", "75389", "75393", "75394", "75396", "75397", "75399", "75400", "75401", "75403", "75404", "75408", "75412", "75413", "75414", "75415", "75416", "75417", "75418", "75419", "75422", "75425", "75426", "75429", "75431", "75433", "75435", "75436", "75437", "75438", "75439", "75441", "75442", "75446", "75449", "75450", "75451", "75452", "75456", "75457", "75460", "75462", "75463", "75465", "75467", "75468", "75470", "75472", "75473", "75474", "75475", "75476", "75477", "75479", "75482", "75486", "75487", "75489", "75490", "75491", "75493", "75497", "75499", "75503", "75506", "75508", "75509", "75510", "75512", "75514", "75515", "75518", "75521", "75523", "75524", "75526", "75529", "75531", "75532", "75535", "75538", "75545", "75547", "75548", "75553", "75554", "75555", "75556", "75560", "75562", "75564", "75565", "75566", "75567", "75568", "75570", "75571", "75574", "75575", "75576", "75578", "75580", "75582", "75584", "75589", "75591", "75592", "75594", "75596", "75597", "75600", "75602", "75607", "75608", "75609", "75612", "75613", "75614", "75617", "75623", "75624", "75625", "75627", "75628", "75632", "75634", "75639", "75641", "75643", "75646", "75649", "75650", "75657", "75658", "75659", "75666", "75669", "75672", "75674", "75676", "75678", "75679", "75680", "75681", "75682", "75683", "75688", "75692", "75693", "75694", "75697", "75700", "75701", "75706", "75708", "75710", "75711", "75713", "75714", "75716", "75718", "75719", "75720", "75722", "75725", "75729", "75730", "75732", "75735", "75736", "75737", "75738", "75739", "75741", "75744", "75745", "75748", "75752", "75754", "75757", "75758", "75760", "75762", "75763", "75765", "75769", "75770", "75772", "75773", "75777", "75779", "75780", "75782", "75786", "75787", "75789", "75792", "75794", "75797", "75800", "75801", "75804", "75812", "75813", "75814", "75817", "75818", "75819", "75820", "75821", "75823", "75825", "75828", "75830", "75831", "75834", "75835", "75836", "75837", "75838", "75840", "75844", "75845", "75846", "75847", "75848", "75849", "75850", "75851", "75854", "75856", "75859", "75860", "75861", "75868", "75869", "75870", "75871", "75879", "75883", "75884", "75886", "75887", "75888", "75891", "75892", "75896", "75897", "75899", "75903", "75904", "75905", "75911", "75913", "75914", "75916", "75917", "75920", "75922", "75923", "75925", "75928", "75929", "75930", "75932", "75937", "75938", "75939", "75943", "75949", "75953", "75954", "75957", "75959", "75960", "75962", "75964", "75965", "75966", "75969", "75971", "75973", "75974", "75975", "75977", "75978", "75981", "75983", "75987", "75996", "75997", "75999", "76000", "76001", "76004", "76010", "76013", "76018", "76020", "76021", "76023", "76024", "76025", "76027", "76028", "76030", "76032", "76034", "76035", "76038", "76039", "76040", "76041", "76042", "76046", "76048", "76051", "76052", "76053", "76054", "76055", "76056", "76057", "76060", "76062", "76063", "76070", "76071", "76073", "76075", "76076", "76078", "76082", "76083", "76089", "76092", "76093", "76096", "76099", "76100", "76102", "76103", "76104", "76106", "76109", "76112", "76114", "76117", "76118", "76119", "76120", "76123", "76126", "76129", "76136", "76137", "76140", "76141", "76143", "76144", "76147", "76148", "76149", "76151", "76153", "76157", "76160", "76162", "76164", "76166", "76167", "76169", "76170", "76172", "76174", "76176", "76177", "76178", "76179", "76181", "76185", "76186", "76187", "76188", "76189", "76190", "76191", "76195", "76197", "76198", "76199", "76201", "76202", "76203", "76204", "76205", "76208", "76210", "76212", "76215", "76218", "76220", "76222", "76223", "76224", "76225", "76226", "76227", "76228", "76236", "76237", "76238", "76239", "76240", "76241", "76242", "76246", "76247", "76248", "76249", "76251", "76252", "76253", "76255", "76256", "76258", "76259", "76263", "76265", "76266", "76267", "76270", "76274", "76275", "76278", "76279", "76283", "76289", "76290", "76293", "76294", "76296", "76299", "76301", "76304", "76305", "76307", "76308", "76309", "76310", "76311", "76313", "76314", "76315", "76319", "76321", "76322", "76326", "76327", "76328", "76330", "76338", "76341", "76345", "76347", "76349", "76350", "76352", "76358", "76359", "76361", "76362", "76366", "76368", "76371", "76373", "76378", "76383", "76385", "76387", "76388", "76389", "76390", "76391", "76395", "76396", "76399", "76402", "76403", "76404", "76410", "76411", "76412", "76413", "76414", "76415", "76418", "76419", "76420", "76421", "76422", "76426", "76427", "76429", "76432", "76438", "76439", "76441", "76442", "76443", "76445", "76450", "76455", "76458", "76461", "76465", "76467", "76468", "76470", "76473", "76478", "76479", "76481", "76482", "76485", "76486", "76489", "76490", "76493", "76495", "76499", "76501", "76502", "76506", "76508", "76512", "76514", "76515", "76517", "76521", "76526", "76527", "76528", "76529", "76530", "76534", "76535", "76539", "76541", "76542", "76543", "76544", "76545", "76551", "76553", "76558", "76560", "76561", "76562", "76563", "76567", "76568", "76569", "76570", "76571", "76576", "76577", "76578", "76579", "76580", "76584", "76589", "76590", "76592", "76595", "76598", "76603", "76604", "76607", "76608", "76609", "76610", "76612", "76614", "76616", "76617", "76618", "76621", "76622", "76625", "76626", "76629", "76633", "76634", "76635", "76636", "76640", "76642", "76644", "76645", "76647", "76648", "76650", "76653", "76654", "76655", "76658", "76661", "76662", "76665", "76669", "76670", "76672", "76673", "76674", "76677", "76679", "76681", "76682", "76688", "76690", "76692", "76694", "76696", "76699", "76700", "76705", "76708", "76709", "76710", "76712", "76713", "76714", "76716", "76717", "76721", "76722", "76723", "76724", "76727", "76729", "76730", "76732", "76733", "76734", "76737", "76738", "76739", "76742", "76743", "76744", "76745", "76746", "76747", "76749", "76750", "76753", "76754", "76755", "76757", "76759", "76764", "76765", "76766", "76768", "76770", "76772", "76774", "76779", "76780", "76783", "76784", "76787", "76788", "76793", "76795", "76797", "76799", "76803", "76804", "76805", "76807", "76816", "76817", "76818", "76820", "76821", "76822", "76833", "76834", "76835", "76836", "76838", "76839", "76841", "76842", "76843", "76844", "76845", "76846", "76849", "76851", "76852", "76853", "76854", "76855", "76857", "76858", "76860", "76862", "76863", "76864", "76865", "76867", "76868", "76869", "76870", "76871", "76872", "76875", "76876", "76877", "76881", "76883", "76885", "76886", "76887", "76889", "76890", "76891", "76893", "76894", "76895", "76897", "76900", "76904", "76908", "76909", "76910", "76911", "76912", "76915", "76916", "76917", "76920", "76921", "76923", "76924", "76926", "76928", "76929", "76930", "76932", "76934", "76935", "76936", "76938", "76941", "76945", "76946", "76947", "76950", "76951", "76952", "76955", "76956", "76957", "76960", "76961", "76962", "76964", "76965", "76967", "76968", "76969", "76971", "76973", "76979", "76981", "76982", "76983", "76984", "76985", "76986", "76987", "76988", "76990", "76991", "76992", "76995", "76996", "77000", "77002", "77005", "77006", "77007", "77009", "77012", "77014", "77020", "77021", "77023", "77025", "77026", "77031", "77033", "77036", "77037", "77039", "77042", "77044", "77045", "77046", "77048", "77050", "77052", "77057", "77059", "77061", "77062", "77064", "77066", "77067", "77068", "77069", "77071", "77072", "77075", "77077", "77079", "77080", "77081", "77082", "77094", "77095", "77096", "77098", "77099", "77101", "77103", "77106", "77108", "77109", "77111", "77114", "77116", "77117", "77118", "77119", "77120", "77122", "77123", "77124", "77126", "77127", "77130", "77131", "77133", "77135", "77136", "77137", "77138", "77139", "77144", "77146", "77149", "77151", "77152", "77155", "77157", "77161", "77162", "77163", "77165", "77166", "77167", "77168", "77169", "77170", "77171", "77172", "77173", "77174", "77177", "77180", "77181", "77182", "77185", "77186", "77187", "77188", "77189", "77191", "77193", "77194", "77195", "77197", "77200", "77202", "77203", "77204", "77205", "77206", "77207", "77208", "77209", "77210", "77212", "77213", "77214", "77217", "77221", "77222", "77227", "77228", "77229", "77233", "77234", "77244", "77245", "77250", "77251", "77254", "77256", "77257", "77258", "77264", "77266", "77267", "77269", "77271", "77273", "77274", "77276", "77277", "77278", "77281", "77282", "77284", "77286", "77287", "77288", "77289", "77291", "77294", "77295", "77297", "77298", "77300", "77301", "77305", "77306", "77309", "77314", "77316", "77322", "77324", "77328", "77331", "77332", "77334", "77339", "77340", "77345", "77347", "77348", "77350", "77352", "77354", "77357", "77358", "77359", "77360", "77361", "77362", "77364", "77365", "77367", "77369", "77370", "77374", "77376", "77377", "77378", "77381", "77382", "77383", "77384", "77387", "77390", "77394", "77395", "77397", "77399", "77400", "77403", "77404", "77406", "77408", "77409", "77410", "77415", "77417", "77418", "77422", "77424", "77425", "77426", "77430", "77431", "77432", "77433", "77434", "77435", "77436", "77437", "77438", "77440", "77442", "77445", "77446", "77448", "77449", "77452", "77453", "77454", "77455", "77461", "77462", "77464", "77468", "77469", "77474", "77476", "77480", "77482", "77484", "77487", "77489", "77491", "77492", "77493", "77494", "77495", "77499", "77501", "77508", "77509", "77510", "77512", "77513", "77516", "77517", "77520", "77521", "77523", "77524", "77525", "77528", "77530", "77531", "77532", "77533", "77536", "77538", "77540", "77543", "77545", "77549", "77551", "77552", "77553", "77554", "77555", "77560", "77562", "77563", "77565", "77566", "77568", "77569", "77571", "77573", "77574", "77576", "77577", "77578", "77580", "77585", "77586", "77588", "77589", "77590", "77591", "77593", "77595", "77600", "77601", "77603", "77606", "77607", "77608", "77611", "77612", "77613", "77614", "77619", "77623", "77624", "77625", "77626", "77627", "77628", "77629", "77633", "77634", "77635", "77638", "77639", "77640", "77641", "77642", "77644", "77645", "77650", "77651", "77652", "77653", "77654", "77656", "77658", "77659", "77662", "77663", "77665", "77668", "77669", "77671", "77673", "77674", "77678", "77679", "77680", "77681", "77682", "77685", "77686", "77687", "77693", "77694", "77696", "77697", "77702", "77703", "77704", "77706", "77707", "77708", "77710", "77711", "77712", "77714", "77715", "77718", "77720", "77721", "77723", "77725", "77727", "77730", "77734", "77735", "77739", "77740", "77741", "77742", "77744", "77747", "77749", "77751", "77752", "77753", "77754", "77756", "77757", "77758", "77760", "77761", "77762", "77763", "77764", "77768", "77770", "77772", "77773", "77774", "77777", "77781", "77784", "77785", "77786", "77792", "77794", "77796", "77797", "77799", "77800", "77804", "77805", "77808", "77809", "77810", "77812", "77813", "77816", "77821", "77823", "77825", "77826", "77828", "77829", "77832", "77835", "77836", "77837", "77838", "77840", "77842", "77846", "77849", "77851", "77853", "77855", "77858", "77859", "77860", "77861", "77867", "77869", "77871", "77877", "77881", "77883", "77886", "77889", "77891", "77892", "77894", "77895", "77896", "77898", "77899", "77900", "77902", "77903", "77906", "77907", "77909", "77911", "77912", "77913", "77918", "77921", "77924", "77925", "77926", "77927", "77929", "77931", "77932", "77934", "77935", "77938", "77941", "77942", "77943", "77945", "77946", "77952", "77954", "77955", "77957", "77960", "77962", "77963", "77965", "77968", "77971", "77973", "77976", "77977", "77981", "77983", "77986", "77987", "77988", "77989", "77991", "77994", "77996", "77998", "78002", "78003", "78005", "78006", "78007", "78011", "78012", "78014", "78015", "78016", "78017", "78019", "78021", "78022", "78024", "78026", "78027", "78029", "78031", "78032", "78038", "78040", "78042", "78046", "78047", "78049", "78052", "78053", "78055", "78056", "78057", "78060", "78064", "78068", "78071", "78072", "78073", "78074", "78075", "78077", "78079", "78080", "78081", "78082", "78086", "78090", "78092", "78095", "78096", "78097", "78098", "78099", "78103", "78104", "78106", "78107", "78110", "78112", "78113", "78114", "78116", "78117", "78118", "78120", "78123", "78124", "78125", "78129", "78132", "78134", "78141", "78143", "78144", "78149", "78150", "78154", "78156", "78157", "78158", "78162", "78168", "78171", "78172", "78174", "78176", "78178", "78179", "78180", "78183", "78189", "78196", "78199", "78202", "78203", "78204", "78208", "78212", "78215", "78216", "78218", "78219", "78220", "78221", "78223", "78231", "78232", "78233", "78234", "78235", "78236", "78237", "78241", "78242", "78244", "78245", "78246", "78248", "78250", "78251", "78252", "78254", "78256", "78257", "78258", "78261", "78263", "78266", "78267", "78269", "78271", "78272", "78274", "78276", "78278", "78280", "78281", "78283", "78287", "78288", "78291", "78292", "78294", "78302", "78303", "78306", "78309", "78310", "78312", "78313", "78318", "78320", "78321", "78322", "78326", "78330", "78331", "78333", "78335", "78338", "78340", "78343", "78344", "78345", "78346", "78348", "78351", "78352", "78356", "78360", "78361", "78362", "78367", "78368", "78369", "78370", "78371", "78372", "78374", "78376", "78377", "78378", "78380", "78383", "78387", "78389", "78390", "78391", "78392", "78394", "78395", "78400", "78401", "78404", "78405", "78411", "78413", "78414", "78415", "78416", "78419", "78422", "78423", "78424", "78425", "78427", "78433", "78435", "78436", "78437", "78439", "78441", "78445", "78447", "78448", "78450", "78452", "78453", "78454", "78455", "78462", "78463", "78465", "78466", "78467", "78472", "78473", "78474", "78478", "78479", "78482", "78485", "78487", "78493", "78496", "78497", "78502", "78503", "78507", "78509", "78510", "78511", "78513", "78517", "78518", "78520", "78521", "78524", "78527", "78529", "78531", "78535", "78540", "78541", "78542", "78543", "78545", "78547", "78548", "78549", "78550", "78555", "78556", "78558", "78559", "78563", "78566", "78567", "78568", "78569", "78573", "78574", "78575", "78578", "78583", "78584", "78585", "78586", "78589", "78590", "78595", "78596", "78597", "78599", "78603", "78604", "78609", "78610", "78611", "78614", "78615", "78616", "78619", "78629", "78631", "78633", "78634", "78638", "78639", "78640", "78643", "78644", "78649", "78652", "78654", "78658", "78661", "78662", "78663", "78664", "78666", "78667", "78670", "78671", "78675", "78679", "78681", "78683", "78684", "78685", "78686", "78687", "78688", "78689", "78690", "78691", "78692", "78693", "78699", "78701", "78705", "78707", "78709", "78712", "78713", "78717", "78719", "78720", "78721", "78722", "78723", "78725", "78727", "78728", "78729", "78732", "78734", "78735", "78736", "78740", "78741", "78742", "78743", "78746", "78749", "78751", "78752", "78753", "78754", "78757", "78758", "78763", "78764", "78767", "78768", "78770", "78772", "78773", "78775", "78776", "78777", "78778", "78779", "78782", "78788", "78789", "78792", "78793", "78794", "78795", "78796", "78797", "78800", "78801", "78802", "78803", "78806", "78807", "78810", "78811", "78813", "78814", "78817", "78818", "78820", "78821", "78823", "78826", "78829", "78830", "78833", "78835", "78837", "78842", "78843", "78844", "78846", "78847", "78848", "78851", "78852", "78853", "78856", "78859", "78860", "78863", "78865", "78866", "78867", "78868", "78872", "78873", "78874", "78877", "78879", "78880", "78882", "78884", "78885", "78887", "78890", "78892", "78901", "78902", "78904", "78905", "78906", "78912", "78915", "78916", "78917", "78918", "78921", "78922", "78925", "78929", "78930", "78931", "78932", "78933", "78935", "78939", "78941", "78942", "78943", "78945", "78947", "78949", "78952", "78953", "78955", "78963", "78964", "78965", "78966", "78967", "78968", "78969", "78973", "78976", "78978", "78980", "78981", "78983", "78984", "78986", "78994", "78997", "79001", "79002", "79003", "79004", "79005", "79006", "79008", "79009", "79010", "79011", "79015", "79016", "79018", "79023", "79028", "79030", "79031", "79032", "79034", "79035", "79038", "79041", "79042", "79043", "79046", "79054", "79057", "79061", "79063", "79064", "79066", "79067", "79068", "79070", "79071", "79077", "79080", "79085", "79087", "79089", "79094", "79097", "79100", "79101", "79102", "79105", "79106", "79108", "79111", "79114", "79115", "79117", "79118", "79119", "79120", "79121", "79122", "79124", "79125", "79128", "79129", "79133", "79135", "79138", "79139", "79140", "79143", "79145", "79146", "79148", "79149", "79150", "79151", "79154", "79155", "79156", "79161", "79162", "79163", "79165", "79166", "79167", "79168", "79170", "79171", "79172", "79173", "79175", "79176", "79177", "79178", "79181", "79182", "79183", "79184", "79185", "79186", "79188", "79192", "79193", "79194", "79195", "79197", "79200", "79201", "79202", "79204", "79207", "79209", "79210", "79211", "79214", "79215", "79219", "79220", "79221", "79222", "79224", "79226", "79227", "79228", "79229", "79231", "79232", "79235", "79236", "79240", "79242", "79243", "79244", "79245", "79246", "79247", "79248", "79250", "79251", "79253", "79254", "79255", "79256", "79259", "79264", "79266", "79268", "79270", "79273", "79274", "79277", "79280", "79282", "79284", "79286", "79287", "79289", "79290", "79291", "79293", "79294", "79295", "79300", "79301", "79302", "79303", "79305", "79306", "79307", "79308", "79309", "79311", "79312", "79315", "79320", "79322", "79323", "79324", "79326", "79330", "79333", "79334", "79335", "79336", "79340", "79341", "79342", "79343", "79344", "79345", "79346", "79349", "79350", "79352", "79355", "79356", "79358", "79360", "79362", "79363", "79364", "79365", "79366", "79368", "79369", "79375", "79377", "79378", "79382", "79383", "79385", "79386", "79389", "79390", "79393", "79394", "79395", "79396", "79397", "79398", "79399", "79400", "79401", "79404", "79405", "79406", "79413", "79414", "79415", "79417", "79418", "79420", "79426", "79428", "79429", "79432", "79434", "79438", "79439", "79441", "79443", "79445", "79449", "79452", "79453", "79455", "79460", "79462", "79465", "79466", "79467", "79468", "79470", "79471", "79472", "79473", "79477", "79478", "79482", "79483", "79484", "79485", "79487", "79488", "79489", "79492", "79493", "79495", "79497", "79498", "79499", "79500", "79501", "79503", "79505", "79506", "79508", "79509", "79510", "79511", "79512", "79515", "79517", "79520", "79521", "79522", "79523", "79524", "79526", "79529", "79533", "79537", "79538", "79540", "79541", "79543", "79544", "79545", "79549", "79550", "79551", "79553", "79556", "79559", "79560", "79561", "79563", "79565", "79569", "79570", "79573", "79577", "79578", "79579", "79580", "79581", "79584", "79585", "79586", "79587", "79588", "79589", "79595", "79599", "79600", "79601", "79606", "79612", "79613", "79614", "79615", "79616", "79617", "79620", "79624", "79625", "79627", "79628", "79630", "79632", "79633", "79635", "79636", "79637", "79639", "79640", "79641", "79645", "79649", "79651", "79652", "79653", "79654", "79655", "79658", "79660", "79661", "79662", "79663", "79664", "79665", "79666", "79667", "79668", "79669", "79670", "79671", "79674", "79676", "79678", "79679", "79680", "79681", "79682", "79683", "79684", "79685", "79686", "79688", "79689", "79697", "79699", "79700", "79701", "79702", "79703", "79706", "79708", "79711", "79712", "79714", "79715", "79716", "79717", "79718", "79721", "79727", "79728", "79729", "79731", "79732", "79734", "79736", "79742", "79743", "79744", "79750", "79752", "79755", "79758", "79759", "79767", "79769", "79770", "79771", "79775", "79776", "79779", "79780", "79781", "79782", "79789", "79791", "79792", "79794", "79795", "79796", "79797", "79798", "79802", "79805", "79809", "79810", "79811", "79814", "79815", "79817", "79824", "79826", "79828", "79831", "79832", "79833", "79834", "79837", "79839", "79840", "79841", "79845", "79846", "79849", "79850", "79851", "79854", "79855", "79857", "79861", "79862", "79866", "79870", "79872", "79873", "79877", "79879", "79880", "79881", "79882", "79883", "79884", "79885", "79886", "79888", "79889", "79891", "79892", "79893", "79896", "79900", "79904", "79910", "79911", "79919", "79922", "79923", "79924", "79925", "79928", "79929", "79933", "79935", "79938", "79940", "79944", "79945", "79949", "79954", "79955", "79956", "79957", "79958", "79961", "79964", "79965", "79969", "79970", "79971", "79972", "79973", "79974", "79977", "79979", "79982", "79984", "79990", "79991", "79995", "79997", "79998", "80001", "80002", "80004", "80005", "80006", "80010", "80011", "80014", "80015", "80020", "80026", "80029", "80031", "80032", "80035", "80036", "80038", "80039", "80041", "80042", "80043", "80044", "80049", "80050", "80051", "80052", "80053", "80055", "80056", "80060", "80061", "80064", "80066", "80069", "80070", "80071", "80074", "80075", "80076", "80077", "80080", "80083", "80084", "80085", "80086", "80087", "80088", "80089", "80091", "80093", "80094", "80095", "80098", "80100", "80102", "80103", "80104", "80105", "80106", "80109", "80110", "80112", "80115", "80117", "80122", "80129", "80130", "80131", "80133", "80134", "80136", "80138", "80141", "80142", "80143", "80144", "80147", "80154", "80158", "80159", "80161", "80163", "80168", "80170", "80177", "80178", "80179", "80180", "80181", "80182", "80192", "80195", "80196", "80198", "80199", "80201", "80202", "80203", "80205", "80208", "80209", "80210", "80211", "80212", "80213", "80216", "80217", "80222", "80224", "80225", "80227", "80228", "80229", "80231", "80233", "80234", "80237", "80238", "80239", "80240", "80242", "80243", "80245", "80247", "80248", "80251", "80253", "80256", "80261", "80263", "80264", "80267", "80268", "80269", "80271", "80274", "80275", "80277", "80278", "80280", "80282", "80283", "80285", "80286", "80288", "80292", "80293", "80294", "80297", "80298", "80300", "80304", "80305", "80306", "80308", "80310", "80311", "80313", "80314", "80316", "80317", "80318", "80319", "80321", "80324", "80325", "80327", "80329", "80331", "80335", "80337", "80340", "80349", "80350", "80353", "80355", "80356", "80357", "80359", "80362", "80363", "80365", "80368", "80370", "80372", "80373", "80375", "80376", "80378", "80380", "80382", "80383", "80384", "80385", "80388", "80389", "80390", "80392", "80395", "80397", "80400", "80401", "80404", "80406", "80412", "80415", "80417", "80418", "80420", "80422", "80424", "80425", "80426", "80427", "80428", "80429", "80430", "80432", "80437", "80438", "80439", "80444", "80445", "80446", "80447", "80449", "80452", "80460", "80462", "80463", "80464", "80465", "80469", "80470", "80471", "80476", "80480", "80482", "80483", "80485", "80487", "80492", "80495", "80496", "80498", "80500", "80502", "80503", "80505", "80506", "80507", "80508", "80510", "80511", "80514", "80515", "80516", "80519", "80520", "80522", "80523", "80525", "80527", "80530", "80532", "80534", "80536", "80537", "80538", "80539", "80540", "80545", "80547", "80549", "80552", "80556", "80558", "80559", "80560", "80561", "80562", "80563", "80565", "80566", "80569", "80570", "80571", "80572", "80573", "80577", "80578", "80580", "80581", "80582", "80583", "80584", "80585", "80589", "80593", "80594", "80595", "80596", "80598", "80600", "80601", "80603", "80605", "80607", "80610", "80612", "80613", "80615", "80616", "80618", "80620", "80621", "80622", "80623", "80624", "80626", "80630", "80631", "80632", "80634", "80636", "80638", "80642", "80643", "80644", "80645", "80646", "80649", "80654", "80655", "80656", "80657", "80659", "80661", "80663", "80664", "80665", "80668", "80674", "80675", "80676", "80678", "80680", "80681", "80686", "80692", "80695", "80698", "80700", "80701", "80704", "80705", "80710", "80711", "80713", "80717", "80719", "80720", "80722", "80725", "80726", "80728", "80734", "80736", "80737", "80738", "80740", "80743", "80744", "80747", "80749", "80750", "80752", "80753", "80755", "80756", "80757", "80758", "80760", "80761", "80762", "80763", "80766", "80770", "80771", "80772", "80774", "80776", "80779", "80783", "80786", "80787", "80788", "80789", "80790", "80792", "80793", "80796", "80800", "80801", "80802", "80803", "80805", "80806", "80810", "80811", "80812", "80814", "80820", "80823", "80825", "80828", "80829", "80834", "80836", "80838", "80840", "80841", "80844", "80845", "80846", "80847", "80848", "80850", "80853", "80854", "80855", "80856", "80857", "80858", "80863", "80866", "80868", "80872", "80875", "80876", "80877", "80878", "80880", "80881", "80883", "80887", "80889", "80890", "80891", "80893", "80894", "80895", "80896", "80897", "80898", "80899", "80900", "80903", "80904", "80908", "80909", "80911", "80913", "80914", "80915", "80916", "80917", "80918", "80919", "80920", "80921", "80922", "80926", "80929", "80934", "80938", "80941", "80947", "80948", "80950", "80952", "80953", "80959", "80960", "80961", "80962", "80963", "80965", "80967", "80969", "80970", "80971", "80972", "80977", "80979", "80983", "80984", "80986", "80987", "80988", "80989", "80990", "80992", "80994", "80997", "81002", "81004", "81005", "81006", "81007", "81008", "81010", "81014", "81016", "81021", "81022", "81023", "81024", "81025", "81026", "81030", "81033", "81037", "81040", "81045", "81046", "81047", "81049", "81050", "81051", "81053", "81054", "81055", "81056", "81057", "81061", "81064", "81069", "81070", "81071", "81075", "81078", "81084", "81086", "81087", "81088", "81091", "81092", "81093", "81095", "81097", "81098", "81100", "81102", "81105", "81106", "81112", "81113", "81114", "81117", "81120", "81121", "81122", "81128", "81130", "81131", "81135", "81136", "81140", "81142", "81146", "81150", "81151", "81152", "81154", "81156", "81157", "81161", "81164", "81165", "81166", "81167", "81169", "81170", "81173", "81179", "81181", "81184", "81188", "81190", "81194", "81196", "81197", "81198", "81200", "81201", "81207", "81208", "81209", "81210", "81214", "81219", "81220", "81223", "81228", "81230", "81233", "81239", "81249", "81251", "81258", "81261", "81262", "81263", "81265", "81266", "81268", "81270", "81271", "81272", "81273", "81275", "81276", "81279", "81283", "81284", "81285", "81287", "81288", "81290", "81291", "81293", "81298", "81299", "81301", "81302", "81304", "81306", "81307", "81308", "81311", "81314", "81316", "81319", "81320", "81321", "81325", "81327", "81328", "81330", "81333", "81335", "81336", "81339", "81340", "81343", "81344", "81348", "81349", "81359", "81360", "81361", "81362", "81363", "81364", "81365", "81370", "81373", "81375", "81376", "81381", "81383", "81384", "81386", "81388", "81390", "81391", "81394", "81395", "81399", "81400", "81401", "81404", "81407", "81409", "81410", "81411", "81413", "81415", "81417", "81419", "81420", "81422", "81423", "81425", "81426", "81429", "81431", "81433", "81434", "81436", "81438", "81439", "81441", "81443", "81444", "81448", "81449", "81451", "81452", "81453", "81455", "81457", "81458", "81459", "81460", "81461", "81462", "81464", "81468", "81471", "81472", "81473", "81478", "81479", "81480", "81481", "81484", "81486", "81488", "81489", "81490", "81494", "81495", "81497", "81499", "81500", "81501", "81502", "81503", "81504", "81509", "81510", "81511", "81513", "81515", "81517", "81518", "81519", "81520", "81522", "81523", "81524", "81526", "81528", "81529", "81531", "81534", "81536", "81537", "81538", "81541", "81543", "81544", "81548", "81549", "81552", "81553", "81555", "81558", "81559", "81560", "81561", "81566", "81567", "81568", "81571", "81572", "81573", "81574", "81575", "81576", "81577", "81578", "81580", "81581", "81589", "81597", "81600", "81601", "81602", "81604", "81605", "81606", "81609", "81610", "81611", "81612", "81615", "81616", "81617", "81619", "81621", "81623", "81624", "81625", "81626", "81628", "81629", "81630", "81633", "81634", "81635", "81636", "81637", "81638", "81640", "81642", "81643", "81644", "81645", "81648", "81653", "81657", "81658", "81659", "81660", "81663", "81667", "81672", "81674", "81675", "81677", "81682", "81684", "81686", "81687", "81688", "81689", "81690", "81691", "81694", "81695", "81696", "81698", "81699", "81702", "81705", "81706", "81707", "81709", "81714", "81717", "81722", "81723", "81725", "81726", "81729", "81730", "81733", "81734", "81736", "81738", "81739", "81740", "81742", "81743", "81744", "81746", "81748", "81749", "81750", "81752", "81754", "81758", "81760", "81762", "81763", "81764", "81766", "81767", "81769", "81770", "81771", "81773", "81775", "81777", "81778", "81781", "81782", "81783", "81785", "81786", "81788", "81789", "81790", "81791", "81792", "81793", "81794", "81795", "81796", "81798", "81803", "81804", "81805", "81806", "81809", "81810", "81811", "81813", "81814", "81815", "81816", "81817", "81819", "81826", "81829", "81831", "81832", "81833", "81836", "81837", "81838", "81840", "81841", "81842", "81843", "81844", "81845", "81847", "81849", "81851", "81852", "81853", "81859", "81860", "81866", "81867", "81869", "81872", "81873", "81874", "81878", "81879", "81883", "81888", "81890", "81892", "81897", "81899", "81901", "81905", "81908", "81909", "81911", "81912", "81913", "81916", "81919", "81920", "81922", "81923", "81924", "81929", "81930", "81934", "81935", "81937", "81939", "81941", "81944", "81947", "81948", "81949", "81950", "81951", "81952", "81953", "81954", "81956", "81957", "81959", "81960", "81962", "81963", "81965", "81968", "81970", "81971", "81972", "81973", "81975", "81979", "81980", "81982", "81985", "81986", "81987", "81988", "81989", "81990", "81993", "81994", "81995", "81997", "81998", "82003", "82004", "82009", "82013", "82016", "82017", "82018", "82019", "82020", "82021", "82024", "82032", "82033", "82035", "82036", "82039", "82042", "82043", "82047", "82052", "82054", "82056", "82060", "82063", "82065", "82066", "82067", "82068", "82069", "82070", "82073", "82079", "82081", "82083", "82084", "82085", "82086", "82087", "82089", "82091", "82092", "82094", "82095", "82098", "82099", "82100", "82103", "82105", "82106", "82109", "82110", "82111", "82113", "82115", "82117", "82120", "82121", "82125", "82127", "82128", "82131", "82135", "82138", "82140", "82141", "82143", "82147", "82148", "82149", "82150", "82151", "82152", "82154", "82156", "82158", "82160", "82163", "82164", "82165", "82166", "82172", "82175", "82176", "82178", "82179", "82181", "82182", "82183", "82185", "82188", "82189", "82190", "82191", "82193", "82194", "82197", "82198", "82200", "82202", "82203", "82207", "82210", "82211", "82212", "82214", "82215", "82224", "82225", "82226", "82229", "82230", "82236", "82238", "82239", "82241", "82242", "82244", "82246", "82247", "82249", "82250", "82251", "82252", "82253", "82260", "82261", "82262", "82263", "82265", "82269", "82270", "82271", "82273", "82274", "82276", "82277", "82282", "82284", "82285", "82287", "82288", "82289", "82291", "82292", "82293", "82294", "82295", "82296", "82297", "82299", "82300", "82301", "82303", "82304", "82312", "82319", "82320", "82321", "82323", "82326", "82328", "82329", "82330", "82331", "82332", "82333", "82334", "82337", "82340", "82341", "82344", "82345", "82346", "82348", "82354", "82355", "82357", "82358", "82360", "82361", "82362", "82366", "82374", "82376", "82377", "82379", "82381", "82382", "82383", "82384", "82388", "82389", "82391", "82392", "82393", "82394", "82395", "82396", "82397", "82399", "82401", "82402", "82403", "82404", "82406", "82407", "82410", "82415", "82418", "82421", "82422", "82423", "82424", "82425", "82426", "82427", "82428", "82432", "82433", "82434", "82436", "82437", "82439", "82440", "82441", "82442", "82448", "82449", "82451", "82454", "82455", "82457", "82458", "82459", "82461", "82462", "82463", "82465", "82466", "82467", "82469", "82471", "82475", "82477", "82481", "82484", "82486", "82487", "82489", "82494", "82495", "82496", "82498", "82499", "82500", "82501", "82504", "82507", "82510", "82511", "82512", "82513", "82514", "82516", "82517", "82520", "82521", "82525", "82530", "82531", "82532", "82533", "82534", "82535", "82536", "82540", "82541", "82542", "82544", "82545", "82548", "82549", "82551", "82553", "82555", "82557", "82561", "82564", "82565", "82568", "82570", "82571", "82572", "82573", "82574", "82579", "82580", "82582", "82584", "82586", "82587", "82588", "82590", "82591", "82592", "82593", "82595", "82597", "82600", "82602", "82604", "82605", "82607", "82608", "82612", "82615", "82616", "82618", "82619", "82621", "82623", "82625", "82626", "82628", "82630", "82636", "82637", "82638", "82640", "82646", "82647", "82650", "82651", "82652", "82654", "82655", "82656", "82657", "82659", "82661", "82664", "82666", "82668", "82669", "82671", "82672", "82673", "82674", "82676", "82678", "82681", "82686", "82691", "82692", "82696", "82698", "82699", "82701", "82702", "82705", "82708", "82709", "82713", "82716", "82717", "82719", "82726", "82727", "82728", "82734", "82736", "82738", "82739", "82742", "82745", "82748", "82749", "82750", "82751", "82752", "82753", "82756", "82758", "82759", "82760", "82762", "82765", "82768", "82770", "82774", "82776", "82778", "82780", "82782", "82783", "82784", "82785", "82787", "82789", "82790", "82796", "82797", "82798", "82799", "82800", "82801", "82802", "82805", "82806", "82807", "82810", "82812", "82813", "82817", "82818", "82819", "82820", "82821", "82822", "82823", "82825", "82828", "82830", "82834", "82836", "82838", "82841", "82843", "82844", "82846", "82847", "82849", "82850", "82853", "82854", "82855", "82860", "82862", "82863", "82864", "82866", "82867", "82868", "82869", "82871", "82873", "82874", "82875", "82876", "82877", "82878", "82882", "82883", "82887", "82888", "82889", "82891", "82893", "82894", "82901", "82902", "82907", "82909", "82910", "82911", "82912", "82913", "82914", "82916", "82920", "82925", "82927", "82930", "82931", "82933", "82934", "82935", "82937", "82938", "82940", "82942", "82943", "82945", "82947", "82948", "82951", "82953", "82956", "82958", "82961", "82963", "82964", "82965", "82971", "82974", "82976", "82977", "82978", "82982", "82984", "82986", "82988", "82990", "82991", "82993", "82995", "82996", "83000", "83002", "83003", "83005", "83007", "83008", "83009", "83010", "83013", "83014", "83015", "83017", "83021", "83023", "83024", "83025", "83026", "83028", "83030", "83032", "83034", "83035", "83036", "83038", "83039", "83040", "83047", "83048", "83049", "83051", "83052", "83053", "83060", "83064", "83065", "83066", "83069", "83071", "83073", "83074", "83075", "83077", "83078", "83079", "83080", "83081", "83083", "83084", "83086", "83088", "83091", "83094", "83096", "83097", "83099", "83100", "83106", "83107", "83110", "83111", "83112", "83115", "83117", "83119", "83120", "83121", "83123", "83127", "83129", "83131", "83132", "83136", "83139", "83140", "83141", "83142", "83143", "83145", "83147", "83148", "83149", "83150", "83152", "83155", "83156", "83157", "83158", "83160", "83161", "83167", "83169", "83170", "83171", "83172", "83174", "83175", "83177", "83178", "83183", "83185", "83187", "83190", "83191", "83192", "83193", "83194", "83195", "83198", "83199", "83202", "83204", "83205", "83206", "83207", "83208", "83210", "83211", "83212", "83215", "83216", "83217", "83218", "83219", "83220", "83223", "83225", "83233", "83234", "83235", "83238", "83239", "83240", "83242", "83243", "83244", "83248", "83249", "83250", "83251", "83253", "83254", "83256", "83258", "83262", "83265", "83266", "83268", "83271", "83272", "83273", "83276", "83278", "83279", "83281", "83286", "83287", "83289", "83290", "83291", "83292", "83296", "83298", "83300", "83301", "83302", "83303", "83306", "83309", "83313", "83316", "83318", "83328", "83329", "83330", "83331", "83332", "83333", "83335", "83336", "83338", "83339", "83343", "83344", "83346", "83347", "83353", "83356", "83357", "83359", "83361", "83362", "83365", "83366", "83367", "83371", "83372", "83374", "83376", "83377", "83383", "83384", "83385", "83386", "83387", "83388", "83390", "83392", "83396", "83398", "83399", "83402", "83403", "83406", "83408", "83412", "83413", "83414", "83420", "83422", "83423", "83428", "83430", "83435", "83437", "83438", "83439", "83440", "83441", "83444", "83445", "83448", "83449", "83450", "83453", "83455", "83456", "83457", "83458", "83460", "83462", "83463", "83466", "83469", "83470", "83471", "83474", "83475", "83478", "83479", "83480", "83483", "83484", "83486", "83489", "83490", "83492", "83493", "83495", "83497", "83500", "83502", "83503", "83504", "83506", "83507", "83509", "83513", "83523", "83525", "83527", "83531", "83534", "83536", "83540", "83541", "83543", "83545", "83546", "83547", "83548", "83551", "83554", "83559", "83562", "83563", "83564", "83565", "83568", "83571", "83572", "83575", "83576", "83577", "83578", "83579", "83582", "83584", "83586", "83587", "83588", "83589", "83590", "83593", "83595", "83597", "83599", "83602", "83603", "83606", "83608", "83611", "83613", "83614", "83615", "83617", "83618", "83622", "83623", "83626", "83628", "83629", "83630", "83631", "83634", "83636", "83637", "83638", "83640", "83641", "83642", "83648", "83649", "83651", "83653", "83656", "83657", "83659", "83662", "83664", "83665", "83668", "83669", "83672", "83673", "83675", "83676", "83677", "83679", "83680", "83681", "83683", "83687", "83688", "83689", "83694", "83695", "83696", "83697", "83698", "83700", "83705", "83707", "83708", "83709", "83712", "83715", "83716", "83722", "83723", "83724", "83726", "83731", "83732", "83736", "83739", "83741", "83745", "83746", "83748", "83749", "83751", "83752", "83753", "83754", "83756", "83758", "83760", "83762", "83766", "83768", "83774", "83776", "83777", "83778", "83779", "83780", "83781", "83782", "83783", "83788", "83789", "83791", "83792", "83795", "83798", "83803", "83805", "83807", "83810", "83813", "83814", "83816", "83817", "83818", "83819", "83820", "83822", "83827", "83828", "83835", "83840", "83841", "83844", "83845", "83846", "83847", "83848", "83849", "83850", "83851", "83857", "83858", "83859", "83860", "83861", "83862", "83870", "83874", "83877", "83878", "83879", "83880", "83884", "83885", "83889", "83893", "83894", "83896", "83897", "83898", "83900", "83901", "83903", "83904", "83905", "83907", "83912", "83913", "83918", "83919", "83920", "83921", "83923", "83924", "83925", "83926", "83927", "83928", "83932", "83934", "83936", "83937", "83940", "83942", "83943", "83944", "83946", "83948", "83949", "83953", "83955", "83957", "83960", "83964", "83966", "83967", "83969", "83971", "83973", "83974", "83977", "83979", "83983", "83984", "83985", "83986", "83988", "83991", "83995", "83996", "83997", "83998", "83999", "84000", "84001", "84003", "84006", "84010", "84011", "84012", "84014", "84018", "84019", "84021", "84022", "84023", "84024", "84027", "84031", "84032", "84033", "84035", "84040", "84041", "84043", "84044", "84045", "84046", "84048", "84049", "84055", "84056", "84057", "84060", "84061", "84063", "84064", "84068", "84070", "84071", "84079", "84086", "84087", "84088", "84091", "84093", "84094", "84095", "84096", "84097", "84098", "84100", "84101", "84104", "84105", "84108", "84109", "84111", "84113", "84117", "84120", "84121", "84122", "84123", "84126", "84129", "84130", "84131", "84133", "84134", "84135", "84136", "84138", "84139", "84142", "84143", "84144", "84148", "84149", "84152", "84153", "84161", "84164", "84166", "84167", "84168", "84169", "84171", "84174", "84177", "84178", "84179", "84181", "84183", "84184", "84186", "84192", "84195", "84196", "84200", "84201", "84203", "84204", "84205", "84206", "84209", "84210", "84211", "84212", "84213", "84215", "84218", "84219", "84221", "84222", "84223", "84224", "84226", "84227", "84228", "84234", "84238", "84239", "84241", "84242", "84243", "84245", "84246", "84249", "84250", "84251", "84253", "84255", "84259", "84260", "84262", "84264", "84265", "84267", "84269", "84271", "84274", "84278", "84279", "84280", "84282", "84284", "84285", "84290", "84291", "84293", "84294", "84298", "84301", "84305", "84307", "84308", "84310", "84312", "84315", "84316", "84318", "84320", "84322", "84324", "84326", "84328", "84329", "84330", "84331", "84333", "84334", "84335", "84336", "84337", "84344", "84349", "84350", "84352", "84354", "84356", "84361", "84366", "84367", "84369", "84371", "84378", "84381", "84382", "84383", "84385", "84387", "84389", "84390", "84392", "84394", "84396", "84399", "84401", "84403", "84405", "84407", "84410", "84411", "84412", "84413", "84416", "84418", "84422", "84424", "84426", "84427", "84428", "84430", "84432", "84434", "84436", "84438", "84439", "84441", "84442", "84443", "84444", "84446", "84447", "84448", "84449", "84450", "84451", "84454", "84460", "84462", "84463", "84470", "84472", "84473", "84477", "84478", "84481", "84484", "84485", "84488", "84489", "84490", "84491", "84492", "84494", "84495", "84503", "84504", "84505", "84511", "84513", "84515", "84516", "84518", "84519", "84520", "84521", "84524", "84526", "84527", "84529", "84532", "84536", "84538", "84542", "84544", "84545", "84546", "84548", "84549", "84550", "84551", "84553", "84555", "84556", "84558", "84559", "84560", "84567", "84580", "84581", "84583", "84585", "84586", "84587", "84590", "84592", "84594", "84597", "84599", "84600", "84601", "84605", "84606", "84607", "84608", "84609", "84610", "84616", "84617", "84619", "84623", "84624", "84625", "84628", "84629", "84634", "84637", "84643", "84644", "84646", "84650", "84653", "84656", "84658", "84660", "84662", "84663", "84667", "84668", "84670", "84671", "84673", "84674", "84677", "84678", "84680", "84683", "84686", "84687", "84689", "84691", "84693", "84694", "84695", "84697", "84698", "84702", "84704", "84707", "84708", "84714", "84716", "84717", "84718", "84720", "84723", "84725", "84726", "84727", "84730", "84731", "84732", "84733", "84735", "84739", "84740", "84744", "84746", "84747", "84748", "84749", "84751", "84752", "84753", "84754", "84755", "84756", "84759", "84761", "84763", "84764", "84765", "84769", "84770", "84771", "84772", "84775", "84776", "84777", "84778", "84779", "84781", "84783", "84784", "84785", "84786", "84787", "84789", "84790", "84791", "84795", "84798", "84802", "84805", "84806", "84807", "84810", "84812", "84813", "84814", "84817", "84819", "84820", "84821", "84822", "84823", "84829", "84830", "84832", "84835", "84836", "84838", "84842", "84843", "84844", "84847", "84848", "84849", "84850", "84852", "84853", "84854", "84855", "84856", "84857", "84861", "84862", "84868", "84871", "84872", "84873", "84874", "84875", "84876", "84877", "84878", "84881", "84882", "84886", "84889", "84890", "84891", "84892", "84900", "84903", "84904", "84909", "84912", "84915", "84916", "84917", "84920", "84922", "84923", "84924", "84925", "84929", "84930", "84933", "84934", "84935", "84938", "84939", "84940", "84942", "84943", "84946", "84947", "84952", "84953", "84955", "84957", "84959", "84963", "84964", "84968", "84969", "84970", "84972", "84976", "84978", "84982", "84985", "84988", "84992", "84993", "84995", "84997", "84999", "85000", "85004", "85006", "85009", "85010", "85011", "85014", "85015", "85017", "85023", "85026", "85027", "85029", "85031", "85032", "85034", "85040", "85041", "85044", "85047", "85050", "85051", "85053", "85056", "85057", "85058", "85061", "85063", "85064", "85070", "85071", "85072", "85076", "85077", "85079", "85080", "85082", "85083", "85085", "85087", "85088", "85090", "85093", "85095", "85098", "85102", "85106", "85108", "85109", "85116", "85117", "85120", "85122", "85124", "85125", "85126", "85127", "85128", "85129", "85130", "85132", "85135", "85136", "85137", "85141", "85144", "85150", "85151", "85152", "85155", "85156", "85158", "85160", "85162", "85164", "85166", "85167", "85168", "85170", "85171", "85172", "85173", "85175", "85176", "85177", "85178", "85179", "85180", "85181", "85185", "85187", "85188", "85190", "85191", "85192", "85193", "85194", "85197", "85199", "85205", "85206", "85207", "85211", "85212", "85213", "85216", "85217", "85218", "85219", "85224", "85226", "85227", "85230", "85231", "85234", "85235", "85236", "85240", "85245", "85246", "85249", "85251", "85252", "85253", "85254", "85255", "85256", "85257", "85261", "85262", "85263", "85265", "85267", "85268", "85274", "85275", "85278", "85280", "85285", "85287", "85290", "85296", "85297", "85298", "85299", "85300", "85301", "85302", "85304", "85306", "85307", "85308", "85310", "85311", "85312", "85313", "85323", "85324", "85325", "85327", "85330", "85334", "85335", "85338", "85339", "85340", "85342", "85344", "85345", "85347", "85348", "85349", "85352", "85353", "85354", "85356", "85357", "85359", "85360", "85361", "85363", "85367", "85368", "85369", "85373", "85374", "85378", "85380", "85387", "85388", "85389", "85390", "85395", "85397", "85398", "85407", "85408", "85414", "85418", "85421", "85423", "85432", "85433", "85435", "85437", "85438", "85439", "85440", "85441", "85442", "85443", "85444", "85445", "85447", "85449", "85450", "85451", "85453", "85456", "85458", "85459", "85463", "85466", "85470", "85473", "85475", "85476", "85477", "85478", "85480", "85481", "85482", "85484", "85488", "85489", "85490", "85492", "85494", "85500", "85502", "85505", "85508", "85510", "85511", "85516", "85517", "85518", "85522", "85525", "85527", "85529", "85530", "85531", "85532", "85535", "85537", "85538", "85539", "85540", "85541", "85542", "85543", "85544", "85545", "85548", "85549", "85552", "85553", "85557", "85559", "85561", "85562", "85563", "85565", "85569", "85570", "85571", "85572", "85573", "85574", "85578", "85579", "85582", "85584", "85585", "85586", "85587", "85588", "85590", "85591", "85592", "85595", "85598", "85600", "85607", "85608", "85610", "85612", "85613", "85616", "85621", "85622", "85627", "85628", "85629", "85630", "85631", "85632", "85635", "85639", "85640", "85641", "85644", "85648", "85649", "85650", "85651", "85655", "85660", "85662", "85664", "85665", "85667", "85668", "85669", "85672", "85674", "85677", "85678", "85680", "85683", "85685", "85689", "85690", "85691", "85694", "85696", "85699", "85700", "85701", "85702", "85703", "85710", "85712", "85713", "85714", "85715", "85716", "85720", "85723", "85726", "85729", "85730", "85733", "85736", "85739", "85741", "85745", "85746", "85747", "85749", "85750", "85751", "85752", "85757", "85760", "85761", "85762", "85763", "85764", "85765", "85769", "85771", "85772", "85774", "85776", "85778", "85780", "85783", "85784", "85785", "85789", "85794", "85795", "85798", "85800", "85801", "85803", "85805", "85806", "85807", "85809", "85810", "85811", "85812", "85813", "85814", "85817", "85819", "85820", "85824", "85825", "85826", "85831", "85832", "85835", "85837", "85838", "85841", "85843", "85844", "85845", "85848", "85854", "85857", "85859", "85860", "85862", "85865", "85871", "85872", "85874", "85877", "85878", "85880", "85883", "85884", "85888", "85890", "85892", "85895", "85897", "85900", "85901", "85907", "85910", "85913", "85915", "85916", "85918", "85921", "85927", "85930", "85932", "85933", "85935", "85937", "85939", "85940", "85941", "85943", "85944", "85946", "85951", "85952", "85955", "85956", "85957", "85959", "85960", "85962", "85964", "85965", "85967", "85970", "85973", "85978", "85979", "85980", "85981", "85983", "85984", "85985", "85989", "85992", "85993", "85996", "85999", "86000", "86002", "86003", "86005", "86007", "86008", "86013", "86016", "86017", "86018", "86020", "86021", "86022", "86023", "86024", "86026", "86031", "86037", "86039", "86040", "86043", "86046", "86047", "86050", "86053", "86056", "86060", "86061", "86064", "86065", "86066", "86067", "86068", "86070", "86071", "86072", "86074", "86075", "86077", "86078", "86079", "86082", "86084", "86085", "86086", "86090", "86092", "86093", "86095", "86096", "86098", "86100", "86101", "86104", "86105", "86107", "86109", "86112", "86115", "86116", "86117", "86118", "86119", "86120", "86122", "86124", "86128", "86129", "86130", "86131", "86134", "86137", "86138", "86142", "86143", "86146", "86147", "86150", "86151", "86154", "86156", "86159", "86160", "86161", "86162", "86164", "86165", "86166", "86167", "86171", "86172", "86173", "86176", "86178", "86181", "86183", "86184", "86187", "86188", "86189", "86190", "86191", "86195", "86196", "86198", "86201", "86203", "86204", "86205", "86206", "86207", "86208", "86211", "86213", "86215", "86219", "86221", "86222", "86223", "86225", "86228", "86230", "86233", "86234", "86235", "86237", "86240", "86241", "86242", "86243", "86247", "86249", "86251", "86252", "86253", "86254", "86256", "86263", "86264", "86265", "86266", "86268", "86270", "86271", "86275", "86276", "86278", "86279", "86280", "86282", "86283", "86284", "86288", "86289", "86291", "86294", "86295", "86297", "86299", "86303", "86305", "86306", "86307", "86308", "86310", "86312", "86313", "86316", "86324", "86325", "86329", "86330", "86332", "86333", "86334", "86335", "86336", "86344", "86346", "86347", "86349", "86353", "86355", "86356", "86358", "86360", "86365", "86367", "86372", "86373", "86378", "86379", "86380", "86381", "86382", "86385", "86387", "86390", "86391", "86392", "86393", "86394", "86395", "86398", "86399", "86400", "86406", "86410", "86413", "86414", "86415", "86416", "86417", "86419", "86421", "86422", "86423", "86425", "86426", "86427", "86433", "86435", "86437", "86438", "86442", "86444", "86451", "86452", "86455", "86456", "86458", "86460", "86463", "86465", "86466", "86467", "86469", "86471", "86472", "86473", "86474", "86476", "86477", "86478", "86480", "86482", "86484", "86486", "86487", "86488", "86490", "86491", "86494", "86496", "86497", "86501", "86502", "86505", "86509", "86512", "86514", "86516", "86517", "86522", "86523", "86526", "86527", "86529", "86532", "86533", "86534", "86535", "86536", "86539", "86541", "86545", "86546", "86547", "86549", "86550", "86553", "86554", "86559", "86562", "86567", "86568", "86569", "86570", "86571", "86572", "86575", "86576", "86577", "86579", "86580", "86582", "86586", "86587", "86588", "86590", "86591", "86593", "86594", "86595", "86596", "86597", "86599", "86601", "86602", "86603", "86604", "86608", "86609", "86611", "86612", "86613", "86614", "86615", "86616", "86617", "86618", "86620", "86621", "86622", "86623", "86624", "86625", "86627", "86628", "86630", "86635", "86637", "86639", "86640", "86643", "86645", "86646", "86648", "86650", "86651", "86655", "86657", "86659", "86661", "86663", "86665", "86666", "86668", "86669", "86670", "86671", "86675", "86676", "86678", "86679", "86680", "86681", "86682", "86685", "86688", "86689", "86692", "86695", "86696", "86697", "86699", "86700", "86701", "86702", "86704", "86705", "86707", "86708", "86709", "86710", "86711", "86714", "86718", "86719", "86725", "86726", "86728", "86730", "86731", "86734", "86738", "86740", "86741", "86746", "86747", "86749", "86750", "86752", "86753", "86756", "86757", "86760", "86761", "86764", "86766", "86768", "86770", "86771", "86772", "86779", "86781", "86783", "86784", "86790", "86791", "86792", "86795", "86797", "86798", "86800", "86805", "86807", "86810", "86811", "86813", "86815", "86816", "86818", "86819", "86820", "86821", "86823", "86825", "86826", "86827", "86829", "86833", "86839", "86840", "86841", "86843", "86853", "86854", "86858", "86860", "86861", "86866", "86869", "86870", "86871", "86873", "86878", "86879", "86882", "86883", "86885", "86886", "86887", "86888", "86890", "86891", "86892", "86893", "86895", "86896", "86900", "86903", "86904", "86910", "86911", "86912", "86919", "86922", "86924", "86925", "86926", "86928", "86929", "86931", "86933", "86935", "86936", "86938", "86942", "86943", "86945", "86949", "86950", "86954", "86956", "86959", "86960", "86961", "86963", "86964", "86966", "86968", "86969", "86970", "86971", "86975", "86976", "86977", "86978", "86979", "86980", "86981", "86982", "86985", "86989", "86992", "86993", "86996", "86998", "87000", "87001", "87003", "87004", "87006", "87007", "87009", "87010", "87012", "87013", "87015", "87016", "87018", "87019", "87021", "87022", "87024", "87025", "87028", "87029", "87030", "87031", "87035", "87036", "87040", "87042", "87043", "87045", "87046", "87050", "87051", "87052", "87053", "87054", "87055", "87057", "87058", "87059", "87061", "87062", "87067", "87068", "87072", "87074", "87076", "87077", "87078", "87080", "87081", "87082", "87085", "87088", "87095", "87096", "87102", "87105", "87108", "87111", "87113", "87114", "87115", "87121", "87122", "87124", "87125", "87126", "87127", "87129", "87133", "87135", "87136", "87137", "87139", "87140", "87142", "87143", "87145", "87147", "87149", "87155", "87156", "87158", "87159", "87162", "87166", "87168", "87169", "87170", "87171", "87179", "87180", "87181", "87182", "87186", "87189", "87191", "87192", "87196", "87197", "87201", "87204", "87205", "87206", "87207", "87208", "87210", "87213", "87214", "87215", "87217", "87219", "87223", "87224", "87225", "87227", "87229", "87233", "87234", "87236", "87239", "87241", "87243", "87246", "87251", "87252", "87254", "87255", "87256", "87257", "87262", "87263", "87264", "87265", "87267", "87268", "87270", "87271", "87273", "87274", "87275", "87279", "87286", "87287", "87289", "87290", "87295", "87297", "87298", "87299", "87300", "87301", "87306", "87307", "87309", "87310", "87312", "87316", "87319", "87320", "87321", "87322", "87327", "87330", "87332", "87333", "87334", "87335", "87336", "87338", "87339", "87340", "87341", "87342", "87344", "87345", "87347", "87348", "87351", "87356", "87360", "87363", "87369", "87372", "87373", "87374", "87375", "87377", "87380", "87382", "87383", "87385", "87387", "87388", "87389", "87390", "87394", "87395", "87397", "87398", "87404", "87405", "87408", "87410", "87412", "87413", "87415", "87416", "87417", "87418", "87420", "87421", "87424", "87426", "87427", "87429", "87430", "87431", "87433", "87435", "87436", "87440", "87441", "87443", "87446", "87448", "87452", "87454", "87455", "87458", "87460", "87463", "87465", "87467", "87469", "87470", "87474", "87475", "87476", "87480", "87483", "87485", "87489", "87490", "87495", "87499", "87500", "87506", "87507", "87508", "87509", "87510", "87512", "87514", "87516", "87518", "87519", "87520", "87527", "87528", "87529", "87532", "87534", "87537", "87542", "87546", "87547", "87549", "87554", "87556", "87557", "87561", "87563", "87564", "87565", "87566", "87567", "87569", "87570", "87576", "87578", "87579", "87582", "87588", "87589", "87591", "87593", "87595", "87597", "87598", "87599", "87601", "87603", "87604", "87607", "87608", "87610", "87611", "87613", "87616", "87618", "87619", "87620", "87621", "87624", "87625", "87626", "87627", "87629", "87630", "87631", "87636", "87638", "87639", "87642", "87643", "87644", "87647", "87648", "87650", "87652", "87653", "87655", "87656", "87657", "87659", "87661", "87663", "87666", "87667", "87668", "87670", "87671", "87672", "87674", "87676", "87678", "87679", "87680", "87681", "87682", "87684", "87689", "87690", "87693", "87694", "87695", "87696", "87697", "87698", "87699", "87700", "87702", "87703", "87704", "87705", "87706", "87707", "87708", "87709", "87711", "87714", "87717", "87719", "87721", "87724", "87725", "87726", "87727", "87728", "87730", "87733", "87735", "87736", "87740", "87741", "87744", "87747", "87748", "87749", "87750", "87754", "87755", "87756", "87760", "87761", "87762", "87765", "87767", "87768", "87769", "87770", "87772", "87775", "87777", "87780", "87781", "87782", "87784", "87785", "87792", "87796", "87798", "87799", "87800", "87802", "87805", "87806", "87814", "87817", "87818", "87819", "87820", "87821", "87823", "87825", "87826", "87828", "87831", "87833", "87835", "87839", "87840", "87843", "87844", "87845", "87846", "87847", "87848", "87853", "87854", "87856", "87858", "87859", "87861", "87862", "87864", "87865", "87871", "87872", "87876", "87879", "87880", "87881", "87882", "87886", "87887", "87891", "87893", "87895", "87897", "87898", "87899", "87900", "87901", "87902", "87903", "87904", "87906", "87910", "87912", "87913", "87918", "87919", "87922", "87924", "87927", "87928", "87929", "87931", "87932", "87936", "87937", "87938", "87939", "87941", "87943", "87948", "87950", "87951", "87952", "87954", "87959", "87961", "87962", "87963", "87966", "87981", "87982", "87987", "87989", "87990", "87991", "87992", "87994", "87995", "87996", "87997", "87999", "88000", "88001", "88002", "88003", "88005", "88006", "88007", "88009", "88011", "88013", "88014", "88017", "88027", "88029", "88030", "88032", "88034", "88036", "88037", "88038", "88039", "88044", "88045", "88046", "88047", "88048", "88050", "88051", "88052", "88053", "88054", "88056", "88057", "88058", "88060", "88061", "88064", "88069", "88070", "88073", "88075", "88077", "88078", "88079", "88083", "88086", "88087", "88093", "88094", "88096", "88097", "88100", "88101", "88103", "88105", "88106", "88107", "88108", "88109", "88111", "88116", "88121", "88124", "88125", "88127", "88128", "88131", "88132", "88133", "88134", "88135", "88137", "88138", "88143", "88144", "88146", "88147", "88148", "88151", "88153", "88154", "88156", "88158", "88159", "88160", "88163", "88164", "88167", "88168", "88169", "88172", "88178", "88181", "88184", "88186", "88188", "88190", "88193", "88194", "88195", "88197", "88198", "88199", "88201", "88203", "88205", "88208", "88210", "88211", "88212", "88213", "88214", "88217", "88218", "88219", "88222", "88223", "88224", "88225", "88228", "88229", "88231", "88232", "88233", "88236", "88238", "88239", "88240", "88248", "88250", "88252", "88253", "88254", "88256", "88257", "88258", "88263", "88264", "88266", "88267", "88272", "88274", "88276", "88277", "88281", "88282", "88285", "88286", "88288", "88289", "88291", "88294", "88298", "88302", "88305", "88308", "88309", "88312", "88313", "88319", "88320", "88322", "88326", "88327", "88328", "88332", "88333", "88335", "88338", "88339", "88341", "88343", "88346", "88351", "88353", "88354", "88355", "88357", "88360", "88361", "88363", "88367", "88369", "88370", "88372", "88374", "88375", "88377", "88378", "88379", "88380", "88381", "88382", "88383", "88386", "88388", "88389", "88390", "88391", "88392", "88393", "88395", "88396", "88399", "88401", "88402", "88404", "88408", "88409", "88411", "88413", "88414", "88415", "88417", "88419", "88422", "88424", "88425", "88426", "88428", "88429", "88432", "88435", "88437", "88439", "88441", "88442", "88443", "88444", "88450", "88456", "88458", "88460", "88461", "88462", "88466", "88467", "88468", "88469", "88474", "88475", "88476", "88478", "88483", "88484", "88488", "88489", "88490", "88491", "88492", "88494", "88495", "88496", "88497", "88501", "88502", "88504", "88505", "88506", "88507", "88508", "88509", "88511", "88514", "88516", "88517", "88520", "88521", "88523", "88526", "88527", "88528", "88529", "88531", "88532", "88533", "88535", "88537", "88538", "88539", "88541", "88542", "88545", "88549", "88552", "88555", "88556", "88557", "88559", "88560", "88563", "88565", "88568", "88571", "88575", "88577", "88578", "88581", "88582", "88585", "88587", "88592", "88596", "88597", "88599", "88600", "88601", "88602", "88606", "88609", "88610", "88614", "88615", "88617", "88618", "88620", "88621", "88622", "88623", "88625", "88626", "88628", "88633", "88635", "88636", "88637", "88638", "88639", "88640", "88641", "88646", "88647", "88650", "88651", "88655", "88656", "88657", "88658", "88659", "88661", "88662", "88666", "88667", "88668", "88669", "88675", "88677", "88681", "88684", "88685", "88688", "88692", "88697", "88698", "88699", "88702", "88703", "88704", "88709", "88710", "88711", "88714", "88715", "88718", "88719", "88720", "88722", "88723", "88724", "88725", "88727", "88728", "88729", "88730", "88731", "88732", "88734", "88735", "88736", "88738", "88741", "88742", "88743", "88745", "88747", "88748", "88749", "88750", "88751", "88752", "88754", "88756", "88757", "88758", "88764", "88765", "88766", "88772", "88773", "88774", "88775", "88776", "88778", "88779", "88780", "88786", "88787", "88788", "88790", "88792", "88795", "88797", "88799", "88801", "88804", "88806", "88808", "88809", "88811", "88815", "88817", "88818", "88822", "88825", "88826", "88829", "88831", "88832", "88834", "88837", "88838", "88839", "88841", "88843", "88845", "88847", "88848", "88855", "88856", "88858", "88859", "88860", "88861", "88862", "88864", "88865", "88866", "88867", "88869", "88873", "88875", "88877", "88878", "88880", "88882", "88884", "88885", "88886", "88887", "88890", "88891", "88892", "88894", "88895", "88898", "88899", "88901", "88902", "88903", "88904", "88905", "88908", "88909", "88910", "88913", "88915", "88916", "88918", "88919", "88920", "88921", "88922", "88925", "88932", "88934", "88935", "88936", "88937", "88940", "88942", "88943", "88945", "88947", "88948", "88949", "88951", "88953", "88957", "88959", "88961", "88963", "88964", "88965", "88966", "88971", "88974", "88977", "88979", "88980", "88985", "88986", "88987", "88988", "88990", "88991", "88992", "88993", "88997", "88998", "89004", "89005", "89007", "89008", "89009", "89011", "89012", "89013", "89015", "89017", "89023", "89026", "89029", "89030", "89031", "89033", "89035", "89038", "89039", "89040", "89041", "89043", "89044", "89045", "89046", "89048", "89049", "89050", "89051", "89052", "89053", "89055", "89059", "89060", "89062", "89063", "89064", "89066", "89067", "89068", "89070", "89071", "89072", "89074", "89075", "89078", "89079", "89080", "89081", "89083", "89084", "89086", "89090", "89094", "89095", "89098", "89099", "89102", "89103", "89104", "89106", "89109", "89110", "89113", "89114", "89116", "89118", "89120", "89123", "89124", "89128", "89129", "89131", "89132", "89133", "89135", "89136", "89138", "89139", "89140", "89142", "89147", "89148", "89149", "89150", "89151", "89153", "89154", "89155", "89159", "89160", "89162", "89165", "89169", "89171", "89172", "89173", "89176", "89178", "89180", "89181", "89182", "89184", "89188", "89189", "89191", "89194", "89204", "89208", "89210", "89213", "89215", "89217", "89219", "89220", "89221", "89222", "89223", "89224", "89226", "89228", "89229", "89230", "89231", "89237", "89238", "89239", "89242", "89243", "89244", "89249", "89250", "89253", "89254", "89255", "89257", "89258", "89260", "89261", "89262", "89265", "89266", "89267", "89268", "89269", "89271", "89272", "89273", "89275", "89280", "89282", "89285", "89286", "89287", "89290", "89291", "89294", "89295", "89296", "89297", "89298", "89299", "89302", "89305", "89308", "89312", "89316", "89320", "89323", "89324", "89325", "89326", "89327", "89328", "89332", "89333", "89334", "89335", "89336", "89337", "89338", "89342", "89344", "89346", "89347", "89351", "89353", "89356", "89357", "89358", "89360", "89362", "89363", "89365", "89366", "89367", "89368", "89369", "89371", "89372", "89373", "89377", "89380", "89382", "89383", "89384", "89387", "89392", "89393", "89394", "89395", "89396", "89398", "89399", "89402", "89403", "89404", "89406", "89407", "89408", "89411", "89413", "89415", "89419", "89422", "89425", "89427", "89430", "89432", "89435", "89436", "89438", "89440", "89441", "89442", "89443", "89446", "89447", "89449", "89451", "89453", "89454", "89457", "89458", "89460", "89466", "89470", "89472", "89473", "89474", "89476", "89477", "89478", "89479", "89480", "89482", "89483", "89484", "89490", "89491", "89492", "89493", "89495", "89497", "89500", "89501", "89502", "89504", "89506", "89507", "89510", "89511", "89513", "89517", "89518", "89521", "89522", "89523", "89524", "89525", "89526", "89527", "89529", "89530", "89534", "89537", "89538", "89539", "89540", "89544", "89546", "89549", "89551", "89555", "89556", "89559", "89563", "89564", "89569", "89570", "89572", "89573", "89575", "89576", "89577", "89578", "89579", "89581", "89585", "89586", "89587", "89589", "89590", "89592", "89593", "89594", "89595", "89596", "89597", "89600", "89601", "89604", "89606", "89607", "89608", "89609", "89612", "89614", "89615", "89616", "89617", "89620", "89621", "89622", "89624", "89625", "89627", "89630", "89633", "89636", "89638", "89644", "89645", "89647", "89648", "89649", "89652", "89654", "89660", "89663", "89665", "89668", "89669", "89671", "89674", "89675", "89676", "89678", "89680", "89681", "89683", "89685", "89689", "89690", "89691", "89692", "89693", "89696", "89697", "89698", "89701", "89702", "89703", "89709", "89711", "89712", "89713", "89714", "89716", "89719", "89721", "89722", "89724", "89725", "89730", "89733", "89734", "89737", "89738", "89746", "89748", "89752", "89753", "89754", "89757", "89762", "89763", "89764", "89766", "89767", "89768", "89770", "89771", "89773", "89774", "89775", "89782", "89783", "89786", "89789", "89790", "89791", "89794", "89796", "89797", "89798", "89800", "89802", "89803", "89805", "89807", "89808", "89810", "89811", "89812", "89824", "89826", "89827", "89829", "89830", "89836", "89838", "89839", "89844", "89846", "89849", "89850", "89854", "89855", "89856", "89858", "89860", "89861", "89863", "89864", "89866", "89867", "89868", "89870", "89872", "89875", "89877", "89881", "89884", "89885", "89887", "89889", "89891", "89892", "89893", "89894", "89898", "89900", "89901", "89903", "89905", "89906", "89909", "89911", "89912", "89913", "89914", "89918", "89919", "89921", "89922", "89923", "89926", "89927", "89928", "89929", "89930", "89932", "89934", "89935", "89936", "89938", "89939", "89941", "89942", "89943", "89945", "89946", "89947", "89948", "89950", "89951", "89952", "89953", "89955", "89957", "89961", "89966", "89969", "89971", "89972", "89974", "89975", "89977", "89978", "89982", "89983", "89985", "89986", "89987", "89988", "89989", "89991", "89993", "89996", "89998", "90001", "90004", "90005", "90006", "90007", "90010", "90011", "90013", "90017", "90021", "90022", "90026", "90027", "90029", "90031", "90034", "90038", "90039", "90042", "90044", "90047", "90049", "90050", "90051", "90054", "90059", "90061", "90064", "90065", "90066", "90068", "90069", "90070", "90071", "90073", "90075", "90083", "90084", "90088", "90089", "90090", "90091", "90092", "90093", "90094", "90095", "90098", "90100", "90103", "90107", "90108", "90109", "90110", "90113", "90120", "90122", "90130", "90134", "90137", "90140", "90141", "90145", "90146", "90148", "90149", "90151", "90153", "90154", "90156", "90160", "90164", "90166", "90168", "90171", "90172", "90173", "90174", "90177", "90180", "90181", "90182", "90190", "90193", "90195", "90197", "90199", "90201", "90202", "90203", "90204", "90206", "90212", "90214", "90217", "90218", "90220", "90224", "90225", "90226", "90229", "90230", "90232", "90235", "90236", "90240", "90242", "90243", "90244", "90245", "90246", "90249", "90252", "90254", "90255", "90260", "90264", "90265", "90266", "90269", "90270", "90271", "90276", "90278", "90279", "90280", "90282", "90283", "90288", "90293", "90294", "90295", "90297", "90298", "90300", "90303", "90304", "90305", "90309", "90310", "90314", "90316", "90317", "90323", "90324", "90327", "90331", "90332", "90333", "90341", "90342", "90343", "90344", "90347", "90348", "90349", "90350", "90351", "90354", "90355", "90356", "90358", "90360", "90361", "90362", "90364", "90366", "90367", "90368", "90371", "90372", "90373", "90374", "90381", "90384", "90385", "90386", "90389", "90392", "90393", "90395", "90396", "90397", "90398", "90399", "90400", "90401", "90403", "90404", "90406", "90410", "90411", "90412", "90413", "90414", "90415", "90421", "90422", "90424", "90425", "90433", "90435", "90437", "90440", "90441", "90445", "90448", "90449", "90450", "90453", "90454", "90458", "90459", "90460", "90461", "90464", "90465", "90466", "90467", "90468", "90471", "90472", "90476", "90477", "90478", "90479", "90481", "90482", "90484", "90485", "90489", "90490", "90491", "90492", "90503", "90505", "90507", "90509", "90510", "90511", "90512", "90514", "90515", "90519", "90521", "90522", "90523", "90527", "90529", "90533", "90540", "90541", "90543", "90544", "90545", "90547", "90548", "90550", "90552", "90554", "90556", "90559", "90560", "90562", "90563", "90564", "90568", "90571", "90572", "90573", "90576", "90577", "90579", "90582", "90587", "90591", "90593", "90595", "90596", "90600", "90601", "90602", "90603", "90606", "90607", "90609", "90610", "90613", "90616", "90618", "90619", "90624", "90625", "90626", "90634", "90636", "90637", "90638", "90640", "90641", "90642", "90646", "90649", "90652", "90657", "90658", "90661", "90663", "90666", "90667", "90668", "90670", "90671", "90673", "90676", "90679", "90681", "90684", "90687", "90688", "90690", "90691", "90692", "90694", "90696", "90699", "90700", "90701", "90703", "90705", "90709", "90714", "90718", "90719", "90722", "90727", "90728", "90730", "90736", "90737", "90738", "90739", "90740", "90743", "90746", "90747", "90748", "90749", "90756", "90757", "90758", "90759", "90760", "90761", "90762", "90767", "90768", "90770", "90771", "90773", "90776", "90777", "90778", "90779", "90781", "90782", "90783", "90784", "90786", "90787", "90788", "90789", "90790", "90793", "90794", "90795", "90798", "90799", "90800", "90801", "90805", "90806", "90809", "90810", "90816", "90817", "90823", "90824", "90825", "90828", "90831", "90832", "90834", "90835", "90846", "90848", "90850", "90851", "90853", "90854", "90857", "90859", "90860", "90861", "90862", "90865", "90866", "90867", "90869", "90870", "90871", "90873", "90874", "90875", "90876", "90879", "90887", "90888", "90890", "90892", "90894", "90895", "90897", "90898", "90899", "90904", "90907", "90909", "90912", "90913", "90915", "90916", "90917", "90919", "90920", "90925", "90926", "90927", "90931", "90936", "90942", "90946", "90947", "90948", "90951", "90952", "90954", "90955", "90956", "90960", "90964", "90966", "90969", "90973", "90977", "90979", "90980", "90981", "90983", "90985", "90986", "90987", "90993", "90995", "90997", "90999", "91000", "91001", "91002", "91004", "91007", "91008", "91013", "91016", "91019", "91020", "91022", "91026", "91028", "91029", "91030", "91033", "91034", "91036", "91038", "91040", "91041", "91042", "91044", "91046", "91047", "91050", "91051", "91053", "91054", "91056", "91057", "91060", "91062", "91064", "91065", "91066", "91068", "91069", "91074", "91076", "91079", "91082", "91085", "91086", "91087", "91088", "91089", "91091", "91092", "91098", "91101", "91103", "91104", "91106", "91107", "91109", "91112", "91113", "91115", "91119", "91120", "91121", "91122", "91123", "91131", "91133", "91137", "91140", "91142", "91143", "91148", "91149", "91151", "91152", "91158", "91161", "91162", "91165", "91166", "91169", "91171", "91172", "91174", "91175", "91177", "91178", "91181", "91183", "91184", "91186", "91188", "91189", "91191", "91196", "91197", "91198", "91201", "91203", "91209", "91210", "91212", "91213", "91214", "91217", "91218", "91221", "91222", "91223", "91225", "91227", "91228", "91232", "91233", "91236", "91237", "91238", "91239", "91242", "91246", "91247", "91248", "91249", "91251", "91252", "91254", "91255", "91256", "91257", "91259", "91261", "91263", "91264", "91266", "91271", "91275", "91276", "91278", "91279", "91281", "91282", "91283", "91284", "91285", "91286", "91287", "91288", "91289", "91290", "91294", "91295", "91296", "91297", "91299", "91303", "91304", "91305", "91307", "91309", "91312", "91313", "91314", "91315", "91316", "91322", "91325", "91327", "91328", "91330", "91332", "91334", "91335", "91336", "91338", "91339", "91340", "91341", "91345", "91346", "91348", "91349", "91350", "91351", "91352", "91353", "91360", "91363", "91364", "91366", "91368", "91369", "91372", "91374", "91376", "91379", "91380", "91381", "91383", "91391", "91398", "91401", "91402", "91403", "91406", "91409", "91411", "91412", "91413", "91415", "91417", "91418", "91419", "91420", "91421", "91422", "91423", "91425", "91426", "91429", "91430", "91431", "91433", "91435", "91439", "91442", "91444", "91446", "91449", "91451", "91453", "91455", "91456", "91457", "91458", "91459", "91460", "91463", "91465", "91466", "91467", "91470", "91471", "91472", "91475", "91477", "91478", "91479", "91480", "91481", "91482", "91483", "91485", "91488", "91491", "91492", "91493", "91494", "91495", "91496", "91497", "91498", "91499", "91501", "91504", "91505", "91511", "91516", "91519", "91520", "91522", "91523", "91524", "91525", "91527", "91528", "91529", "91531", "91532", "91533", "91534", "91536", "91537", "91538", "91539", "91540", "91542", "91543", "91546", "91547", "91548", "91549", "91550", "91551", "91553", "91556", "91557", "91558", "91559", "91561", "91562", "91563", "91564", "91565", "91566", "91570", "91572", "91573", "91576", "91577", "91580", "91583", "91584", "91585", "91587", "91588", "91593", "91594", "91595", "91596", "91599", "91601", "91602", "91604", "91606", "91607", "91612", "91615", "91618", "91619", "91621", "91623", "91625", "91626", "91627", "91628", "91630", "91632", "91633", "91634", "91635", "91636", "91637", "91639", "91641", "91645", "91647", "91649", "91652", "91653", "91654", "91656", "91657", "91658", "91659", "91660", "91661", "91662", "91664", "91665", "91666", "91667", "91668", "91669", "91671", "91672", "91673", "91674", "91675", "91680", "91681", "91682", "91684", "91685", "91688", "91689", "91694", "91703", "91709", "91710", "91714", "91716", "91719", "91721", "91722", "91724", "91726", "91734", "91736", "91739", "91740", "91745", "91746", "91747", "91748", "91751", "91752", "91756", "91757", "91758", "91759", "91760", "91761", "91763", "91764", "91766", "91767", "91769", "91772", "91773", "91776", "91777", "91778", "91784", "91786", "91787", "91789", "91791", "91792", "91795", "91796", "91797", "91799", "91800", "91802", "91804", "91805", "91806", "91808", "91811", "91813", "91817", "91818", "91821", "91824", "91825", "91826", "91827", "91829", "91833", "91834", "91839", "91841", "91842", "91843", "91845", "91846", "91851", "91853", "91854", "91855", "91856", "91859", "91860", "91864", "91865", "91866", "91868", "91869", "91870", "91871", "91872", "91874", "91876", "91882", "91883", "91885", "91886", "91887", "91888", "91889", "91890", "91891", "91892", "91893", "91897", "91899", "91900", "91901", "91902", "91904", "91905", "91907", "91908", "91909", "91911", "91912", "91913", "91918", "91920", "91921", "91923", "91924", "91926", "91927", "91929", "91932", "91934", "91936", "91937", "91940", "91943", "91947", "91948", "91949", "91952", "91953", "91954", "91959", "91960", "91961", "91964", "91965", "91967", "91969", "91970", "91974", "91976", "91979", "91982", "91985", "91986", "91990", "91991", "91996", "91998", "91999", "92000", "92001", "92002", "92003", "92004", "92005", "92006", "92007", "92010", "92014", "92015", "92018", "92019", "92023", "92024", "92029", "92030", "92031", "92035", "92037", "92038", "92041", "92044", "92045", "92049", "92050", "92051", "92052", "92054", "92055", "92058", "92061", "92062", "92064", "92065", "92067", "92068", "92069", "92072", "92076", "92077", "92078", "92080", "92081", "92083", "92087", "92088", "92090", "92093", "92096", "92098", "92099", "92101", "92103", "92107", "92108", "92114", "92115", "92117", "92119", "92120", "92121", "92123", "92125", "92126", "92127", "92129", "92132", "92133", "92135", "92136", "92138", "92139", "92141", "92143", "92146", "92159", "92160", "92162", "92164", "92166", "92167", "92168", "92170", "92171", "92173", "92174", "92177", "92179", "92180", "92181", "92183", "92185", "92186", "92189", "92192", "92193", "92196", "92197", "92200", "92201", "92202", "92203", "92204", "92206", "92208", "92209", "92210", "92211", "92212", "92214", "92217", "92219", "92223", "92226", "92227", "92228", "92229", "92230", "92231", "92236", "92237", "92238", "92243", "92245", "92246", "92247", "92251", "92252", "92255", "92257", "92259", "92261", "92263", "92266", "92267", "92268", "92269", "92273", "92274", "92276", "92277", "92280", "92282", "92283", "92284", "92285", "92286", "92287", "92290", "92291", "92292", "92294", "92295", "92298", "92300", "92301", "92302", "92303", "92305", "92307", "92308", "92309", "92310", "92311", "92314", "92319", "92320", "92322", "92323", "92325", "92327", "92328", "92329", "92330", "92334", "92336", "92337", "92343", "92344", "92345", "92349", "92353", "92355", "92356", "92360", "92361", "92363", "92364", "92365", "92366", "92367", "92368", "92369", "92372", "92374", "92377", "92378", "92379", "92386", "92388", "92393", "92394", "92395", "92396", "92398", "92399", "92402", "92403", "92404", "92405", "92409", "92411", "92414", "92415", "92417", "92419", "92421", "92423", "92429", "92431", "92432", "92433", "92434", "92436", "92438", "92440", "92441", "92442", "92444", "92448", "92450", "92451", "92455", "92456", "92457", "92458", "92459", "92460", "92462", "92463", "92464", "92465", "92467", "92468", "92469", "92470", "92473", "92474", "92477", "92480", "92482", "92487", "92490", "92491", "92495", "92496", "92497", "92498", "92499", "92500", "92503", "92505", "92506", "92508", "92511", "92512", "92513", "92515", "92520", "92522", "92523", "92524", "92526", "92528", "92530", "92534", "92538", "92539", "92540", "92542", "92543", "92544", "92545", "92548", "92554", "92557", "92559", "92561", "92562", "92564", "92565", "92566", "92567", "92577", "92578", "92579", "92580", "92581", "92582", "92583", "92587", "92588", "92589", "92590", "92591", "92592", "92594", "92595", "92597", "92599", "92601", "92603", "92605", "92607", "92612", "92613", "92617", "92618", "92619", "92621", "92622", "92628", "92631", "92634", "92635", "92636", "92638", "92639", "92640", "92642", "92644", "92645", "92646", "92647", "92651", "92652", "92653", "92655", "92656", "92660", "92661", "92662", "92666", "92669", "92675", "92676", "92678", "92684", "92686", "92687", "92688", "92689", "92690", "92691", "92692", "92694", "92695", "92696", "92698", "92700", "92703", "92704", "92707", "92708", "92709", "92712", "92714", "92717", "92718", "92722", "92725", "92727", "92728", "92729", "92734", "92739", "92741", "92743", "92745", "92747", "92748", "92749", "92750", "92751", "92752", "92758", "92760", "92761", "92762", "92764", "92765", "92766", "92767", "92768", "92771", "92774", "92777", "92779", "92781", "92784", "92787", "92791", "92792", "92793", "92794", "92796", "92798", "92799", "92801", "92802", "92803", "92804", "92806", "92808", "92810", "92811", "92812", "92814", "92815", "92819", "92821", "92822", "92823", "92825", "92828", "92832", "92834", "92836", "92841", "92842", "92843", "92844", "92845", "92846", "92848", "92849", "92852", "92853", "92855", "92859", "92861", "92862", "92863", "92864", "92868", "92869", "92872", "92874", "92876", "92877", "92878", "92880", "92881", "92882", "92883", "92884", "92885", "92886", "92887", "92890", "92896", "92897", "92899", "92900", "92902", "92904", "92906", "92907", "92909", "92910", "92914", "92915", "92917", "92918", "92920", "92921", "92922", "92923", "92924", "92932", "92933", "92934", "92935", "92936", "92937", "92941", "92942", "92945", "92946", "92948", "92949", "92952", "92954", "92957", "92960", "92961", "92963", "92964", "92966", "92967", "92969", "92970", "92971", "92973", "92974", "92976", "92977", "92978", "92979", "92981", "92982", "92983", "92989", "92991", "92993", "92995", "92996", "92997", "92999", "93000", "93003", "93005", "93006", "93007", "93008", "93009", "93011", "93013", "93014", "93017", "93024", "93025", "93028", "93031", "93032", "93033", "93034", "93036", "93039", "93040", "93041", "93043", "93045", "93046", "93047", "93048", "93050", "93051", "93052", "93055", "93056", "93057", "93059", "93061", "93064", "93066", "93067", "93068", "93069", "93071", "93077", "93078", "93081", "93082", "93083", "93084", "93085", "93087", "93089", "93091", "93095", "93096", "93100", "93101", "93104", "93105", "93106", "93107", "93108", "93111", "93113", "93115", "93122", "93123", "93124", "93127", "93129", "93132", "93134", "93135", "93136", "93138", "93142", "93143", "93145", "93146", "93150", "93151", "93153", "93154", "93155", "93157", "93158", "93159", "93160", "93162", "93163", "93164", "93165", "93166", "93167", "93169", "93171", "93172", "93173", "93176", "93177", "93178", "93179", "93180", "93181", "93182", "93184", "93195", "93196", "93197", "93205", "93207", "93209", "93210", "93211", "93212", "93215", "93216", "93217", "93218", "93219", "93220", "93221", "93223", "93225", "93226", "93228", "93230", "93231", "93232", "93237", "93238", "93239", "93240", "93241", "93245", "93246", "93247", "93249", "93250", "93251", "93252", "93254", "93255", "93257", "93258", "93260", "93262", "93265", "93266", "93267", "93268", "93271", "93273", "93274", "93275", "93276", "93277", "93280", "93282", "93283", "93285", "93287", "93288", "93289", "93292", "93293", "93295", "93296", "93300", "93301", "93302", "93303", "93305", "93306", "93309", "93312", "93315", "93316", "93318", "93319", "93324", "93325", "93326", "93327", "93331", "93332", "93333", "93334", "93336", "93337", "93338", "93339", "93340", "93341", "93342", "93344", "93346", "93351", "93352", "93353", "93354", "93357", "93360", "93361", "93366", "93367", "93369", "93370", "93376", "93379", "93382", "93383", "93389", "93390", "93391", "93392", "93395", "93396", "93397", "93399", "93400", "93402", "93403", "93406", "93407", "93411", "93412", "93417", "93422", "93423", "93424", "93429", "93433", "93434", "93436", "93437", "93438", "93441", "93444", "93449", "93450", "93451", "93452", "93453", "93455", "93457", "93458", "93459", "93460", "93462", "93466", "93467", "93470", "93471", "93472", "93476", "93477", "93478", "93479", "93480", "93481", "93487", "93488", "93489", "93490", "93491", "93493", "93494", "93496", "93500", "93501", "93502", "93503", "93507", "93509", "93510", "93511", "93514", "93515", "93518", "93523", "93525", "93526", "93529", "93530", "93532", "93535", "93538", "93539", "93542", "93544", "93545", "93549", "93553", "93554", "93555", "93557", "93562", "93563", "93566", "93569", "93570", "93572", "93574", "93576", "93577", "93579", "93582", "93584", "93585", "93586", "93587", "93588", "93589", "93596", "93597", "93599", "93604", "93605", "93608", "93613", "93614", "93616", "93620", "93623", "93625", "93626", "93627", "93628", "93629", "93630", "93631", "93632", "93633", "93634", "93636", "93641", "93644", "93646", "93647", "93648", "93649", "93650", "93654", "93655", "93656", "93660", "93662", "93663", "93664", "93670", "93671", "93672", "93674", "93676", "93677", "93678", "93679", "93681", "93683", "93686", "93687", "93690", "93697", "93698", "93699", "93700", "93701", "93705", "93707", "93708", "93709", "93710", "93711", "93712", "93713", "93715", "93717", "93718", "93719", "93723", "93727", "93728", "93729", "93730", "93733", "93735", "93738", "93744", "93745", "93746", "93749", "93755", "93757", "93759", "93760", "93761", "93762", "93765", "93767", "93769", "93770", "93771", "93772", "93775", "93776", "93777", "93779", "93780", "93781", "93783", "93786", "93787", "93790", "93791", "93792", "93793", "93794", "93795", "93796", "93797", "93799", "93801", "93802", "93804", "93805", "93806", "93811", "93812", "93815", "93816", "93817", "93818", "93821", "93823", "93825", "93826", "93827", "93828", "93829", "93831", "93832", "93833", "93834", "93836", "93837", "93838", "93839", "93841", "93842", "93843", "93844", "93847", "93850", "93851", "93852", "93855", "93857", "93859", "93861", "93864", "93865", "93869", "93870", "93872", "93876", "93878", "93881", "93882", "93883", "93887", "93889", "93894", "93896", "93897", "93902", "93903", "93911", "93917", "93920", "93921", "93923", "93925", "93926", "93927", "93928", "93929", "93930", "93932", "93936", "93939", "93941", "93942", "93943", "93944", "93947", "93948", "93951", "93952", "93953", "93954", "93956", "93960", "93963", "93964", "93967", "93969", "93971", "93976", "93978", "93979", "93980", "93981", "93982", "93988", "93989", "93991", "93992", "93993", "93994", "93995", "93997", "93998", "93999", "94000", "94001", "94002", "94005", "94006", "94008", "94009", "94011", "94012", "94013", "94015", "94017", "94018", "94019", "94023", "94025", "94027", "94028", "94030", "94031", "94033", "94034", "94035", "94036", "94038", "94041", "94045", "94046", "94047", "94048", "94049", "94050", "94053", "94055", "94056", "94057", "94058", "94060", "94061", "94062", "94065", "94066", "94068", "94072", "94074", "94075", "94076", "94077", "94082", "94088", "94091", "94093", "94094", "94098", "94099", "94100", "94102", "94103", "94110", "94114", "94118", "94119", "94120", "94123", "94125", "94129", "94130", "94131", "94134", "94135", "94138", "94141", "94145", "94149", "94150", "94151", "94155", "94156", "94157", "94160", "94161", "94166", "94167", "94169", "94172", "94173", "94177", "94178", "94179", "94180", "94183", "94185", "94188", "94191", "94192", "94196", "94197", "94200", "94202", "94205", "94206", "94207", "94209", "94212", "94214", "94215", "94218", "94219", "94220", "94224", "94225", "94228", "94229", "94230", "94233", "94234", "94237", "94238", "94239", "94240", "94242", "94243", "94246", "94248", "94249", "94250", "94251", "94252", "94253", "94254", "94255", "94256", "94257", "94261", "94262", "94267", "94269", "94272", "94273", "94274", "94276", "94280", "94281", "94282", "94283", "94284", "94285", "94286", "94289", "94292", "94294", "94295", "94297", "94298", "94299", "94301", "94302", "94303", "94305", "94306", "94307", "94310", "94311", "94312", "94313", "94315", "94318", "94319", "94320", "94322", "94323", "94325", "94327", "94328", "94334", "94335", "94337", "94339", "94345", "94347", "94350", "94352", "94353", "94357", "94358", "94362", "94363", "94366", "94367", "94369", "94370", "94373", "94375", "94376", "94377", "94378", "94381", "94383", "94385", "94386", "94388", "94389", "94391", "94393", "94401", "94402", "94403", "94407", "94409", "94410", "94413", "94416", "94417", "94418", "94419", "94421", "94430", "94431", "94433", "94435", "94436", "94437", "94439", "94441", "94442", "94447", "94449", "94451", "94452", "94453", "94455", "94461", "94462", "94463", "94466", "94468", "94470", "94472", "94480", "94482", "94483", "94487", "94492", "94493", "94496", "94497", "94500", "94504", "94505", "94506", "94507", "94508", "94509", "94511", "94513", "94514", "94515", "94516", "94518", "94520", "94521", "94522", "94523", "94524", "94526", "94528", "94530", "94533", "94535", "94537", "94538", "94539", "94540", "94543", "94548", "94551", "94552", "94553", "94555", "94556", "94558", "94561", "94562", "94563", "94565", "94568", "94569", "94571", "94572", "94573", "94574", "94575", "94579", "94581", "94583", "94584", "94586", "94588", "94589", "94590", "94591", "94592", "94594", "94595", "94596", "94598", "94599", "94600", "94601", "94606", "94607", "94608", "94610", "94611", "94613", "94616", "94621", "94624", "94625", "94626", "94627", "94634", "94636", "94637", "94643", "94644", "94645", "94647", "94655", "94656", "94657", "94659", "94660", "94663", "94668", "94669", "94672", "94674", "94675", "94677", "94682", "94683", "94684", "94685", "94686", "94687", "94688", "94689", "94691", "94693", "94697", "94700", "94701", "94702", "94703", "94707", "94713", "94714", "94715", "94718", "94719", "94720", "94722", "94724", "94729", "94733", "94734", "94736", "94737", "94741", "94742", "94744", "94745", "94746", "94747", "94748", "94750", "94753", "94754", "94755", "94757", "94758", "94759", "94763", "94764", "94765", "94769", "94770", "94773", "94780", "94784", "94788", "94791", "94792", "94795", "94797", "94799", "94801", "94802", "94804", "94807", "94809", "94810", "94813", "94815", "94819", "94824", "94826", "94828", "94829", "94830", "94831", "94832", "94833", "94834", "94836", "94837", "94838", "94839", "94840", "94841", "94843", "94844", "94846", "94847", "94848", "94849", "94851", "94852", "94853", "94856", "94858", "94860", "94861", "94863", "94865", "94867", "94868", "94869", "94870", "94871", "94874", "94875", "94876", "94878", "94880", "94883", "94885", "94886", "94887", "94894", "94895", "94897", "94899", "94900", "94902", "94905", "94907", "94910", "94911", "94912", "94914", "94915", "94919", "94920", "94923", "94925", "94926", "94930", "94931", "94935", "94936", "94938", "94939", "94941", "94942", "94944", "94945", "94946", "94947", "94948", "94949", "94950", "94953", "94955", "94956", "94957", "94958", "94961", "94964", "94967", "94968", "94973", "94974", "94975", "94984", "94991", "94993", "94994", "94996", "94997", "95001", "95003", "95004", "95005", "95011", "95012", "95013", "95014", "95015", "95016", "95018", "95019", "95026", "95028", "95029", "95033", "95035", "95038", "95039", "95040", "95044", "95045", "95049", "95050", "95051", "95052", "95054", "95056", "95057", "95059", "95060", "95061", "95062", "95066", "95067", "95070", "95071", "95072", "95073", "95074", "95080", "95082", "95083", "95089", "95090", "95092", "95094", "95095", "95096", "95097", "95098", "95099", "95100", "95102", "95106", "95109", "95110", "95113", "95117", "95118", "95119", "95122", "95123", "95124", "95125", "95126", "95127", "95129", "95130", "95132", "95133", "95134", "95135", "95138", "95139", "95140", "95141", "95143", "95146", "95147", "95148", "95149", "95151", "95153", "95155", "95157", "95158", "95161", "95164", "95166", "95167", "95171", "95174", "95175", "95177", "95179", "95180", "95181", "95184", "95185", "95186", "95187", "95188", "95190", "95191", "95192", "95195", "95197", "95200", "95202", "95203", "95205", "95210", "95214", "95215", "95217", "95218", "95220", "95222", "95223", "95226", "95227", "95228", "95229", "95230", "95231", "95232", "95238", "95240", "95243", "95246", "95247", "95249", "95251", "95252", "95253", "95262", "95264", "95266", "95267", "95270", "95271", "95272", "95275", "95276", "95278", "95279", "95282", "95283", "95291", "95292", "95293", "95294", "95295", "95296", "95297", "95300", "95303", "95304", "95306", "95311", "95313", "95314", "95315", "95317", "95324", "95325", "95327", "95328", "95329", "95331", "95332", "95333", "95334", "95338", "95339", "95340", "95342", "95344", "95347", "95348", "95349", "95352", "95353", "95354", "95355", "95356", "95357", "95358", "95359", "95361", "95362", "95364", "95365", "95367", "95369", "95370", "95371", "95373", "95374", "95375", "95376", "95378", "95381", "95388", "95389", "95390", "95392", "95395", "95397", "95398", "95402", "95403", "95405", "95407", "95408", "95416", "95420", "95421", "95422", "95423", "95425", "95427", "95429", "95430", "95431", "95432", "95435", "95438", "95439", "95441", "95442", "95443", "95444", "95445", "95449", "95451", "95452", "95454", "95455", "95456", "95457", "95458", "95460", "95461", "95464", "95468", "95469", "95471", "95472", "95473", "95475", "95478", "95480", "95482", "95483", "95484", "95486", "95490", "95492", "95493", "95495", "95496", "95499", "95500", "95501", "95503", "95505", "95510", "95511", "95512", "95514", "95517", "95518", "95519", "95521", "95523", "95525", "95527", "95528", "95532", "95535", "95536", "95537", "95539", "95540", "95542", "95548", "95549", "95555", "95556", "95558", "95559", "95561", "95564", "95565", "95566", "95568", "95570", "95571", "95572", "95573", "95575", "95576", "95581", "95582", "95583", "95584", "95589", "95591", "95592", "95593", "95594", "95595", "95596", "95597", "95599", "95600", "95602", "95605", "95606", "95607", "95609", "95611", "95612", "95615", "95616", "95617", "95618", "95619", "95622", "95624", "95628", "95631", "95632", "95634", "95635", "95638", "95640", "95641", "95642", "95644", "95646", "95647", "95648", "95651", "95653", "95654", "95657", "95658", "95659", "95663", "95664", "95668", "95672", "95674", "95675", "95679", "95680", "95683", "95686", "95687", "95688", "95691", "95694", "95698", "95700", "95702", "95705", "95709", "95714", "95715", "95716", "95718", "95720", "95721", "95724", "95725", "95728", "95733", "95734", "95736", "95739", "95740", "95742", "95743", "95745", "95747", "95750", "95751", "95753", "95758", "95759", "95760", "95761", "95762", "95764", "95765", "95767", "95769", "95773", "95774", "95775", "95777", "95778", "95780", "95781", "95782", "95783", "95786", "95791", "95793", "95794", "95797", "95800", "95801", "95803", "95807", "95809", "95810", "95811", "95812", "95813", "95814", "95816", "95821", "95824", "95825", "95828", "95829", "95830", "95832", "95834", "95835", "95838", "95839", "95840", "95842", "95845", "95846", "95847", "95851", "95854", "95855", "95856", "95858", "95861", "95864", "95866", "95867", "95870", "95872", "95873", "95874", "95875", "95877", "95878", "95879", "95881", "95888", "95889", "95890", "95891", "95893", "95894", "95895", "95896", "95898", "95899", "95900", "95901", "95904", "95905", "95906", "95907", "95912", "95914", "95916", "95917", "95920", "95921", "95923", "95924", "95927", "95929", "95930", "95931", "95933", "95939", "95941", "95943", "95947", "95948", "95949", "95950", "95953", "95955", "95956", "95958", "95964", "95965", "95966", "95967", "95970", "95976", "95978", "95979", "95980", "95982", "95984", "95987", "95989", "95990", "95991", "95992", "95994", "95995", "95997", "95998", "95999", "96003", "96004", "96006", "96010", "96013", "96014", "96015", "96017", "96019", "96020", "96021", "96022", "96025", "96027", "96028", "96031", "96032", "96034", "96035", "96038", "96039", "96040", "96041", "96042", "96043", "96044", "96047", "96048", "96050", "96051", "96052", "96055", "96056", "96057", "96060", "96062", "96063", "96064", "96066", "96067", "96068", "96069", "96070", "96071", "96075", "96076", "96080", "96081", "96082", "96083", "96085", "96087", "96090", "96093", "96097", "96098", "96099", "96100", "96102", "96104", "96107", "96110", "96112", "96113", "96115", "96117", "96120", "96121", "96122", "96123", "96124", "96126", "96129", "96130", "96132", "96133", "96135", "96136", "96142", "96145", "96147", "96148", "96149", "96150", "96152", "96154", "96156", "96162", "96163", "96164", "96166", "96167", "96168", "96169", "96170", "96172", "96173", "96175", "96177", "96178", "96180", "96183", "96186", "96190", "96191", "96193", "96201", "96202", "96203", "96204", "96205", "96206", "96207", "96209", "96211", "96213", "96214", "96218", "96219", "96220", "96221", "96222", "96223", "96224", "96228", "96230", "96231", "96232", "96234", "96238", "96239", "96241", "96242", "96244", "96246", "96247", "96249", "96255", "96259", "96262", "96265", "96266", "96272", "96273", "96274", "96275", "96277", "96278", "96279", "96282", "96284", "96287", "96289", "96291", "96292", "96293", "96299", "96302", "96303", "96304", "96311", "96313", "96314", "96316", "96317", "96318", "96319", "96322", "96324", "96325", "96327", "96330", "96331", "96332", "96333", "96335", "96337", "96338", "96340", "96343", "96345", "96346", "96347", "96349", "96352", "96354", "96356", "96357", "96358", "96359", "96362", "96365", "96367", "96368", "96371", "96372", "96373", "96374", "96375", "96376", "96379", "96380", "96384", "96390", "96391", "96392", "96394", "96395", "96396", "96397", "96398", "96399", "96400", "96402", "96404", "96410", "96415", "96416", "96417", "96418", "96419", "96426", "96427", "96430", "96435", "96437", "96439", "96440", "96441", "96442", "96446", "96447", "96448", "96451", "96452", "96454", "96456", "96458", "96459", "96460", "96461", "96462", "96463", "96464", "96465", "96469", "96470", "96471", "96476", "96478", "96485", "96487", "96490", "96493", "96494", "96495", "96497", "96498", "96500", "96501", "96503", "96505", "96506", "96509", "96512", "96516", "96520", "96522", "96524", "96525", "96527", "96528", "96529", "96530", "96536", "96539", "96540", "96544", "96545", "96546", "96547", "96550", "96552", "96553", "96556", "96557", "96561", "96562", "96563", "96564", "96568", "96569", "96573", "96574", "96575", "96577", "96580", "96582", "96584", "96585", "96586", "96587", "96588", "96594", "96597", "96599", "96601", "96605", "96606", "96609", "96611", "96612", "96616", "96618", "96619", "96622", "96623", "96624", "96625", "96631", "96632", "96633", "96635", "96637", "96643", "96644", "96645", "96646", "96648", "96651", "96652", "96653", "96659", "96662", "96663", "96664", "96665", "96666", "96668", "96670", "96672", "96674", "96676", "96677", "96680", "96681", "96682", "96683", "96686", "96687", "96689", "96690", "96691", "96694", "96695", "96696", "96698", "96700", "96702", "96703", "96705", "96706", "96708", "96710", "96711", "96713", "96714", "96715", "96717", "96721", "96722", "96727", "96729", "96731", "96732", "96734", "96736", "96737", "96741", "96746", "96747", "96752", "96755", "96756", "96757", "96760", "96762", "96763", "96766", "96769", "96770", "96771", "96775", "96776", "96777", "96779", "96783", "96784", "96785", "96786", "96787", "96788", "96789", "96791", "96792", "96795", "96796", "96798", "96802", "96805", "96806", "96807", "96808", "96809", "96812", "96813", "96814", "96815", "96816", "96818", "96821", "96823", "96824", "96825", "96827", "96829", "96830", "96831", "96832", "96835", "96837", "96840", "96841", "96843", "96844", "96846", "96848", "96849", "96851", "96852", "96853", "96855", "96856", "96858", "96859", "96861", "96863", "96864", "96865", "96866", "96867", "96868", "96869", "96871", "96872", "96875", "96876", "96881", "96889", "96893", "96896", "96900", "96901", "96902", "96903", "96904", "96905", "96907", "96908", "96910", "96911", "96912", "96915", "96916", "96917", "96918", "96922", "96927", "96932", "96937", "96938", "96942", "96943", "96945", "96947", "96949", "96951", "96952", "96953", "96954", "96955", "96959", "96961", "96965", "96966", "96967", "96969", "96976", "96978", "96979", "96980", "96982", "96983", "96984", "96986", "96989", "96990", "96991", "96997", "97004", "97005", "97007", "97009", "97010", "97013", "97014", "97015", "97016", "97017", "97020", "97021", "97022", "97024", "97031", "97032", "97035", "97038", "97040", "97041", "97042", "97043", "97044", "97048", "97052", "97056", "97060", "97066", "97068", "97071", "97076", "97077", "97079", "97082", "97084", "97085", "97086", "97090", "97092", "97094", "97095", "97096", "97097", "97098", "97101", "97102", "97104", "97105", "97106", "97107", "97108", "97110", "97113", "97114", "97115", "97118", "97119", "97120", "97122", "97125", "97129", "97130", "97131", "97132", "97138", "97139", "97140", "97144", "97148", "97149", "97150", "97153", "97154", "97155", "97156", "97157", "97159", "97160", "97162", "97163", "97168", "97172", "97175", "97179", "97180", "97181", "97182", "97183", "97184", "97185", "97188", "97189", "97192", "97193", "97194", "97198", "97200", "97201", "97204", "97205", "97206", "97208", "97211", "97212", "97214", "97215", "97217", "97221", "97222", "97223", "97224", "97225", "97226", "97229", "97230", "97231", "97233", "97235", "97237", "97238", "97240", "97241", "97242", "97244", "97246", "97255", "97256", "97260", "97264", "97267", "97268", "97269", "97270", "97271", "97272", "97273", "97275", "97277", "97278", "97279", "97284", "97286", "97287", "97289", "97291", "97292", "97295", "97296", "97297", "97299", "97300", "97301", "97304", "97305", "97307", "97308", "97309", "97310", "97311", "97312", "97316", "97319", "97323", "97325", "97326", "97327", "97328", "97330", "97331", "97332", "97336", "97339", "97341", "97343", "97345", "97346", "97347", "97348", "97350", "97353", "97355", "97357", "97359", "97360", "97362", "97368", "97369", "97370", "97372", "97373", "97375", "97378", "97380", "97381", "97382", "97384", "97385", "97386", "97387", "97388", "97391", "97393", "97395", "97398", "97400", "97402", "97404", "97405", "97406", "97409", "97410", "97419", "97421", "97422", "97423", "97424", "97427", "97430", "97432", "97437", "97439", "97440", "97441", "97442", "97444", "97445", "97446", "97449", "97450", "97451", "97456", "97458", "97463", "97465", "97466", "97468", "97470", "97473", "97475", "97476", "97479", "97481", "97484", "97487", "97488", "97491", "97494", "97495", "97496", "97498", "97499", "97500", "97501", "97502", "97503", "97505", "97507", "97508", "97512", "97513", "97516", "97517", "97520", "97522", "97526", "97528", "97529", "97530", "97531", "97532", "97536", "97537", "97539", "97544", "97545", "97548", "97550", "97551", "97552", "97554", "97556", "97558", "97562", "97564", "97566", "97567", "97568", "97570", "97571", "97573", "97575", "97576", "97578", "97579", "97580", "97581", "97585", "97587", "97588", "97589", "97590", "97593", "97594", "97595", "97596", "97597", "97598", "97599", "97600", "97601", "97602", "97603", "97604", "97605", "97606", "97607", "97610", "97612", "97617", "97620", "97621", "97624", "97625", "97626", "97627", "97628", "97629", "97636", "97637", "97638", "97647", "97648", "97651", "97652", "97654", "97655", "97656", "97657", "97664", "97665", "97666", "97668", "97670", "97672", "97674", "97675", "97676", "97680", "97684", "97685", "97687", "97688", "97690", "97694", "97697", "97698", "97699", "97700", "97701", "97704", "97705", "97706", "97707", "97708", "97710", "97711", "97713", "97715", "97720", "97722", "97723", "97725", "97726", "97730", "97731", "97735", "97738", "97740", "97741", "97742", "97747", "97748", "97752", "97753", "97754", "97756", "97757", "97758", "97759", "97760", "97762", "97763", "97764", "97766", "97767", "97768", "97770", "97771", "97772", "97773", "97774", "97775", "97776", "97780", "97782", "97784", "97786", "97790", "97791", "97792", "97795", "97806", "97807", "97808", "97809", "97811", "97812", "97813", "97816", "97818", "97820", "97821", "97822", "97823", "97824", "97826", "97828", "97829", "97831", "97834", "97836", "97837", "97839", "97848", "97849", "97850", "97852", "97853", "97854", "97856", "97859", "97861", "97862", "97863", "97864", "97865", "97866", "97868", "97871", "97873", "97875", "97876", "97877", "97879", "97881", "97882", "97883", "97886", "97887", "97892", "97895", "97896", "97898", "97899", "97905", "97906", "97907", "97908", "97910", "97912", "97915", "97916", "97917", "97919", "97922", "97927", "97931", "97934", "97935", "97936", "97937", "97939", "97940", "97941", "97946", "97948", "97949", "97952", "97954", "97957", "97958", "97959", "97961", "97962", "97964", "97965", "97967", "97968", "97969", "97970", "97972", "97975", "97978", "97980", "97985", "97988", "97991", "97992", "97994", "97995", "97996", "97997", "97999", "98001", "98003", "98004", "98005", "98006", "98007", "98008", "98009", "98012", "98013", "98015", "98016", "98018", "98020", "98023", "98029", "98030", "98034", "98039", "98041", "98042", "98044", "98046", "98047", "98050", "98051", "98053", "98054", "98055", "98056", "98057", "98059", "98063", "98064", "98066", "98068", "98069", "98070", "98072", "98073", "98082", "98083", "98085", "98087", "98088", "98089", "98090", "98093", "98094", "98095", "98097", "98101", "98102", "98103", "98104", "98105", "98106", "98110", "98111", "98114", "98117", "98118", "98123", "98128", "98129", "98131", "98132", "98134", "98135", "98137", "98138", "98140", "98146", "98149", "98155", "98156", "98157", "98159", "98160", "98165", "98167", "98172", "98174", "98175", "98176", "98178", "98181", "98182", "98183", "98184", "98185", "98186", "98187", "98188", "98191", "98192", "98193", "98195", "98196", "98197", "98199", "98203", "98207", "98213", "98214", "98218", "98219", "98220", "98221", "98223", "98225", "98228", "98230", "98231", "98236", "98238", "98240", "98244", "98247", "98251", "98253", "98254", "98255", "98256", "98259", "98260", "98264", "98268", "98269", "98271", "98273", "98274", "98276", "98277", "98279", "98281", "98283", "98284", "98286", "98288", "98296", "98299", "98300", "98304", "98308", "98310", "98311", "98312", "98314", "98316", "98320", "98323", "98328", "98329", "98331", "98333", "98334", "98337", "98339", "98341", "98342", "98343", "98344", "98349", "98351", "98353", "98354", "98355", "98357", "98358", "98359", "98361", "98362", "98364", "98366", "98367", "98371", "98372", "98373", "98376", "98377", "98378", "98382", "98385", "98389", "98392", "98393", "98394", "98395", "98397", "98398", "98401", "98403", "98408", "98409", "98411", "98414", "98417", "98418", "98419", "98422", "98423", "98425", "98426", "98428", "98429", "98430", "98432", "98434", "98435", "98436", "98439", "98440", "98441", "98444", "98445", "98449", "98450", "98451", "98452", "98454", "98455", "98456", "98457", "98459", "98460", "98461", "98462", "98464", "98467", "98468", "98474", "98480", "98481", "98482", "98483", "98484", "98489", "98490", "98491", "98492", "98496", "98500", "98503", "98504", "98507", "98508", "98509", "98510", "98512", "98514", "98515", "98517", "98518", "98519", "98524", "98531", "98535", "98536", "98537", "98540", "98544", "98545", "98550", "98552", "98553", "98555", "98557", "98559", "98560", "98561", "98563", "98564", "98567", "98571", "98573", "98575", "98584", "98585", "98588", "98589", "98590", "98591", "98592", "98594", "98596", "98598", "98599", "98600", "98602", "98603", "98604", "98607", "98608", "98616", "98618", "98619", "98623", "98624", "98627", "98632", "98633", "98635", "98638", "98641", "98643", "98644", "98645", "98648", "98652", "98655", "98656", "98662", "98663", "98664", "98665", "98669", "98672", "98674", "98676", "98677", "98679", "98682", "98683", "98684", "98685", "98686", "98690", "98692", "98693", "98695", "98701", "98703", "98705", "98706", "98708", "98709", "98710", "98711", "98712", "98714", "98715", "98716", "98717", "98719", "98721", "98722", "98724", "98726", "98727", "98730", "98732", "98733", "98735", "98737", "98740", "98742", "98744", "98750", "98751", "98752", "98753", "98755", "98756", "98757", "98758", "98759", "98760", "98766", "98767", "98768", "98769", "98772", "98776", "98777", "98778", "98779", "98781", "98782", "98786", "98790", "98793", "98794", "98795", "98796", "98800", "98801", "98802", "98803", "98804", "98808", "98809", "98810", "98811", "98815", "98816", "98817", "98820", "98824", "98826", "98828", "98829", "98832", "98833", "98835", "98836", "98837", "98838", "98840", "98844", "98850", "98851", "98856", "98857", "98859", "98860", "98861", "98862", "98864", "98865", "98867", "98868", "98869", "98870", "98871", "98873", "98874", "98875", "98876", "98877", "98880", "98881", "98882", "98886", "98887", "98889", "98890", "98892", "98893", "98894", "98896", "98898", "98900", "98901", "98902", "98904", "98906", "98908", "98909", "98910", "98913", "98916", "98918", "98920", "98921", "98922", "98926", "98927", "98930", "98933", "98935", "98936", "98940", "98941", "98942", "98943", "98949", "98950", "98951", "98952", "98954", "98955", "98956", "98957", "98958", "98959", "98960", "98961", "98962", "98963", "98964", "98967", "98968", "98972", "98974", "98979", "98981", "98983", "98984", "98986", "98990", "98991", "98993", "98994", "98995", "98997", "98998", "98999", "99000", "99003", "99004", "99005", "99011", "99012", "99014", "99015", "99018", "99019", "99023", "99024", "99026", "99029", "99030", "99031", "99032", "99035", "99036", "99037", "99039", "99042", "99043", "99048", "99049", "99050", "99055", "99057", "99058", "99060", "99062", "99064", "99066", "99067", "99072", "99077", "99078", "99080", "99082", "99083", "99087", "99090", "99091", "99093", "99094", "99098", "99099", "99100", "99101", "99102", "99103", "99104", "99107", "99108", "99114", "99115", "99116", "99120", "99124", "99127", "99128", "99129", "99130", "99131", "99132", "99134", "99136", "99139", "99141", "99143", "99144", "99145", "99150", "99152", "99153", "99158", "99159", "99164", "99165", "99168", "99169", "99170", "99171", "99173", "99175", "99176", "99177", "99181", "99182", "99183", "99185", "99186", "99189", "99191", "99192", "99193", "99194", "99195", "99196", "99197", "99201", "99202", "99204", "99205", "99207", "99212", "99213", "99214", "99215", "99216", "99217", "99218", "99220", "99221", "99224", "99227", "99228", "99232", "99235", "99237", "99238", "99243", "99244", "99250", "99251", "99252", "99253", "99257", "99258", "99261", "99262", "99263", "99264", "99265", "99266", "99267", "99268", "99269", "99270", "99273", "99274", "99277", "99279", "99281", "99284", "99286", "99287", "99288", "99290", "99295", "99297", "99299", "99300", "99302", "99303", "99304", "99305", "99306", "99311", "99314", "99318", "99320", "99322", "99323", "99325", "99326", "99327", "99331", "99337", "99338", "99339", "99342", "99343", "99348", "99351", "99355", "99357", "99360", "99362", "99364", "99365", "99370", "99371", "99372", "99373", "99381", "99384", "99387", "99389", "99390", "99391", "99394", "99396", "99399", "99401", "99402", "99403", "99408", "99409", "99410", "99411", "99412", "99413", "99414", "99416", "99418", "99419", "99421", "99424", "99426", "99430", "99431", "99434", "99438", "99439", "99441", "99447", "99448", "99449", "99451", "99452", "99455", "99456", "99458", "99460", "99463", "99465", "99466", "99469", "99470", "99472", "99473", "99479", "99486", "99487", "99488", "99489", "99499", "99500", "99501", "99503", "99504", "99505", "99508", "99509", "99510", "99514", "99516", "99521", "99522", "99523", "99527", "99533", "99535", "99537", "99538", "99542", "99544", "99545", "99548", "99550", "99554", "99556", "99559", "99560", "99567", "99570", "99572", "99573", "99574", "99575", "99582", "99583", "99584", "99586", "99588", "99589", "99591", "99596", "99600", "99602", "99603", "99604", "99606", "99607", "99609", "99610", "99612", "99613", "99616", "99620", "99621", "99623", "99627", "99629", "99630", "99632", "99634", "99635", "99641", "99643", "99650", "99651", "99652", "99653", "99654", "99655", "99656", "99657", "99661", "99663", "99664", "99665", "99666", "99668", "99670", "99671", "99673", "99674", "99675", "99679", "99684", "99689", "99693", "99695", "99696", "99699", "99700", "99702", "99703", "99705", "99706", "99710", "99711", "99714", "99715", "99716", "99719", "99720", "99721", "99722", "99723", "99726", "99727", "99728", "99731", "99732", "99733", "99734", "99736", "99737", "99738", "99739", "99741", "99743", "99746", "99747", "99748", "99749", "99750", "99757", "99759", "99760", "99761", "99762", "99763", "99765", "99766", "99769", "99772", "99777", "99778", "99783", "99785", "99787", "99788", "99789", "99791", "99795", "99796", "99798", "99799", "99801", "99803", "99804", "99805", "99806", "99807", "99809", "99812", "99813", "99814", "99821", "99823", "99824", "99828", "99829", "99830", "99831", "99832", "99835", "99838", "99839", "99840", "99841", "99846", "99848", "99849", "99850", "99852", "99853", "99854", "99859", "99861", "99864", "99865", "99866", "99870", "99874", "99876", "99878", "99880", "99881", "99884", "99885", "99886", "99891", "99893", "99897", "99898", "99899", "99901", "99902", "99903", "99904", "99905", "99907", "99914", "99916", "99919", "99920", "99921", "99922", "99923", "99924", "99926", "99927", "99930", "99932", "99933", "99934", "99935", "99937", "99938", "99944", "99945", "99946", "99949", "99953", "99954", "99957", "99958", "99959", "99960", "99964", "99966", "99970", "99972", "99973", "99975", "99976", "99979", "99980", "99984", "99986", "99988", "99989", "99990", "99991", "99992", "99993", "99994", "99997", "99998", "100001", "100002", "100004", "100006", "100008", "100009", "100010", "100011", "100014", "100017", "100020", "100021", "100022", "100023", "100028", "100029", "100032", "100033", "100034", "100035", "100037", "100045", "100049", "100050", "100052", "100054", "100059", "100060", "100061", "100064", "100065", "100066", "100067", "100069", "100071", "100073", "100075", "100076", "100079", "100080", "100081", "100082", "100084", "100087", "100090", "100091", "100095", "100097", "100098", "100102", "100103", "100106", "100109", "100111", "100114", "100118", "100121", "100122", "100123", "100124", "100126", "100128", "100129", "100130", "100132", "100133", "100134", "100135", "100137", "100142", "100143", "100144", "100145", "100150", "100151", "100152", "100154", "100155", "100159", "100160", "100161", "100162", "100163", "100165", "100167", "100168", "100169", "100171", "100172", "100176", "100177", "100178", "100191", "100192", "100193", "100198", "100201", "100204", "100205", "100206", "100207", "100211", "100212", "100213", "100217", "100220", "100224", "100225", "100226", "100227", "100228", "100232", "100234", "100240", "100241", "100242", "100243", "100244", "100247", "100248", "100249", "100251", "100257", "100259", "100261", "100262", "100263", "100264", "100265", "100266", "100268", "100272", "100273", "100279", "100280", "100281", "100284", "100285", "100286", "100290", "100292", "100293", "100294", "100295", "100296", "100298", "100301", "100302", "100303", "100305", "100306", "100310", "100315", "100317", "100324", "100327", "100330", "100331", "100334", "100335", "100338", "100340", "100341", "100342", "100343", "100345", "100349", "100350", "100351", "100352", "100354", "100355", "100358", "100359", "100364", "100366", "100367", "100369", "100371", "100372", "100375", "100377", "100379", "100384", "100390", "100391", "100392", "100393", "100394", "100395", "100396", "100397", "100402", "100403", "100404", "100406", "100407", "100410", "100411", "100412", "100414", "100417", "100422", "100423", "100426", "100427", "100428", "100429", "100433", "100436", "100439", "100440", "100441", "100448", "100449", "100451", "100452", "100453", "100454", "100457", "100459", "100461", "100462", "100467", "100468", "100470", "100471", "100473", "100475", "100477", "100478", "100480", "100481", "100483", "100484", "100486", "100488", "100490", "100492", "100493", "100495", "100496", "100497", "100498", "100499", "100500", "100502", "100503", "100506", "100508", "100510", "100513", "100514", "100516", "100518", "100520", "100521", "100523", "100525", "100528", "100531", "100532", "100534", "100535", "100536", "100539", "100540", "100541", "100542", "100545", "100546", "100547", "100548", "100551", "100552", "100553", "100554", "100556", "100557", "100566", "100567", "100568", "100570", "100577", "100578", "100580", "100581", "100582", "100583", "100584", "100585", "100587", "100588", "100589", "100591", "100595", "100596", "100597", "100600", "100602", "100603", "100605", "100606", "100607", "100609", "100610", "100612", "100616", "100618", "100620", "100624", "100625", "100627", "100628", "100631", "100633", "100636", "100637", "100638", "100639", "100641", "100642", "100643", "100645", "100649", "100654", "100655", "100656", "100657", "100658", "100659", "100661", "100662", "100670", "100673", "100675", "100677", "100679", "100680", "100681", "100682", "100683", "100686", "100687", "100689", "100693", "100695", "100696", "100697", "100698", "100700", "100702", "100703", "100707", "100710", "100713", "100714", "100715", "100716", "100717", "100720", "100721", "100724", "100725", "100726", "100729", "100730", "100732", "100736", "100737", "100742", "100743", "100744", "100747", "100751", "100753", "100755", "100756", "100758", "100760", "100765", "100767", "100769", "100771", "100774", "100775", "100776", "100777", "100780", "100781", "100782", "100785", "100786", "100788", "100789", "100790", "100794", "100798", "100799", "100802", "100805", "100808", "100810", "100811", "100813", "100814", "100815", "100817", "100818", "100823", "100826", "100827", "100830", "100832", "100835", "100836", "100840", "100844", "100845", "100849", "100850", "100854", "100856", "100858", "100861", "100870", "100872", "100874", "100876", "100877", "100879", "100880", "100882", "100883", "100887", "100891", "100892", "100895", "100896", "100897", "100898", "100900", "100901", "100904", "100905", "100906", "100909", "100911", "100912", "100915", "100917", "100919", "100920", "100921", "100923", "100925", "100926", "100928", "100929", "100933", "100937", "100938", "100939", "100940", "100947", "100948", "100951", "100952", "100955", "100957", "100958", "100959", "100961", "100962", "100963", "100964", "100969", "100974", "100975", "100976", "100977", "100981", "100982", "100984", "100986", "100988", "100990", "100993", "100994", "100997", "100998", "101001", "101003", "101006", "101011", "101013", "101014", "101015", "101019", "101021", "101034", "101035", "101037", "101038", "101040", "101052", "101056", "101060", "101061", "101064", "101065", "101066", "101067", "101068", "101070", "101071", "101072", "101076", "101079", "101082", "101083", "101084", "101085", "101089", "101091", "101092", "101093", "101094", "101096", "101101", "101102", "101104", "101106", "101107", "101108", "101113", "101114", "101115", "101116", "101117", "101120", "101123", "101124", "101125", "101126", "101129", "101131", "101134", "101138", "101141", "101142", "101143", "101144", "101145", "101146", "101147", "101150", "101154", "101156", "101158", "101160", "101163", "101166", "101167", "101170", "101173", "101181", "101182", "101183", "101185", "101186", "101191", "101192", "101194", "101197", "101201", "101203", "101204", "101208", "101209", "101210", "101211", "101215", "101217", "101219", "101222", "101223", "101224", "101227", "101229", "101232", "101234", "101237", "101239", "101242", "101248", "101249", "101251", "101252", "101254", "101255", "101256", "101258", "101259", "101260", "101264", "101267", "101268", "101272", "101275", "101277", "101279", "101280", "101286", "101292", "101293", "101294", "101298", "101303", "101304", "101307", "101310", "101312", "101315", "101317", "101320", "101322", "101325", "101326", "101327", "101329", "101330", "101333", "101334", "101340", "101344", "101349", "101350", "101353", "101354", "101355", "101356", "101359", "101361", "101362", "101364", "101370", "101371", "101375", "101377", "101378", "101379", "101380", "101381", "101383", "101384", "101387", "101388", "101393", "101394", "101395", "101397", "101404", "101407", "101409", "101412", "101414", "101415", "101417", "101419", "101420", "101422", "101424", "101425", "101427", "101430", "101431", "101432", "101434", "101435", "101437", "101441", "101442", "101443", "101444", "101446", "101447", "101448", "101449", "101453", "101454", "101455", "101457", "101460", "101461", "101462", "101463", "101464", "101465", "101467", "101468", "101469", "101471", "101472", "101476", "101480", "101483", "101485", "101486", "101488", "101494", "101495", "101497", "101502", "101504", "101507", "101508", "101510", "101511", "101513", "101516", "101517", "101518", "101519", "101520", "101521", "101525", "101526", "101527", "101530", "101533", "101536", "101537", "101538", "101546", "101548", "101551", "101552", "101554", "101555", "101557", "101559", "101564", "101565", "101566", "101567", "101569", "101573", "101577", "101578", "101580", "101581", "101582", "101583", "101585", "101586", "101587", "101590", "101594", "101595", "101596", "101597", "101598", "101601", "101602", "101603", "101604", "101608", "101610", "101612", "101614", "101616", "101618", "101619", "101622", "101624", "101625", "101626", "101630", "101631", "101637", "101639", "101640", "101642", "101643", "101644", "101647", "101649", "101651", "101657", "101660", "101661", "101664", "101666", "101667", "101668", "101670", "101671", "101676", "101677", "101678", "101684", "101685", "101687", "101688", "101689", "101691", "101692", "101694", "101695", "101698", "101699", "101701", "101705", "101707", "101709", "101711", "101712", "101714", "101718", "101719", "101721", "101722", "101723", "101724", "101727", "101729", "101730", "101732", "101733", "101735", "101740", "101743", "101744", "101746", "101748", "101750", "101753", "101755", "101756", "101758", "101762", "101764", "101765", "101766", "101767", "101768", "101769", "101770", "101772", "101774", "101777", "101778", "101780", "101781", "101784", "101787", "101789", "101791", "101792", "101794", "101801", "101803", "101804", "101806", "101807", "101808", "101810", "101812", "101815", "101818", "101819", "101822", "101824", "101827", "101828", "101831", "101832", "101836", "101839", "101841", "101842", "101843", "101844", "101846", "101847", "101848", "101850", "101851", "101852", "101853", "101854", "101855", "101857", "101858", "101859", "101860", "101861", "101862", "101863", "101864", "101866", "101868", "101870", "101874", "101875", "101876", "101877", "101878", "101879", "101887", "101889", "101892", "101893", "101894", "101897", "101898", "101902", "101904", "101906", "101907", "101911", "101913", "101918", "101919", "101921", "101922", "101924", "101925", "101926", "101927", "101928", "101930", "101931", "101932", "101934", "101935", "101936", "101939", "101940", "101942", "101944", "101945", "101946", "101947", "101949", "101953", "101956", "101958", "101960", "101961", "101965", "101966", "101967", "101971", "101972", "101973", "101974", "101975", "101978", "101980", "101984", "101985", "101989", "101993", "101998", "101999", "102004", "102007", "102008", "102009", "102010", "102011", "102012", "102014", "102017", "102018", "102019", "102020", "102022", "102027", "102028", "102029", "102030", "102033", "102034", "102035", "102036", "102037", "102038", "102040", "102043", "102045", "102049", "102050", "102053", "102056", "102060", "102061", "102063", "102064", "102068", "102069", "102071", "102073", "102075", "102077", "102078", "102080", "102082", "102084", "102085", "102088", "102089", "102092", "102095", "102096", "102097", "102101", "102102", "102103", "102104", "102105", "102107", "102112", "102113", "102115", "102117", "102118", "102122", "102123", "102124", "102127", "102131", "102132", "102134", "102137", "102138", "102142", "102144", "102145", "102147", "102148", "102150", "102158", "102159", "102161", "102163", "102165", "102166", "102171", "102173", "102177", "102178", "102179", "102180", "102182", "102185", "102189", "102190", "102192", "102196", "102197", "102199", "102200", "102202", "102204", "102205", "102210", "102216", "102218", "102219", "102220", "102221", "102226", "102230", "102233", "102234", "102236", "102237", "102239", "102242", "102243", "102244", "102245", "102246", "102249", "102251", "102252", "102253", "102255", "102261", "102266", "102269", "102271", "102272", "102276", "102285", "102287", "102288", "102289", "102293", "102296", "102297", "102300", "102303", "102304", "102308", "102310", "102313", "102316", "102319", "102321", "102322", "102324", "102327", "102329", "102330", "102340", "102342", "102343", "102344", "102346", "102355", "102357", "102358", "102364", "102365", "102366", "102370", "102374", "102375", "102377", "102378", "102379", "102380", "102381", "102383", "102385", "102387", "102390", "102391", "102392", "102393", "102394", "102396", "102397", "102398", "102400", "102402", "102403", "102404", "102406", "102407", "102408", "102409", "102411", "102415", "102418", "102422", "102423", "102424", "102426", "102427", "102428", "102431", "102432", "102433", "102434", "102436", "102438", "102441", "102445", "102446", "102450", "102451", "102453", "102454", "102457", "102459", "102460", "102462", "102463", "102465", "102466", "102470", "102471", "102475", "102476", "102477", "102481", "102484", "102492", "102493", "102496", "102498", "102499", "102500", "102502", "102503", "102504", "102509", "102512", "102513", "102515", "102516", "102518", "102520", "102521", "102523", "102524", "102525", "102526", "102528", "102530", "102531", "102533", "102537", "102539", "102540", "102541", "102542", "102543", "102545", "102548", "102551", "102552", "102553", "102554", "102558", "102559", "102560", "102561", "102562", "102563", "102564", "102566", "102568", "102569", "102571", "102572", "102574", "102576", "102577", "102583", "102584", "102585", "102586", "102588", "102591", "102595", "102596", "102597", "102600", "102601", "102602", "102603", "102605", "102609", "102610", "102611", "102612", "102613", "102614", "102619", "102622", "102623", "102625", "102627", "102628", "102629", "102631", "102632", "102633", "102635", "102636", "102638", "102641", "102642", "102643", "102644", "102645", "102646", "102647", "102648", "102650", "102654", "102655", "102657", "102660", "102661", "102662", "102663", "102667", "102668", "102669", "102671", "102672", "102674", "102676", "102678", "102679", "102680", "102681", "102682", "102686", "102689", "102690", "102691", "102694", "102696", "102697", "102698", "102699", "102703", "102707", "102711", "102712", "102715", "102716", "102717", "102721", "102723", "102724", "102730", "102731", "102733", "102735", "102736", "102737", "102739", "102741", "102743", "102745", "102746", "102747", "102749", "102750", "102751", "102753", "102754", "102763", "102764", "102765", "102766", "102767", "102770", "102772", "102773", "102774", "102775", "102776", "102781", "102782", "102784", "102790", "102793", "102796", "102800", "102801", "102802", "102803", "102808", "102810", "102811", "102812", "102814", "102816", "102818", "102820", "102821", "102822", "102823", "102828", "102829", "102833", "102837", "102839", "102841", "102842", "102843", "102844", "102848", "102849", "102850", "102851", "102854", "102856", "102857", "102858", "102859", "102863", "102867", "102872", "102876", "102877", "102878", "102881", "102882", "102883", "102884", "102887", "102888", "102889", "102891", "102895", "102898", "102900", "102904", "102906", "102907", "102909", "102910", "102912", "102914", "102916", "102917", "102922", "102923", "102924", "102926", "102927", "102928", "102930", "102933", "102934", "102935", "102936", "102937", "102939", "102940", "102944", "102946", "102947", "102949", "102952", "102954", "102959", "102961", "102964", "102965", "102966", "102968", "102970", "102975", "102980", "102981", "102982", "102983", "102987", "102988", "102989", "102992", "102993", "102994", "102995", "102996", "102997", "102999", "103002", "103003", "103004", "103007", "103009", "103010", "103014", "103015", "103016", "103017", "103021", "103024", "103026", "103027", "103028", "103030", "103032", "103033", "103037", "103038", "103043", "103048", "103050", "103052", "103054", "103056", "103057", "103058", "103060", "103062", "103063", "103067", "103069", "103070", "103071", "103072", "103077", "103079", "103080", "103081", "103082", "103083", "103085", "103086", "103087", "103090", "103091", "103093", "103095", "103096", "103097", "103100", "103101", "103102", "103103", "103105", "103106", "103107", "103108", "103110", "103111", "103112", "103113", "103115", "103116", "103117", "103119", "103120", "103121", "103122", "103123", "103127", "103129", "103130", "103133", "103134", "103135", "103136", "103138", "103145", "103147", "103150", "103151", "103152", "103156", "103160", "103164", "103165", "103166", "103167", "103168", "103172", "103175", "103176", "103177", "103178", "103181", "103182", "103183", "103184", "103186", "103190", "103192", "103194", "103196", "103197", "103198", "103199", "103200", "103201", "103203", "103206", "103211", "103212", "103213", "103215", "103220", "103221", "103222", "103223", "103225", "103226", "103232", "103233", "103234", "103237", "103238", "103239", "103243", "103244", "103248", "103249", "103251", "103252", "103254", "103256", "103257", "103258", "103259", "103260", "103265", "103267", "103272", "103273", "103274", "103276", "103278", "103279", "103281", "103282", "103283", "103284", "103285", "103286", "103288", "103290", "103293", "103294", "103296", "103299", "103301", "103303", "103306", "103307", "103308", "103310", "103312", "103313", "103314", "103317", "103319", "103324", "103325", "103331", "103333", "103334", "103336", "103338", "103344", "103346", "103348", "103349", "103350", "103352", "103353", "103356", "103357", "103358", "103363", "103365", "103370", "103371", "103374", "103375", "103376", "103377", "103378", "103379", "103380", "103381", "103382", "103386", "103387", "103389", "103390", "103393", "103394", "103395", "103398", "103401", "103402", "103404", "103405", "103408", "103409", "103410", "103411", "103417", "103424", "103425", "103426", "103427", "103432", "103433", "103438", "103439", "103441", "103442", "103447", "103448", "103449", "103451", "103452", "103453", "103454", "103456", "103459", "103461", "103463", "103465", "103469", "103470", "103472", "103473", "103476", "103477", "103480", "103481", "103482", "103483", "103485", "103487", "103488", "103491", "103492", "103494", "103496", "103497", "103498", "103499", "103500", "103501", "103502", "103504", "103505", "103506", "103507", "103509", "103510", "103513", "103514", "103515", "103517", "103518", "103519", "103521", "103522", "103523", "103526", "103533", "103534", "103539", "103541", "103542", "103546", "103547", "103549", "103551", "103554", "103556", "103558", "103560", "103564", "103565", "103569", "103571", "103574", "103575", "103581", "103582", "103583", "103585", "103589", "103593", "103594", "103595", "103601", "103604", "103605", "103609", "103610", "103612", "103613", "103614", "103616", "103617", "103618", "103620", "103626", "103628", "103630", "103632", "103634", "103635", "103637", "103638", "103640", "103641", "103643", "103644", "103646", "103647", "103649", "103652", "103653", "103654", "103662", "103664", "103666", "103667", "103668", "103672", "103673", "103674", "103675", "103677", "103678", "103681", "103684", "103686", "103688", "103689", "103692", "103694", "103695", "103698", "103699", "103701", "103705", "103708", "103710", "103711", "103712", "103713", "103716", "103720", "103721", "103724", "103726", "103728", "103731", "103734", "103735", "103737", "103741", "103743", "103744", "103747", "103748", "103751", "103754", "103756", "103757", "103758", "103759", "103762", "103763", "103764", "103766", "103767", "103768", "103772", "103775", "103776", "103777", "103778", "103779", "103782", "103784", "103785", "103786", "103791", "103794", "103795", "103796", "103799", "103801", "103804", "103807", "103808", "103810", "103813", "103814", "103816", "103818", "103820", "103821", "103822", "103826", "103827", "103834", "103835", "103836", "103838", "103839", "103840", "103843", "103844", "103845", "103846", "103848", "103849", "103850", "103851", "103854", "103855", "103856", "103857", "103858", "103859", "103863", "103864", "103866", "103869", "103871", "103872", "103873", "103875", "103878", "103883", "103885", "103887", "103888", "103889", "103891", "103892", "103895", "103896", "103898", "103899", "103900", "103909", "103911", "103912", "103914", "103916", "103917", "103922", "103923", "103926", "103935", "103937", "103940", "103942", "103943", "103944", "103945", "103947", "103948", "103951", "103954", "103959", "103960", "103961", "103966", "103967", "103970", "103972", "103973", "103974", "103975", "103978", "103982", "103984", "103985", "103986", "103987", "103989", "103992", "103995", "103996", "103997", "103999", "104002", "104003", "104005", "104006", "104007", "104008", "104009", "104010", "104011", "104012", "104013", "104015", "104016", "104019", "104021", "104024", "104025", "104027", "104030", "104031", "104033", "104035", "104036", "104041", "104047", "104049", "104050", "104052", "104054", "104056", "104058", "104061", "104062", "104063", "104064", "104065", "104068", "104069", "104070", "104072", "104074", "104079", "104080", "104082", "104086", "104089", "104090", "104091", "104092", "104094", "104095", "104097", "104105", "104106", "104107", "104112", "104113", "104114", "104115", "104117", "104118", "104119", "104120", "104122", "104123", "104127", "104129", "104130", "104131", "104132", "104133", "104134", "104135", "104141", "104142", "104146", "104148", "104149", "104152", "104155", "104156", "104157", "104158", "104159", "104160", "104163", "104164", "104165", "104167", "104168", "104169", "104171", "104173", "104174", "104175", "104176", "104177", "104181", "104184", "104188", "104194", "104197", "104199", "104201", "104204", "104206", "104208", "104210", "104214", "104215", "104216", "104219", "104224", "104225", "104226", "104227", "104229", "104233", "104236", "104237", "104238", "104239", "104243", "104251", "104252", "104254", "104255", "104258", "104263", "104264", "104265", "104266", "104268", "104269", "104273", "104274", "104275", "104276", "104277", "104278", "104282", "104283", "104286", "104287", "104290", "104292", "104294", "104298", "104300", "104301", "104302", "104306", "104307", "104310", "104311", "104315", "104317", "104318", "104320", "104321", "104323", "104325", "104328", "104333", "104334", "104336", "104337", "104338", "104340", "104341", "104345", "104347", "104348", "104349", "104350", "104352", "104354", "104358", "104359", "104363", "104366", "104367", "104372", "104374", "104375", "104376", "104377", "104383", "104387", "104389", "104390", "104393", "104398", "104400", "104402", "104407", "104408", "104411", "104412", "104417", "104418", "104420", "104421", "104422", "104423", "104424", "104425", "104426", "104427", "104428", "104429", "104430", "104431", "104432", "104435", "104436", "104440", "104443", "104446", "104447", "104453", "104455", "104456", "104457", "104458", "104460", "104461", "104463", "104465", "104467", "104469", "104471", "104472", "104473", "104474", "104477", "104479", "104481", "104484", "104489", "104491", "104494", "104497", "104499", "104500", "104502", "104503", "104508", "104511", "104514", "104515", "104516", "104519", "104521", "104524", "104525", "104527", "104530", "104533", "104544", "104545", "104547", "104548", "104549", "104550", "104551", "104552", "104553", "104554", "104558", "104560", "104567", "104568", "104570", "104571", "104573", "104575", "104576", "104577", "104578", "104579", "104580", "104581", "104583", "104585", "104586", "104587", "104588", "104590", "104592", "104593", "104594", "104595", "104598", "104600", "104602", "104603", "104606", "104607", "104608", "104609", "104611", "104617", "104619", "104620", "104622", "104624", "104625", "104627", "104629", "104630", "104631", "104632", "104633", "104635", "104639", "104645", "104646", "104648", "104651", "104654", "104655", "104658", "104660", "104662", "104663", "104664", "104665", "104666", "104667", "104668", "104672", "104673", "104674", "104675", "104676", "104678", "104680", "104683", "104685", "104687", "104696", "104698", "104699", "104702", "104706", "104708", "104713", "104714", "104716", "104717", "104722", "104723", "104724", "104725", "104726", "104728", "104729", "104730", "104732", "104733", "104735", "104737", "104738", "104739", "104741", "104742", "104744", "104746", "104747", "104748", "104749", "104755", "104759", "104760", "104761", "104762", "104764", "104766", "104770", "104771", "104773", "104774", "104776", "104777", "104780", "104782", "104783", "104784", "104785", "104786", "104789", "104792", "104795", "104800", "104803", "104809", "104810", "104811", "104812", "104814", "104818", "104821", "104826", "104828", "104829", "104830", "104831", "104833", "104836", "104837", "104838", "104839", "104840", "104842", "104846", "104847", "104852", "104854", "104855", "104857", "104858", "104861", "104862", "104863", "104864", "104871", "104873", "104874", "104876", "104884", "104885", "104887", "104889", "104890", "104892", "104899", "104900", "104901", "104903", "104904", "104907", "104909", "104910", "104911", "104915", "104916", "104917", "104918", "104919", "104921", "104924", "104926", "104927", "104928", "104929", "104930", "104931", "104932", "104933", "104934", "104935", "104936", "104937", "104938", "104939", "104941", "104942", "104944", "104950", "104953", "104957", "104958", "104959", "104961", "104963", "104964", "104965", "104966", "104968", "104969", "104970", "104971", "104972", "104975", "104978", "104980", "104982", "104983", "104985", "104988", "104989", "104990", "104991", "104993", "104994", "104998", "105000", "105001", "105002", "105003", "105006", "105008", "105009", "105010", "105011", "105015", "105017", "105018", "105019", "105020", "105031", "105032", "105033", "105034", "105036", "105038", "105039", "105041", "105045", "105046", "105048", "105050", "105052", "105053", "105059", "105061", "105063", "105064", "105066", "105068", "105069", "105070", "105073", "105075", "105076", "105077", "105081", "105083", "105084", "105085", "105087", "105088", "105089", "105090", "105091", "105095", "105096", "105100", "105103", "105104", "105106", "105108", "105112", "105113", "105114", "105117", "105119", "105120", "105121", "105122", "105123", "105128", "105129", "105130", "105131", "105133", "105134", "105136", "105137", "105139", "105140", "105142", "105144", "105145", "105146", "105148", "105149", "105151", "105155", "105159", "105161", "105163", "105166", "105170", "105172", "105173", "105174", "105178", "105179", "105180", "105181", "105188", "105189", "105190", "105192", "105193", "105194", "105197", "105198", "105203", "105204", "105211", "105213", "105215", "105217", "105220", "105222", "105224", "105225", "105226", "105227", "105230", "105231", "105236", "105237", "105238", "105239", "105241", "105242", "105243", "105244", "105245", "105249", "105250", "105253", "105254", "105255", "105257", "105258", "105260", "105264", "105265", "105266", "105267", "105270", "105275", "105277", "105283", "105285", "105287", "105289", "105291", "105292", "105295", "105296", "105302", "105305", "105307", "105309", "105313", "105316", "105317", "105320", "105324", "105326", "105330", "105331", "105332", "105336", "105339", "105344", "105345", "105346", "105349", "105350", "105353", "105357", "105358", "105359", "105360", "105362", "105363", "105364", "105366", "105367", "105368", "105369", "105370", "105371", "105372", "105374", "105375", "105377", "105384", "105386", "105388", "105392", "105393", "105394", "105395", "105398", "105399", "105401", "105403", "105407", "105409", "105413", "105414", "105423", "105424", "105427", "105428", "105430", "105434", "105435", "105436", "105441", "105442", "105444", "105446", "105448", "105449", "105450", "105452", "105453", "105454", "105456", "105458", "105460", "105462", "105463", "105464", "105465", "105467", "105468", "105469", "105470", "105475", "105478", "105480", "105484", "105485", "105488", "105490", "105491", "105492", "105498", "105507", "105510", "105512", "105513", "105515", "105518", "105519", "105521", "105522", "105523", "105524", "105527", "105531", "105533", "105534", "105536", "105537", "105539", "105541", "105543", "105545", "105548", "105551", "105556", "105557", "105559", "105561", "105562", "105563", "105565", "105566", "105567", "105568", "105569", "105571", "105575", "105576", "105579", "105583", "105585", "105588", "105590", "105591", "105592", "105593", "105598", "105601", "105603", "105605", "105606", "105607", "105609", "105611", "105613", "105616", "105617", "105618", "105625", "105627", "105631", "105634", "105635", "105636", "105637", "105638", "105639", "105643", "105644", "105645", "105646", "105649", "105651", "105652", "105653", "105654", "105659", "105661", "105663", "105666", "105668", "105673", "105674", "105677", "105679", "105681", "105685", "105686", "105687", "105691", "105692", "105694", "105695", "105696", "105698", "105699", "105700", "105704", "105708", "105710", "105711", "105712", "105716", "105719", "105721", "105724", "105725", "105726", "105728", "105730", "105731", "105732", "105733", "105734", "105735", "105736", "105740", "105742", "105744", "105745", "105746", "105747", "105748", "105751", "105753", "105754", "105757", "105759", "105761", "105762", "105763", "105764", "105766", "105768", "105769", "105770", "105771", "105772", "105777", "105779", "105781", "105782", "105784", "105788", "105790", "105791", "105792", "105795", "105797", "105803", "105806", "105809", "105810", "105811", "105812", "105816", "105817", "105818", "105819", "105820", "105821", "105823", "105828", "105829", "105830", "105831", "105833", "105837", "105839", "105840", "105841", "105842", "105843", "105844", "105847", "105848", "105852", "105853", "105857", "105858", "105859", "105862", "105865", "105866", "105867", "105868", "105870", "105875", "105879", "105881", "105882", "105885", "105887", "105889", "105890", "105891", "105893", "105894", "105896", "105899", "105901", "105902", "105903", "105905", "105906", "105908", "105909", "105910", "105915", "105917", "105919", "105923", "105924", "105926", "105928", "105931", "105939", "105940", "105941", "105943", "105944", "105945", "105946", "105949", "105951", "105957", "105958", "105959", "105960", "105962", "105963", "105964", "105965", "105966", "105969", "105970", "105972", "105974", "105975", "105978", "105979", "105980", "105981", "105982", "105983", "105986", "105987", "105992", "105996", "106001", "106002", "106003", "106005", "106006", "106007", "106008", "106009", "106010", "106011", "106013", "106016", "106017", "106018", "106020", "106021", "106022", "106023", "106025", "106027", "106030", "106032", "106033", "106039", "106041", "106043", "106044", "106045", "106046", "106048", "106051", "106052", "106054", "106055", "106056", "106057", "106058", "106062", "106063", "106064", "106065", "106066", "106067", "106069", "106072", "106073", "106075", "106076", "106077", "106078", "106080", "106083", "106085", "106086", "106087", "106089", "106090", "106092", "106095", "106096", "106097", "106099", "106101", "106102", "106103", "106107", "106113", "106114", "106116", "106117", "106119", "106122", "106123", "106124", "106125", "106129", "106130", "106134", "106135", "106137", "106138", "106139", "106142", "106144", "106146", "106152", "106154", "106155", "106157", "106161", "106163", "106164", "106165", "106166", "106167", "106168", "106170", "106171", "106173", "106176", "106178", "106179", "106181", "106182", "106184", "106187", "106192", "106193", "106194", "106196", "106201", "106202", "106203", "106204", "106208", "106209", "106210", "106212", "106213", "106217", "106223", "106225", "106227", "106230", "106232", "106233", "106234", "106235", "106236", "106241", "106242", "106245", "106247", "106249", "106250", "106254", "106255", "106256", "106257", "106258", "106260", "106262", "106264", "106265", "106267", "106270", "106272", "106274", "106277", "106279", "106280", "106283", "106284", "106285", "106286", "106288", "106290", "106291", "106292", "106293", "106294", "106296", "106298", "106302", "106303", "106307", "106308", "106313", "106315", "106317", "106319", "106321", "106323", "106324", "106325", "106333", "106334", "106335", "106336", "106337", "106339", "106340", "106344", "106348", "106351", "106353", "106354", "106356", "106359", "106360", "106362", "106364", "106365", "106367", "106368", "106370", "106372", "106373", "106374", "106377", "106378", "106381", "106384", "106390", "106391", "106392", "106393", "106397", "106398", "106400", "106403", "106404", "106406", "106408", "106411", "106413", "106414", "106417", "106420", "106422", "106423", "106424", "106427", "106431", "106432", "106436", "106437", "106439", "106440", "106441", "106444", "106445", "106447", "106449", "106451", "106453", "106455", "106461", "106462", "106464", "106465", "106468", "106474", "106475", "106483", "106488", "106490", "106493", "106494", "106496", "106501", "106502", "106503", "106504", "106506", "106508", "106509", "106510", "106511", "106513", "106514", "106515", "106521", "106523", "106524", "106526", "106527", "106532", "106534", "106535", "106537", "106541", "106542", "106543", "106544", "106545", "106547", "106548", "106552", "106555", "106562", "106563", "106564", "106566", "106569", "106573", "106575", "106578", "106580", "106581", "106586", "106587", "106588", "106592", "106594", "106596", "106597", "106598", "106602", "106604", "106605", "106606", "106607", "106610", "106611", "106612", "106613", "106614", "106615", "106616", "106617", "106618", "106619", "106621", "106622", "106624", "106626", "106628", "106631", "106632", "106633", "106634", "106635", "106636", "106640", "106641", "106645", "106647", "106648", "106649", "106650", "106651", "106652", "106653", "106654", "106656", "106657", "106659", "106663", "106669", "106671", "106674", "106675", "106682", "106683", "106685", "106686", "106687", "106688", "106690", "106693", "106694", "106695", "106696", "106704", "106705", "106706", "106708", "106710", "106711", "106713", "106714", "106716", "106717", "106722", "106725", "106726", "106727", "106729", "106731", "106732", "106734", "106736", "106740", "106741", "106749", "106753", "106755", "106756", "106757", "106758", "106760", "106761", "106762", "106763", "106764", "106765", "106766", "106768", "106769", "106773", "106776", "106777", "106779", "106782", "106783", "106784", "106785", "106787", "106788", "106793", "106795", "106797", "106799", "106801", "106803", "106804", "106806", "106807", "106808", "106810", "106812", "106813", "106814", "106815", "106819", "106820", "106822", "106824", "106825", "106826", "106828", "106829", "106831", "106832", "106834", "106836", "106838", "106840", "106844", "106846", "106848", "106850", "106854", "106857", "106859", "106860", "106865", "106868", "106872", "106874", "106877", "106879", "106880", "106881", "106882", "106887", "106888", "106889", "106890", "106891", "106892", "106893", "106896", "106901", "106903", "106905", "106907", "106911", "106912", "106914", "106915", "106916", "106917", "106920", "106921", "106922", "106925", "106927", "106929", "106934", "106937", "106938", "106944", "106946", "106948", "106951", "106953", "106954", "106955", "106956", "106957", "106959", "106960", "106963", "106965", "106967", "106969", "106971", "106972", "106976", "106978", "106979", "106982", "106984", "106986", "106987", "106990", "106991", "106993", "106995", "106996", "106997", "107000", "107002", "107009", "107010", "107011", "107013", "107014", "107015", "107019", "107021", "107023", "107024", "107025", "107027", "107029", "107031", "107033", "107034", "107037", "107042", "107043", "107044", "107045", "107046", "107050", "107051", "107052", "107054", "107055", "107056", "107057", "107058", "107059", "107060", "107061", "107062", "107063", "107064", "107065", "107070", "107072", "107073", "107074", "107076", "107079", "107081", "107082", "107083", "107084", "107087", "107090", "107091", "107092", "107093", "107096", "107097", "107098", "107100", "107102", "107103", "107106", "107107", "107109", "107110", "107111", "107112", "107116", "107117", "107119", "107120", "107123", "107124", "107125", "107131", "107134", "107135", "107137", "107138", "107142", "107143", "107145", "107149", "107151", "107152", "107153", "107160", "107162", "107163", "107164", "107166", "107167", "107170", "107172", "107173", "107174", "107175", "107176", "107177", "107179", "107181", "107182", "107184", "107187", "107188", "107189", "107190", "107191", "107192", "107194", "107196", "107198", "107200", "107201", "107206", "107209", "107210", "107212", "107213", "107217", "107218", "107220", "107221", "107229", "107230", "107235", "107237", "107238", "107239", "107243", "107244", "107246", "107247", "107250", "107254", "107256", "107257", "107258", "107261", "107262", "107264", "107265", "107266", "107270", "107271", "107275", "107277", "107279", "107280", "107282", "107284", "107288", "107290", "107292", "107294", "107295", "107296", "107299", "107301", "107305", "107306", "107314", "107322", "107324", "107325", "107327", "107328", "107333", "107334", "107335", "107336", "107337", "107339", "107340", "107341", "107347", "107348", "107350", "107351", "107352", "107355", "107356", "107357", "107359", "107364", "107367", "107368", "107369", "107370", "107371", "107374", "107378", "107379", "107381", "107382", "107384", "107389", "107391", "107392", "107393", "107394", "107397", "107398", "107400", "107402", "107403", "107406", "107407", "107408", "107410", "107411", "107413", "107414", "107415", "107417", "107418", "107426", "107427", "107429", "107430", "107432", "107434", "107439", "107443", "107449", "107450", "107454", "107462", "107465", "107466", "107469", "107470", "107474", "107485", "107487", "107492", "107494", "107496", "107499", "107506", "107509", "107514", "107515", "107517", "107519", "107521", "107522", "107523", "107526", "107527", "107528", "107529", "107530", "107532", "107534", "107535", "107537", "107543", "107545", "107547", "107549", "107550", "107554", "107555", "107556", "107557", "107560", "107570", "107572", "107576", "107580", "107581", "107584", "107588", "107589", "107590", "107591", "107592", "107594", "107598", "107601", "107602", "107606", "107609", "107612", "107616", "107617", "107619", "107625", "107626", "107630", "107631", "107632", "107633", "107634", "107639", "107642", "107643", "107645", "107648", "107650", "107651", "107653", "107654", "107657", "107658", "107660", "107662", "107663", "107667", "107668", "107669", "107670", "107673", "107674", "107677", "107682", "107683", "107686", "107687", "107688", "107689", "107691", "107692", "107693", "107694", "107697", "107699", "107700", "107701", "107702", "107703", "107706", "107707", "107708", "107716", "107718", "107720", "107722", "107723", "107725", "107728", "107729", "107732", "107733", "107738", "107739", "107740", "107741", "107743", "107744", "107747", "107748", "107749", "107751", "107752", "107753", "107756", "107757", "107762", "107763", "107764", "107766", "107768", "107769", "107772", "107777", "107780", "107781", "107782", "107783", "107784", "107785", "107786", "107789", "107790", "107792", "107794", "107795", "107800", "107801", "107802", "107803", "107804", "107808", "107810", "107814", "107815", "107819", "107822", "107823", "107824", "107825", "107828", "107830", "107839", "107840", "107841", "107842", "107845", "107849", "107850", "107851", "107856", "107858", "107860", "107864", "107870", "107871", "107873", "107874", "107878", "107879", "107880", "107881", "107884", "107887", "107893", "107896", "107897", "107898", "107901", "107903", "107904", "107906", "107911", "107912", "107914", "107918", "107920", "107921", "107923", "107924", "107925", "107930", "107932", "107933", "107935", "107938", "107939", "107943", "107945", "107946", "107947", "107948", "107949", "107950", "107953", "107954", "107958", "107959", "107960", "107961", "107963", "107966", "107967", "107968", "107969", "107970", "107971", "107973", "107974", "107976", "107983", "107990", "107991", "107993", "107994", "107995", "107999", "108000", "108001", "108002", "108006", "108009", "108010", "108011", "108012", "108013", "108016", "108020", "108021", "108022", "108023", "108025", "108028", "108029", "108032", "108033", "108037", "108039", "108040", "108041", "108043", "108044", "108046", "108048", "108050", "108056", "108058", "108062", "108064", "108066", "108067", "108068", "108070", "108071", "108072", "108073", "108075", "108080", "108084", "108086", "108088", "108089", "108090", "108092", "108093", "108094", "108096", "108097", "108098", "108101", "108103", "108104", "108106", "108109", "108110", "108113", "108115", "108117", "108122", "108124", "108125", "108126", "108128", "108129", "108131", "108132", "108134", "108136", "108137", "108138", "108144", "108145", "108147", "108148", "108150", "108155", "108157", "108158", "108159", "108160", "108161", "108162", "108163", "108164", "108168", "108170", "108174", "108178", "108179", "108181", "108182", "108183", "108187", "108188", "108189", "108190", "108191", "108195", "108199", "108203", "108204", "108210", "108211", "108216", "108221", "108222", "108223", "108224", "108225", "108226", "108227", "108229", "108230", "108234", "108235", "108236", "108239", "108242", "108244", "108247", "108248", "108252", "108255", "108256", "108257", "108259", "108261", "108262", "108266", "108267", "108269", "108272", "108274", "108275", "108276", "108278", "108280", "108281", "108282", "108284", "108286", "108288", "108289", "108290", "108292", "108293", "108295", "108300", "108303", "108304", "108309", "108310", "108311", "108312", "108314", "108316", "108318", "108320", "108325", "108326", "108329", "108330", "108332", "108333", "108337", "108338", "108340", "108344", "108346", "108347", "108348", "108349", "108360", "108363", "108366", "108368", "108370", "108372", "108374", "108377", "108378", "108380", "108381", "108383", "108385", "108387", "108389", "108390", "108391", "108392", "108393", "108394", "108396", "108399", "108402", "108403", "108408", "108409", "108411", "108412", "108413", "108417", "108420", "108427", "108429", "108431", "108432", "108433", "108434", "108435", "108437", "108438", "108439", "108440", "108445", "108446", "108447", "108449", "108450", "108452", "108453", "108455", "108456", "108459", "108460", "108461", "108462", "108467", "108468", "108469", "108471", "108472", "108474", "108475", "108479", "108480", "108482", "108484", "108488", "108489", "108490", "108491", "108492", "108495", "108496", "108498", "108499", "108502", "108505", "108507", "108508", "108509", "108514", "108515", "108519", "108521", "108522", "108523", "108524", "108529", "108531", "108532", "108533", "108540", "108542", "108544", "108545", "108546", "108548", "108552", "108555", "108562", "108563", "108564", "108566", "108567", "108568", "108570", "108571", "108572", "108575", "108576", "108578", "108579", "108580", "108581", "108582", "108584", "108594", "108595", "108596", "108600", "108604", "108605", "108606", "108609", "108615", "108616", "108619", "108622", "108628", "108630", "108633", "108638", "108639", "108643", "108645", "108648", "108654", "108655", "108656", "108659", "108660", "108661", "108663", "108664", "108665", "108667", "108668", "108671", "108672", "108674", "108677", "108682", "108685", "108688", "108690", "108697", "108698", "108699", "108701", "108703", "108704", "108706", "108707", "108709", "108713", "108715", "108716", "108717", "108718", "108719", "108723", "108726", "108727", "108728", "108730", "108731", "108732", "108733", "108735", "108736", "108737", "108738", "108739", "108742", "108744", "108745", "108746", "108747", "108748", "108752", "108753", "108755", "108756", "108757", "108758", "108760", "108761", "108762", "108763", "108765", "108772", "108773", "108775", "108781", "108782", "108786", "108787", "108788", "108789", "108790", "108792", "108795", "108799", "108801", "108802", "108804", "108805", "108810", "108812", "108815", "108822", "108823", "108824", "108825", "108826", "108827", "108829", "108830", "108832", "108835", "108836", "108837", "108841", "108842", "108843", "108844", "108846", "108848", "108849", "108852", "108853", "108854", "108855", "108859", "108860", "108861", "108863", "108865", "108866", "108867", "108871", "108872", "108873", "108875", "108877", "108879", "108881", "108882", "108884", "108885", "108886", "108888", "108892", "108893", "108895", "108897", "108898", "108899", "108900", "108901", "108904", "108905", "108906", "108907", "108909", "108910", "108913", "108916", "108920", "108922", "108923", "108924", "108925", "108926", "108928", "108930", "108931", "108935", "108940", "108941", "108944", "108949", "108951", "108952", "108953", "108954", "108955", "108956", "108957", "108958", "108961", "108962", "108965", "108966", "108967", "108968", "108969", "108970", "108975", "108976", "108979", "108981", "108983", "108984", "108988", "108989", "108990", "108991", "108992", "108995", "108996", "108999", "109000", "109002", "109005", "109008", "109009", "109011", "109012", "109015", "109016", "109018", "109022", "109023", "109028", "109029", "109032", "109033", "109034", "109036", "109038", "109039", "109042", "109044", "109045", "109046", "109047", "109050", "109052", "109053", "109054", "109056", "109057", "109058", "109061", "109063", "109064", "109065", "109066", "109072", "109073", "109075", "109079", "109080", "109083", "109084", "109088", "109089", "109090", "109095", "109099", "109100", "109101", "109104", "109105", "109106", "109107", "109109", "109112", "109113", "109115", "109118", "109120", "109121", "109124", "109127", "109129", "109130", "109133", "109134", "109136", "109139", "109142", "109143", "109144", "109145", "109149", "109150", "109158", "109160", "109163", "109164", "109165", "109166", "109168", "109170", "109172", "109174", "109175", "109176", "109180", "109188", "109189", "109191", "109194", "109196", "109197", "109201", "109202", "109204", "109205", "109206", "109208", "109210", "109212", "109213", "109214", "109216", "109218", "109219", "109222", "109224", "109226", "109229", "109232", "109234", "109237", "109242", "109244", "109245", "109246", "109247", "109248", "109250", "109251", "109252", "109254", "109255", "109256", "109257", "109260", "109264", "109265", "109266", "109268", "109269", "109271", "109273", "109276", "109277", "109278", "109280", "109285", "109286", "109288", "109289", "109292", "109297", "109299", "109300", "109304", "109305", "109306", "109311", "109313", "109314", "109318", "109319", "109322", "109323", "109324", "109325", "109326", "109328", "109331", "109332", "109334", "109336", "109338", "109340", "109342", "109345", "109346", "109350", "109352", "109355", "109357", "109359", "109364", "109365", "109367", "109370", "109372", "109376", "109379", "109380", "109384", "109385", "109386", "109390", "109392", "109393", "109395", "109398", "109399", "109400", "109401", "109402", "109403", "109407", "109409", "109413", "109414", "109415", "109416", "109419", "109420", "109422", "109424", "109425", "109428", "109431", "109432", "109433", "109434", "109435", "109436", "109439", "109441", "109443", "109445", "109449", "109450", "109451", "109453", "109454", "109455", "109456", "109458", "109460", "109464", "109466", "109468", "109469", "109470", "109472", "109473", "109478", "109479", "109481", "109482", "109483", "109484", "109485", "109487", "109488", "109489", "109492", "109493", "109497", "109505", "109507", "109508", "109509", "109515", "109518", "109520", "109522", "109523", "109525", "109527", "109528", "109532", "109534", "109535", "109537", "109538", "109540", "109542", "109543", "109544", "109546", "109547", "109550", "109551", "109552", "109554", "109555", "109557", "109558", "109559", "109561", "109562", "109563", "109565", "109566", "109568", "109574", "109580", "109581", "109585", "109587", "109590", "109591", "109596", "109597", "109598", "109599", "109601", "109604", "109605", "109606", "109607", "109608", "109611", "109612", "109613", "109614", "109617", "109619", "109623", "109625", "109626", "109627", "109628", "109629", "109631", "109635", "109636", "109642", "109645", "109646", "109647", "109648", "109649", "109651", "109652", "109653", "109654", "109656", "109659", "109660", "109661", "109663", "109666", "109667", "109668", "109669", "109670", "109671", "109673", "109674", "109676", "109682", "109690", "109692", "109695", "109696", "109697", "109699", "109700", "109706", "109707", "109708", "109711", "109713", "109714", "109716", "109717", "109718", "109719", "109720", "109721", "109723", "109726", "109728", "109731", "109741", "109742", "109744", "109746", "109749", "109750", "109754", "109756", "109757", "109758", "109764", "109769", "109770", "109772", "109773", "109775", "109781", "109782", "109785", "109787", "109788", "109789", "109790", "109791", "109792", "109793", "109794", "109796", "109797", "109798", "109800", "109801", "109802", "109803", "109806", "109807", "109811", "109812", "109815", "109816", "109819", "109821", "109823", "109824", "109826", "109830", "109835", "109842", "109848", "109851", "109853", "109854", "109858", "109860", "109861", "109864", "109868", "109871", "109873", "109874", "109875", "109877", "109878", "109880", "109882", "109891", "109893", "109894", "109896", "109898", "109900", "109901", "109902", "109903", "109906", "109907", "109908", "109909", "109911", "109912", "109920", "109922", "109924", "109926", "109933", "109934", "109935", "109938", "109942", "109943", "109945", "109946", "109947", "109948", "109950", "109951", "109953", "109956", "109957", "109959", "109964", "109965", "109968", "109969", "109975", "109977", "109979", "109983", "109984", "109985", "109987", "109988", "109989", "109990", "109991", "109992", "109993", "109994", "109995", "110001", "110004", "110006", "110008", "110010", "110014", "110015", "110018", "110019", "110021", "110022", "110024", "110026", "110029", "110030", "110031", "110032", "110036", "110037", "110038", "110041", "110042", "110043", "110044", "110045", "110047", "110053", "110054", "110055", "110058", "110062", "110065", "110066", "110068", "110069", "110071", "110072", "110073", "110075", "110076", "110077", "110079", "110081", "110082", "110083", "110085", "110087", "110088", "110089", "110092", "110093", "110095", "110099", "110104", "110106", "110108", "110109", "110112", "110113", "110114", "110115", "110116", "110117", "110118", "110122", "110128", "110134", "110137", "110138", "110139", "110140", "110142", "110144", "110146", "110147", "110149", "110150", "110153", "110154", "110155", "110157", "110159", "110160", "110162", "110163", "110165", "110166", "110169", "110170", "110171", "110173", "110174", "110176", "110178", "110179", "110180", "110181", "110182", "110183", "110185", "110186", "110187", "110190", "110191", "110192", "110194", "110197", "110199", "110201", "110203", "110204", "110205", "110208", "110210", "110212", "110215", "110216", "110219", "110227", "110228", "110229", "110230", "110232", "110233", "110234", "110235", "110237", "110238", "110242", "110243", "110244", "110246", "110249", "110250", "110252", "110253", "110254", "110257", "110258", "110260", "110262", "110263", "110264", "110266", "110267", "110268", "110269", "110271", "110272", "110278", "110279", "110280", "110283", "110285", "110286", "110288", "110289", "110291", "110292", "110295", "110297", "110298", "110299", "110302", "110303", "110304", "110306", "110307", "110308", "110311", "110312", "110313", "110314", "110318", "110320", "110321", "110323", "110324", "110325", "110326", "110328", "110329", "110331", "110334", "110342", "110345", "110347", "110349", "110351", "110352", "110356", "110358", "110359", "110360", "110361", "110363", "110365", "110366", "110371", "110372", "110374", "110379", "110380", "110381", "110387", "110388", "110389", "110390", "110391", "110392", "110393", "110394", "110395", "110397", "110398", "110401", "110402", "110404", "110405", "110406", "110411", "110412", "110414", "110418", "110421", "110422", "110423", "110431", "110433", "110436", "110437", "110438", "110440", "110444", "110451", "110454", "110456", "110458", "110459", "110460", "110462", "110463", "110465", "110466", "110467", "110468", "110471", "110473", "110474", "110475", "110477", "110478", "110479", "110480", "110484", "110486", "110487", "110488", "110489", "110491", "110492", "110495", "110502", "110507", "110509", "110510", "110512", "110514", "110515", "110517", "110518", "110521", "110523", "110524", "110529", "110530", "110531", "110540", "110543", "110544", "110545", "110549", "110550", "110555", "110556", "110558", "110559", "110560", "110562", "110563", "110566", "110567", "110570", "110574", "110575", "110576", "110579", "110580", "110583", "110584", "110586", "110587", "110590", "110591", "110594", "110596", "110597", "110600", "110602", "110603", "110604", "110606", "110609", "110612", "110614", "110615", "110616", "110617", "110618", "110620", "110621", "110624", "110625", "110626", "110627", "110632", "110636", "110637", "110638", "110639", "110640", "110643", "110646", "110648", "110649", "110650", "110652", "110655", "110657", "110658", "110663", "110665", "110666", "110669", "110671", "110679", "110682", "110685", "110686", "110688", "110689", "110690", "110691", "110695", "110696", "110700", "110701", "110709", "110710", "110712", "110713", "110715", "110716", "110717", "110719", "110720", "110722", "110724", "110727", "110729", "110732", "110733", "110736", "110737", "110738", "110744", "110745", "110749", "110750", "110751", "110753", "110754", "110756", "110757", "110758", "110759", "110761", "110764", "110765", "110767", "110770", "110772", "110773", "110774", "110779", "110783", "110784", "110787", "110791", "110792", "110793", "110796", "110797", "110798", "110800", "110801", "110802", "110803", "110809", "110810", "110815", "110817", "110819", "110824", "110826", "110827", "110831", "110832", "110834", "110835", "110836", "110837", "110838", "110843", "110846", "110851", "110853", "110855", "110861", "110864", "110865", "110866", "110867", "110868", "110871", "110874", "110876", "110879", "110881", "110884", "110885", "110886", "110888", "110890", "110891", "110892", "110893", "110896", "110897", "110900", "110901", "110905", "110906", "110907", "110908", "110909", "110910", "110912", "110914", "110916", "110917", "110919", "110920", "110921", "110922", "110924", "110925", "110926", "110928", "110929", "110932", "110935", "110936", "110937", "110941", "110942", "110949", "110951", "110952", "110955", "110957", "110960", "110961", "110966", "110967", "110969", "110971", "110973", "110975", "110976", "110977", "110981", "110982", "110983", "110986", "110987", "110988", "110989", "110991", "110992", "110994", "110996", "111005", "111006", "111009", "111011", "111012", "111014", "111015", "111018", "111021", "111023", "111024", "111026", "111028", "111030", "111031", "111032", "111034", "111035", "111037", "111039", "111040", "111043", "111047", "111050", "111051", "111052", "111053", "111054", "111056", "111057", "111059", "111060", "111061", "111064", "111065", "111068", "111071", "111074", "111076", "111077", "111078", "111080", "111082", "111083", "111085", "111087", "111089", "111090", "111092", "111095", "111102", "111103", "111106", "111108", "111109", "111110", "111117", "111118", "111119", "111123", "111124", "111125", "111129", "111131", "111132", "111133", "111135", "111136", "111137", "111140", "111144", "111145", "111147", "111148", "111151", "111152", "111153", "111155", "111156", "111159", "111161", "111163", "111165", "111166", "111169", "111170", "111171", "111174", "111177", "111178", "111180", "111181", "111182", "111184", "111185", "111186", "111191", "111192", "111193", "111195", "111196", "111197", "111199", "111200", "111202", "111204", "111205", "111206", "111209", "111211", "111212", "111217", "111220", "111221", "111223", "111224", "111226", "111227", "111229", "111230", "111235", "111237", "111238", "111242", "111243", "111245", "111248", "111250", "111253", "111254", "111258", "111259", "111260", "111261", "111263", "111265", "111266", "111271", "111277", "111279", "111281", "111282", "111283", "111285", "111287", "111291", "111292", "111293", "111294", "111299", "111302", "111305", "111306", "111307", "111308", "111309", "111310", "111318", "111319", "111321", "111325", "111326", "111331", "111332", "111333", "111336", "111337", "111339", "111340", "111341", "111344", "111345", "111351", "111352", "111354", "111363", "111364", "111367", "111371", "111381", "111384", "111385", "111388", "111391", "111394", "111395", "111397", "111398", "111399", "111401", "111402", "111403", "111404", "111409", "111412", "111413", "111416", "111417", "111421", "111422", "111423", "111425", "111430", "111431", "111432", "111433", "111434", "111435", "111437", "111439", "111441", "111443", "111444", "111445", "111450", "111457", "111459", "111460", "111461", "111463", "111464", "111465", "111467", "111469", "111472", "111473", "111478", "111479", "111485", "111486", "111487", "111488", "111489", "111490", "111491", "111492", "111496", "111497", "111498", "111501", "111503", "111504", "111506", "111509", "111518", "111521", "111522", "111527", "111528", "111529", "111530", "111536", "111537", "111538", "111540", "111545", "111547", "111548", "111550", "111553", "111559", "111560", "111563", "111565", "111570", "111572", "111574", "111575", "111576", "111577", "111580", "111583", "111586", "111590", "111591", "111592", "111593", "111594", "111596", "111600", "111605", "111606", "111607", "111610", "111611", "111614", "111620", "111624", "111625", "111626", "111631", "111632", "111633", "111636", "111638", "111639", "111643", "111644", "111645", "111646", "111647", "111654", "111655", "111656", "111659", "111660", "111661", "111662", "111665", "111668", "111671", "111672", "111674", "111678", "111679", "111681", "111684", "111685", "111687", "111691", "111694", "111695", "111697", "111699", "111703", "111704", "111705", "111706", "111707", "111711", "111713", "111714", "111715", "111716", "111718", "111719", "111720", "111721", "111722", "111725", "111726", "111727", "111729", "111730", "111731", "111732", "111739", "111740", "111743", "111746", "111747", "111748", "111749", "111750", "111751", "111753", "111754", "111755", "111761", "111764", "111765", "111766", "111768", "111771", "111773", "111775", "111782", "111783", "111785", "111789", "111790", "111791", "111793", "111794", "111795", "111796", "111798", "111799", "111800", "111802", "111806", "111807", "111808", "111809", "111810", "111811", "111812", "111813", "111814", "111816", "111817", "111822", "111827", "111832", "111833", "111834", "111835", "111836", "111837", "111839", "111841", "111843", "111849", "111851", "111852", "111857", "111858", "111861", "111863", "111864", "111865", "111870", "111871", "111872", "111873", "111874", "111878", "111879", "111884", "111888", "111890", "111891", "111893", "111894", "111896", "111898", "111899", "111900", "111901", "111903", "111904", "111906", "111907", "111909", "111915", "111916", "111917", "111919", "111920", "111921", "111922", "111925", "111926", "111927", "111931", "111932", "111933", "111934", "111935", "111936", "111937", "111938", "111941", "111943", "111946", "111949", "111952", "111953", "111954", "111955", "111956", "111957", "111958", "111959", "111960", "111964", "111970", "111971", "111972", "111973", "111974", "111975", "111976", "111978", "111980", "111981", "111983", "111984", "111986", "111989", "111991", "111994", "111996", "111997", "111999", "112002", "112003", "112005", "112008", "112010", "112012", "112013", "112014", "112017", "112021", "112022", "112025", "112028", "112029", "112030", "112031", "112032", "112033", "112034", "112035", "112038", "112039", "112040", "112041", "112042", "112043", "112044", "112047", "112048", "112049", "112050", "112051", "112054", "112055", "112058", "112059", "112061", "112062", "112063", "112064", "112065", "112068", "112070", "112074", "112077", "112079", "112081", "112086", "112089", "112090", "112091", "112094", "112095", "112097", "112101", "112103", "112105", "112107", "112108", "112111", "112112", "112116", "112117", "112118", "112119", "112120", "112122", "112124", "112127", "112129", "112130", "112131", "112134", "112136", "112137", "112140", "112142", "112144", "112145", "112146", "112147", "112149", "112151", "112156", "112157", "112158", "112161", "112168", "112171", "112176", "112181", "112183", "112184", "112185", "112186", "112190", "112191", "112193", "112194", "112196", "112198", "112203", "112209", "112210", "112211", "112212", "112214", "112215", "112219", "112220", "112221", "112223", "112224", "112226", "112229", "112230", "112232", "112235", "112236", "112239", "112240", "112242", "112247", "112249", "112250", "112253", "112255", "112259", "112264", "112265", "112266", "112267", "112268", "112270", "112275", "112277", "112279", "112282", "112284", "112285", "112286", "112287", "112288", "112289", "112290", "112291", "112293", "112294", "112295", "112296", "112298", "112301", "112302", "112303", "112305", "112306", "112307", "112308", "112309", "112311", "112313", "112314", "112315", "112317", "112319", "112322", "112324", "112325", "112326", "112328", "112333", "112334", "112336", "112337", "112338", "112341", "112344", "112347", "112348", "112349", "112350", "112351", "112353", "112356", "112359", "112362", "112367", "112368", "112370", "112371", "112372", "112373", "112374", "112375", "112377", "112379", "112382", "112383", "112384", "112387", "112391", "112395", "112399", "112400", "112404", "112407", "112408", "112411", "112413", "112415", "112417", "112418", "112420", "112421", "112422", "112423", "112424", "112425", "112426", "112428", "112440", "112441", "112446", "112447", "112448", "112451", "112452", "112453", "112455", "112456", "112458", "112459", "112464", "112466", "112467", "112470", "112471", "112472", "112473", "112475", "112476", "112477", "112478", "112479", "112480", "112481", "112482", "112483", "112484", "112485", "112486", "112487", "112488", "112493", "112495", "112496", "112498", "112502", "112505", "112506", "112510", "112512", "112514", "112516", "112517", "112519", "112521", "112522", "112525", "112526", "112527", "112530", "112536", "112540", "112542", "112543", "112545", "112547", "112548", "112549", "112550", "112552", "112556", "112558", "112559", "112561", "112565", "112569", "112570", "112571", "112572", "112573", "112576", "112578", "112580", "112581", "112584", "112589", "112596", "112599", "112602", "112603", "112607", "112609", "112610", "112611", "112612", "112613", "112618", "112619", "112621", "112626", "112627", "112628", "112631", "112635", "112637", "112638", "112639", "112641", "112643", "112644", "112646", "112648", "112653", "112654", "112656", "112657", "112660", "112661", "112663", "112664", "112665", "112667", "112669", "112670", "112671", "112672", "112673", "112674", "112676", "112677", "112678", "112679", "112681", "112682", "112685", "112686", "112689", "112691", "112693", "112694", "112696", "112698", "112699", "112700", "112702", "112704", "112706", "112709", "112710", "112714", "112716", "112718", "112719", "112720", "112721", "112722", "112723", "112724", "112725", "112726", "112727", "112728", "112729", "112730", "112731", "112735", "112736", "112738", "112739", "112740", "112742", "112744", "112747", "112749", "112750", "112751", "112752", "112753", "112754", "112756", "112757", "112758", "112760", "112762", "112763", "112764", "112765", "112767", "112769", "112775", "112776", "112777", "112779", "112780", "112781", "112783", "112784", "112786", "112787", "112789", "112790", "112792", "112793", "112795", "112797", "112801", "112802", "112803", "112804", "112805", "112807", "112808", "112814", "112815", "112816", "112817", "112818", "112822", "112823", "112824", "112826", "112828", "112830", "112831", "112836", "112837", "112839", "112840", "112843", "112848", "112849", "112852", "112856", "112861", "112862", "112865", "112867", "112871", "112873", "112874", "112875", "112876", "112877", "112878", "112879", "112881", "112883", "112884", "112887", "112891", "112892", "112894", "112896", "112897", "112898", "112903", "112906", "112907", "112908", "112909", "112913", "112915", "112916", "112918", "112920", "112921", "112925", "112927", "112928", "112932", "112933", "112934", "112936", "112939", "112940", "112941", "112943", "112945", "112946", "112947", "112948", "112950", "112953", "112954", "112955", "112957", "112958", "112960", "112963", "112965", "112967", "112972", "112973", "112976", "112979", "112980", "112983", "112986", "112989", "112990", "112996", "112997", "112998", "112999", "113001", "113002", "113003", "113006", "113007", "113008", "113011", "113012", "113016", "113017", "113018", "113021", "113022", "113030", "113032", "113036", "113037", "113041", "113045", "113047", "113049", "113050", "113051", "113055", "113056", "113057", "113065", "113066", "113067", "113069", "113073", "113074", "113075", "113076", "113077", "113078", "113080", "113082", "113084", "113085", "113086", "113087", "113089", "113090", "113091", "113095", "113096", "113097", "113099", "113100", "113101", "113102", "113106", "113107", "113109", "113110", "113111", "113112", "113114", "113115", "113116", "113117", "113121", "113123", "113124", "113126", "113129", "113132", "113139", "113140", "113141", "113143", "113144", "113145", "113146", "113152", "113154", "113155", "113160", "113161", "113162", "113163", "113164", "113166", "113168", "113169", "113170", "113171", "113173", "113179", "113180", "113181", "113183", "113184", "113185", "113190", "113191", "113192", "113193", "113196", "113197", "113199", "113206", "113208", "113209", "113210", "113211", "113212", "113215", "113216", "113217", "113220", "113221", "113222", "113223", "113224", "113225", "113226", "113227", "113229", "113231", "113233", "113234", "113235", "113237", "113238", "113239", "113240", "113244", "113246", "113247", "113251", "113252", "113253", "113255", "113257", "113259", "113263", "113264", "113266", "113269", "113272", "113281", "113283", "113285", "113286", "113287", "113288", "113289", "113291", "113295", "113296", "113298", "113300", "113302", "113303", "113305", "113307", "113311", "113314", "113316", "113318", "113320", "113322", "113324", "113329", "113330", "113335", "113338", "113339", "113346", "113347", "113349", "113350", "113351", "113352", "113353", "113359", "113360", "113361", "113366", "113370", "113371", "113372", "113373", "113375", "113377", "113378", "113381", "113382", "113386", "113387", "113388", "113392", "113394", "113398", "113399", "113400", "113401", "113404", "113405", "113406", "113408", "113410", "113413", "113414", "113415", "113418", "113423", "113428", "113430", "113432", "113433", "113435", "113439", "113440", "113441", "113443", "113444", "113445", "113446", "113454", "113455", "113457", "113458", "113459", "113460", "113466", "113467", "113468", "113470", "113473", "113475", "113476", "113479", "113482", "113483", "113484", "113486", "113489", "113490", "113491", "113492", "113496", "113499", "113501", "113502", "113505", "113508", "113510", "113511", "113512", "113513", "113515", "113516", "113518", "113519", "113520", "113521", "113523", "113524", "113526", "113527", "113530", "113531", "113532", "113533", "113535", "113539", "113541", "113542", "113543", "113545", "113547", "113550", "113551", "113552", "113554", "113555", "113560", "113561", "113562", "113567", "113569", "113572", "113575", "113577", "113579", "113583", "113588", "113590", "113591", "113594", "113597", "113599", "113600", "113602", "113603", "113604", "113605", "113609", "113610", "113611", "113613", "113615", "113619", "113621", "113622", "113626", "113627", "113628", "113630", "113631", "113633", "113637", "113638", "113643", "113644", "113645", "113646", "113647", "113649", "113650", "113651", "113654", "113655", "113657", "113658", "113659", "113660", "113662", "113666", "113668", "113670", "113671", "113675", "113677", "113681", "113683", "113690", "113691", "113692", "113693", "113695", "113698", "113699", "113701", "113702", "113703", "113704", "113705", "113708", "113711", "113712", "113713", "113714", "113717", "113718", "113720", "113721", "113722", "113723", "113726", "113729", "113732", "113735", "113736", "113742", "113743", "113744", "113745", "113753", "113755", "113758", "113760", "113762", "113763", "113764", "113766", "113772", "113773", "113775", "113777", "113779", "113783", "113784", "113786", "113788", "113791", "113792", "113796", "113797", "113799", "113802", "113803", "113807", "113808", "113809", "113815", "113816", "113818", "113819", "113820", "113821", "113824", "113825", "113826", "113828", "113831", "113834", "113835", "113836", "113837", "113842", "113843", "113844", "113845", "113847", "113849", "113850", "113851", "113853", "113855", "113856", "113857", "113858", "113859", "113861", "113862", "113863", "113864", "113865", "113868", "113869", "113870", "113872", "113874", "113876", "113878", "113879", "113881", "113883", "113884", "113885", "113887", "113890", "113891", "113897", "113899", "113901", "113903", "113905", "113908", "113909", "113910", "113914", "113915", "113916", "113917", "113919", "113920", "113923", "113925", "113926", "113927", "113929", "113931", "113932", "113935", "113936", "113938", "113939", "113941", "113943", "113945", "113946", "113949", "113950", "113952", "113953", "113954", "113957", "113962", "113964", "113969", "113970", "113971", "113972", "113973", "113974", "113976", "113979", "113980", "113981", "113982", "113983", "113987", "113988", "113991", "113993", "113994", "113997", "114001", "114003", "114004", "114005", "114007", "114008", "114009", "114010", "114011", "114014", "114016", "114017", "114022", "114025", "114029", "114034", "114035", "114037", "114038", "114040", "114043", "114045", "114046", "114048", "114049", "114050", "114051", "114053", "114054", "114055", "114056", "114057", "114058", "114059", "114064", "114065", "114066", "114067", "114069", "114079", "114081", "114082", "114083", "114086", "114089", "114090", "114093", "114095", "114101", "114102", "114107", "114109", "114110", "114111", "114112", "114113", "114114", "114117", "114118", "114121", "114122", "114123", "114126", "114128", "114137", "114140", "114142", "114146", "114148", "114151", "114152", "114153", "114159", "114161", "114162", "114163", "114168", "114169", "114173", "114174", "114175", "114176", "114181", "114183", "114184", "114187", "114189", "114190", "114192", "114193", "114194", "114195", "114196", "114200", "114204", "114206", "114207", "114212", "114215", "114216", "114220", "114221", "114223", "114224", "114226", "114227", "114232", "114234", "114237", "114243", "114245", "114246", "114247", "114248", "114251", "114252", "114255", "114256", "114257", "114258", "114263", "114264", "114266", "114267", "114268", "114270", "114271", "114272", "114273", "114274", "114275", "114276", "114280", "114281", "114282", "114284", "114286", "114291", "114292", "114293", "114294", "114297", "114300", "114302", "114307", "114309", "114310", "114313", "114314", "114315", "114316", "114319", "114321", "114322", "114325", "114326", "114327", "114330", "114334", "114341", "114342", "114345", "114347", "114348", "114349", "114350", "114351", "114352", "114356", "114357", "114361", "114362", "114364", "114365", "114366", "114373", "114374", "114377", "114378", "114379", "114382", "114383", "114384", "114386", "114387", "114388", "114389", "114390", "114393", "114401", "114404", "114406", "114411", "114415", "114416", "114420", "114421", "114423", "114424", "114426", "114427", "114428", "114432", "114435", "114437", "114438", "114439", "114440", "114442", "114443", "114448", "114451", "114453", "114454", "114455", "114459", "114460", "114461", "114463", "114465", "114466", "114467", "114470", "114475", "114477", "114481", "114484", "114485", "114487", "114488", "114490", "114492", "114493", "114495", "114497", "114498", "114499", "114501", "114502", "114503", "114505", "114506", "114507", "114508", "114512", "114514", "114516", "114517", "114518", "114520", "114521", "114523", "114524", "114529", "114530", "114532", "114533", "114535", "114537", "114538", "114539", "114540", "114543", "114545", "114547", "114548", "114549", "114552", "114557", "114558", "114559", "114561", "114562", "114567", "114568", "114572", "114573", "114576", "114578", "114579", "114580", "114581", "114582", "114584", "114585", "114587", "114589", "114590", "114592", "114593", "114594", "114595", "114596", "114598", "114600", "114601", "114603", "114605", "114606", "114607", "114608", "114609", "114610", "114617", "114618", "114619", "114621", "114624", "114625", "114626", "114629", "114634", "114635", "114636", "114637", "114639", "114642", "114643", "114644", "114645", "114646", "114647", "114650", "114651", "114656", "114662", "114667", "114669", "114670", "114674", "114675", "114678", "114679", "114680", "114684", "114687", "114688", "114689", "114692", "114695", "114696", "114698", "114700", "114701", "114704", "114706", "114707", "114708", "114710", "114715", "114716", "114719", "114720", "114722", "114728", "114732", "114733", "114734", "114737", "114739", "114740", "114741", "114742", "114746", "114747", "114749", "114750", "114751", "114752", "114754", "114756", "114757", "114759", "114760", "114763", "114764", "114765", "114766", "114769", "114774", "114777", "114783", "114785", "114787", "114789", "114790", "114791", "114792", "114793", "114797", "114798", "114803", "114805", "114807", "114808", "114809", "114811", "114812", "114814", "114815", "114816", "114818", "114819", "114821", "114824", "114826", "114827", "114836", "114838", "114840", "114843", "114845", "114848", "114850", "114852", "114853", "114854", "114856", "114859", "114862", "114863", "114867", "114868", "114869", "114870", "114871", "114873", "114875", "114877", "114878", "114882", "114883", "114884", "114886", "114887", "114888", "114889", "114891", "114892", "114893", "114894", "114895", "114896", "114898", "114899", "114900", "114901", "114902", "114904", "114905", "114907", "114908", "114909", "114910", "114911", "114913", "114914", "114915", "114916", "114917", "114919", "114920", "114921", "114922", "114923", "114924", "114925", "114928", "114930", "114933", "114935", "114938", "114940", "114941", "114943", "114944", "114945", "114946", "114948", "114950", "114951", "114952", "114954", "114955", "114956", "114957", "114958", "114959", "114965", "114972", "114974", "114975", "114976", "114977", "114978", "114979", "114981", "114983", "114985", "114987", "114989", "114992", "114993", "114994", "114995", "114996", "114998", "114999", "115001", "115003", "115008", "115009", "115011", "115013", "115015", "115017", "115020", "115022", "115024", "115027", "115028", "115029", "115030", "115034", "115037", "115039", "115041", "115043", "115045", "115047", "115052", "115055", "115056", "115057", "115059", "115060", "115061", "115066", "115067", "115068", "115069", "115070", "115076", "115077", "115080", "115082", "115083", "115084", "115086", "115087", "115088", "115089", "115093", "115095", "115096", "115097", "115100", "115102", "115104", "115106", "115107", "115109", "115111", "115115", "115116", "115117", "115123", "115124", "115126", "115128", "115129", "115130", "115135", "115136", "115137", "115142", "115147", "115149", "115151", "115152", "115155", "115156", "115157", "115159", "115160", "115161", "115162", "115163", "115166", "115167", "115172", "115174", "115176", "115179", "115180", "115184", "115185", "115186", "115188", "115189", "115191", "115197", "115199", "115200", "115201", "115203", "115207", "115208", "115209", "115210", "115211", "115212", "115214", "115215", "115216", "115217", "115220", "115225", "115226", "115229", "115231", "115233", "115236", "115237", "115238", "115239", "115240", "115241", "115242", "115244", "115247", "115249", "115250", "115251", "115252", "115253", "115254", "115256", "115257", "115258", "115259", "115261", "115264", "115265", "115267", "115268", "115272", "115280", "115284", "115285", "115286", "115287", "115288", "115297", "115299", "115305", "115307", "115313", "115314", "115316", "115319", "115326", "115328", "115331", "115333", "115334", "115335", "115338", "115340", "115342", "115343", "115346", "115347", "115350", "115355", "115356", "115357", "115359", "115361", "115362", "115364", "115367", "115369", "115370", "115372", "115373", "115374", "115375", "115379", "115381", "115382", "115383", "115385", "115387", "115394", "115395", "115396", "115397", "115398", "115399", "115400", "115401", "115409", "115411", "115412", "115413", "115414", "115415", "115416", "115419", "115422", "115427", "115428", "115431", "115433", "115436", "115438", "115439", "115441", "115443", "115445", "115446", "115447", "115450", "115452", "115453", "115454", "115455", "115456", "115458", "115461", "115469", "115470", "115474", "115478", "115480", "115481", "115483", "115484", "115486", "115489", "115490", "115491", "115492", "115493", "115494", "115495", "115496", "115497", "115499", "115500", "115504", "115505", "115506", "115510", "115513", "115514", "115515", "115516", "115519", "115522", "115524", "115525", "115526", "115529", "115530", "115532", "115534", "115535", "115537", "115538", "115539", "115540", "115541", "115543", "115544", "115545", "115546", "115547", "115553", "115559", "115564", "115569", "115570", "115573", "115575", "115581", "115583", "115585", "115586", "115589", "115591", "115592", "115593", "115594", "115596", "115598", "115601", "115602", "115603", "115605", "115608", "115611", "115614", "115616", "115617", "115618", "115619", "115627", "115628", "115631", "115632", "115633", "115634", "115637", "115638", "115645", "115648", "115656", "115657", "115659", "115661", "115663", "115668", "115670", "115673", "115674", "115677", "115679", "115680", "115684", "115686", "115689", "115690", "115694", "115695", "115696", "115701", "115702", "115704", "115705", "115708", "115709", "115710", "115711", "115712", "115714", "115715", "115717", "115718", "115720", "115722", "115723", "115724", "115727", "115728", "115731", "115732", "115736", "115737", "115740", "115741", "115745", "115746", "115748", "115749", "115750", "115751", "115752", "115753", "115754", "115755", "115756", "115758", "115761", "115763", "115765", "115767", "115770", "115771", "115774", "115777", "115781", "115782", "115786", "115787", "115790", "115791", "115797", "115798", "115800", "115801", "115804", "115807", "115810", "115811", "115814", "115815", "115816", "115820", "115821", "115822", "115824", "115825", "115830", "115831", "115832", "115833", "115834", "115835", "115836", "115837", "115839", "115844", "115845", "115846", "115848", "115850", "115851", "115854", "115855", "115857", "115858", "115861", "115862", "115864", "115866", "115867", "115869", "115871", "115873", "115875", "115877", "115878", "115880", "115885", "115891", "115892", "115893", "115899", "115900", "115902", "115903", "115905", "115906", "115907", "115908", "115909", "115910", "115912", "115913", "115917", "115924", "115927", "115929", "115932", "115933", "115935", "115936", "115939", "115941", "115942", "115944", "115945", "115946", "115947", "115948", "115950", "115952", "115957", "115958", "115962", "115963", "115966", "115969", "115971", "115973", "115974", "115980", "115987", "115988", "115989", "115994", "115995", "115997", "115999", "116005", "116006", "116009", "116011", "116012", "116015", "116018", "116021", "116023", "116024", "116025", "116028", "116036", "116039", "116043", "116046", "116047", "116051", "116053", "116055", "116058", "116059", "116060", "116062", "116063", "116065", "116068", "116072", "116073", "116076", "116077", "116080", "116081", "116083", "116086", "116087", "116089", "116091", "116094", "116098", "116101", "116107", "116110", "116112", "116113", "116120", "116128", "116134", "116135", "116136", "116138", "116145", "116147", "116148", "116149", "116150", "116152", "116159", "116162", "116166", "116167", "116170", "116171", "116173", "116177", "116182", "116184", "116185", "116187", "116191", "116194", "116195", "116196", "116197", "116198", "116199", "116203", "116204", "116208", "116210", "116211", "116216", "116217", "116218", "116220", "116222", "116227", "116228", "116229", "116230", "116231", "116235", "116236", "116237", "116238", "116241", "116242", "116243", "116244", "116245", "116250", "116251", "116252", "116255", "116256", "116257", "116258", "116260", "116261", "116262", "116263", "116264", "116270", "116272", "116274", "116275", "116277", "116278", "116280", "116282", "116283", "116284", "116285", "116287", "116288", "116289", "116290", "116294", "116299", "116300", "116303", "116304", "116305", "116306", "116309", "116311", "116312", "116317", "116321", "116328", "116330", "116336", "116338", "116340", "116341", "116344", "116346", "116348", "116351", "116353", "116355", "116357", "116358", "116360", "116365", "116366", "116367", "116368", "116369", "116370", "116372", "116373", "116375", "116382", "116383", "116385", "116386", "116388", "116389", "116390", "116392", "116394", "116396", "116398", "116399", "116401", "116402", "116406", "116409", "116413", "116415", "116420", "116422", "116423", "116424", "116427", "116430", "116431", "116433", "116436", "116437", "116440", "116442", "116444", "116445", "116446", "116450", "116451", "116458", "116460", "116462", "116464", "116466", "116467", "116468", "116472", "116473", "116474", "116477", "116479", "116482", "116483", "116484", "116489", "116491", "116492", "116493", "116496", "116498", "116499", "116503", "116507", "116508", "116510", "116511", "116512", "116513", "116514", "116516", "116518", "116520", "116521", "116522", "116523", "116525", "116527", "116530", "116531", "116532", "116533", "116534", "116535", "116536", "116538", "116539", "116541", "116545", "116547", "116549", "116551", "116552", "116554", "116557", "116558", "116559", "116561", "116562", "116567", "116568", "116571", "116574", "116577", "116578", "116581", "116582", "116583", "116589", "116590", "116592", "116593", "116594", "116595", "116602", "116608", "116609", "116610", "116614", "116616", "116618", "116621", "116623", "116632", "116633", "116636", "116638", "116640", "116641", "116643", "116644", "116649", "116650", "116651", "116654", "116655", "116656", "116657", "116661", "116662", "116665", "116666", "116667", "116668", "116672", "116674", "116675", "116676", "116677", "116678", "116680", "116684", "116686", "116689", "116690", "116693", "116694", "116695", "116697", "116700", "116701", "116702", "116703", "116705", "116708", "116710", "116715", "116716", "116718", "116722", "116725", "116728", "116729", "116734", "116736", "116738", "116739", "116740", "116744", "116749", "116750", "116752", "116756", "116758", "116761", "116762", "116764", "116765", "116766", "116767", "116768", "116770", "116771", "116772", "116773", "116774", "116775", "116778", "116779", "116781", "116783", "116784", "116785", "116786", "116788", "116789", "116790", "116791", "116793", "116796", "116798", "116799", "116800", "116804", "116805", "116806", "116807", "116808", "116809", "116814", "116815", "116816", "116818", "116822", "116824", "116825", "116829", "116830", "116831", "116833", "116836", "116837", "116841", "116843", "116845", "116847", "116848", "116850", "116851", "116852", "116854", "116855", "116859", "116861", "116863", "116864", "116865", "116866", "116868", "116870", "116871", "116876", "116877", "116878", "116879", "116880", "116882", "116883", "116884", "116889", "116891", "116892", "116894", "116895", "116896", "116900", "116910", "116911", "116912", "116913", "116915", "116917", "116918", "116921", "116925", "116927", "116929", "116933", "116935", "116940", "116944", "116945", "116946", "116948", "116952", "116953", "116954", "116955", "116957", "116961", "116964", "116966", "116969", "116970", "116976", "116977", "116979", "116980", "116983", "116985", "116986", "116987", "116988", "116990", "116991", "116992", "116993", "116995", "116996", "116998", "116999", "117001", "117005", "117007", "117008", "117010", "117011", "117013", "117015", "117017", "117018", "117024", "117026", "117028", "117029", "117031", "117032", "117033", "117036", "117038", "117047", "117048", "117049", "117050", "117051", "117052", "117055", "117059", "117063", "117068", "117070", "117071", "117075", "117076", "117077", "117078", "117080", "117081", "117085", "117086", "117088", "117089", "117090", "117091", "117092", "117093", "117095", "117098", "117101", "117105", "117107", "117112", "117115", "117117", "117118", "117120", "117122", "117123", "117125", "117128", "117130", "117131", "117132", "117134", "117135", "117138", "117139", "117142", "117146", "117147", "117149", "117150", "117151", "117154", "117157", "117163", "117167", "117171", "117172", "117173", "117175", "117176", "117177", "117178", "117179", "117184", "117186", "117187", "117188", "117189", "117191", "117192", "117194", "117195", "117196", "117197", "117198", "117202", "117205", "117208", "117210", "117211", "117212", "117215", "117217", "117218", "117221", "117223", "117225", "117227", "117229", "117231", "117232", "117233", "117234", "117238", "117239", "117241", "117242", "117247", "117248", "117249", "117250", "117252", "117254", "117255", "117256", "117257", "117259", "117261", "117262", "117263", "117264", "117265", "117271", "117273", "117277", "117278", "117279", "117280", "117281", "117282", "117283", "117284", "117288", "117290", "117291", "117294", "117295", "117296", "117298", "117299", "117300", "117301", "117302", "117303", "117304", "117305", "117306", "117307", "117308", "117309", "117310", "117312", "117316", "117317", "117318", "117321", "117322", "117323", "117327", "117328", "117329", "117332", "117333", "117334", "117337", "117338", "117339", "117340", "117341", "117344", "117350", "117351", "117354", "117355", "117367", "117371", "117372", "117375", "117377", "117378", "117379", "117381", "117382", "117385", "117391", "117393", "117394", "117395", "117396", "117397", "117399", "117401", "117402", "117403", "117406", "117407", "117409", "117414", "117415", "117418", "117419", "117421", "117427", "117428", "117431", "117435", "117437", "117438", "117440", "117441", "117442", "117443", "117447", "117449", "117450", "117451", "117453", "117454", "117455", "117458", "117460", "117464", "117465", "117468", "117470", "117471", "117473", "117475", "117476", "117477", "117478", "117479", "117480", "117481", "117482", "117484", "117488", "117489", "117490", "117491", "117492", "117493", "117495", "117496", "117497", "117499", "117503", "117505", "117506", "117512", "117514", "117515", "117516", "117518", "117519", "117520", "117523", "117526", "117530", "117531", "117533", "117535", "117536", "117537", "117538", "117539", "117540", "117541", "117542", "117545", "117546", "117549", "117553", "117555", "117556", "117557", "117562", "117564", "117569", "117572", "117575", "117576", "117578", "117579", "117585", "117586", "117587", "117588", "117591", "117592", "117593", "117596", "117597", "117599", "117600", "117601", "117602", "117603", "117604", "117605", "117606", "117607", "117609", "117610", "117611", "117614", "117617", "117618", "117620", "117621", "117623", "117625", "117632", "117633", "117634", "117635", "117638", "117640", "117641", "117642", "117643", "117645", "117647", "117652", "117655", "117656", "117657", "117659", "117660", "117661", "117663", "117667", "117668", "117669", "117671", "117672", "117678", "117681", "117682", "117683", "117684", "117685", "117686", "117688", "117693", "117697", "117699", "117700", "117703", "117705", "117706", "117707", "117711", "117714", "117716", "117717", "117719", "117720", "117722", "117723", "117724", "117725", "117726", "117729", "117731", "117736", "117737", "117738", "117743", "117744", "117745", "117747", "117748", "117749", "117750", "117752", "117754", "117757", "117758", "117759", "117760", "117765", "117766", "117771", "117775", "117776", "117778", "117779", "117780", "117781", "117783", "117785", "117786", "117787", "117788", "117791", "117794", "117795", "117797", "117798", "117799", "117804", "117805", "117806", "117809", "117810", "117815", "117816", "117817", "117818", "117819", "117821", "117824", "117827", "117829", "117830", "117831", "117832", "117835", "117838", "117840", "117841", "117844", "117847", "117851", "117852", "117857", "117861", "117862", "117865", "117866", "117867", "117871", "117872", "117873", "117877", "117878", "117879", "117880", "117881", "117883", "117887", "117890", "117891", "117893", "117894", "117896", "117897", "117899", "117900", "117902", "117905", "117907", "117909", "117912", "117915", "117922", "117925", "117929", "117931", "117933", "117935", "117937", "117942", "117943", "117945", "117947", "117948", "117950", "117951", "117953", "117954", "117955", "117956", "117959", "117961", "117964", "117965", "117969", "117971", "117972", "117973", "117975", "117979", "117980", "117981", "117983", "117985", "117986", "117990", "117992", "117995", "117996", "117997", "118003", "118004", "118005", "118006", "118007", "118010", "118011", "118012", "118013", "118015", "118016", "118017", "118018", "118019", "118021", "118022", "118023", "118025", "118027", "118028", "118030", "118032", "118035", "118040", "118042", "118043", "118044", "118045", "118047", "118049", "118050", "118051", "118052", "118055", "118056", "118066", "118068", "118069", "118070", "118073", "118075", "118076", "118077", "118084", "118086", "118089", "118090", "118091", "118093", "118097", "118099", "118101", "118106", "118107", "118108", "118110", "118117", "118118", "118120", "118123", "118125", "118127", "118131", "118132", "118133", "118134", "118137", "118139", "118149", "118152", "118153", "118154", "118155", "118158", "118159", "118162", "118166", "118172", "118173", "118175", "118177", "118178", "118179", "118180", "118184", "118187", "118190", "118193", "118205", "118206", "118208", "118211", "118213", "118215", "118218", "118219", "118221", "118222", "118223", "118225", "118233", "118235", "118236", "118237", "118238", "118239", "118240", "118241", "118242", "118243", "118245", "118247", "118248", "118249", "118251", "118252", "118253", "118254", "118255", "118258", "118261", "118262", "118263", "118264", "118265", "118266", "118267", "118269", "118270", "118274", "118276", "118278", "118279", "118285", "118288", "118290", "118291", "118293", "118296", "118297", "118298", "118301", "118305", "118307", "118309", "118310", "118311", "118317", "118319", "118320", "118322", "118323", "118325", "118327", "118328", "118330", "118331", "118332", "118333", "118334", "118336", "118337", "118340", "118341", "118343", "118344", "118350", "118352", "118354", "118356", "118357", "118361", "118362", "118363", "118365", "118367", "118370", "118371", "118373", "118374", "118375", "118376", "118378", "118384", "118387", "118390", "118393", "118394", "118398", "118403", "118405", "118406", "118416", "118418", "118420", "118423", "118427", "118428", "118429", "118431", "118433", "118434", "118436", "118437", "118440", "118441", "118442", "118443", "118446", "118447", "118450", "118451", "118452", "118454", "118456", "118458", "118460", "118461", "118463", "118464", "118465", "118467", "118469", "118472", "118473", "118474", "118475", "118476", "118477", "118478", "118479", "118480", "118481", "118483", "118484", "118486", "118493", "118494", "118495", "118497", "118498", "118499", "118500", "118505", "118508", "118509", "118510", "118515", "118516", "118517", "118518", "118520", "118521", "118522", "118523", "118524", "118525", "118528", "118529", "118531", "118532", "118534", "118536", "118543", "118544", "118545", "118548", "118550", "118552", "118553", "118554", "118555", "118556", "118557", "118559", "118560", "118561", "118562", "118563", "118565", "118566", "118567", "118568", "118569", "118571", "118572", "118573", "118574", "118577", "118579", "118581", "118583", "118584", "118588", "118589", "118590", "118593", "118594", "118595", "118596", "118599", "118602", "118603", "118605", "118607", "118609", "118610", "118611", "118612", "118613", "118614", "118618", "118620", "118621", "118623", "118624", "118628", "118629", "118632", "118633", "118640", "118641", "118644", "118645", "118646", "118649", "118650", "118652", "118653", "118654", "118655", "118657", "118658", "118661", "118662", "118668", "118675", "118677", "118678", "118680", "118681", "118682", "118683", "118685", "118686", "118688", "118689", "118691", "118693", "118694", "118696", "118699", "118700", "118701", "118702", "118706", "118708", "118711", "118712", "118713", "118715", "118716", "118719", "118720", "118723", "118724", "118725", "118728", "118729", "118732", "118733", "118735", "118737", "118738", "118739", "118743", "118744", "118747", "118749", "118751", "118752", "118755", "118756", "118757", "118758", "118759", "118760", "118761", "118762", "118765", "118766", "118770", "118771", "118772", "118773", "118774", "118775", "118779", "118780", "118781", "118784", "118787", "118788", "118790", "118791", "118792", "118793", "118795", "118797", "118802", "118803", "118804", "118805", "118807", "118810", "118811", "118813", "118818", "118820", "118822", "118824", "118825", "118827", "118828", "118829", "118830", "118831", "118833", "118835", "118836", "118837", "118841", "118842", "118844", "118845", "118846", "118847", "118849", "118851", "118852", "118854", "118856", "118858", "118859", "118860", "118861", "118864", "118866", "118870", "118873", "118878", "118882", "118884", "118885", "118886", "118888", "118889", "118890", "118891", "118900", "118902", "118904", "118907", "118908", "118914", "118916", "118917", "118921", "118923", "118925", "118926", "118929", "118930", "118931", "118933", "118934", "118935", "118939", "118944", "118946", "118947", "118948", "118950", "118955", "118959", "118960", "118962", "118964", "118965", "118967", "118968", "118975", "118976", "118977", "118979", "118981", "118983", "118984", "118985", "118988", "118989", "118990", "118992", "118997", "118998", "118999", "119000", "119002", "119006", "119008", "119012", "119013", "119014", "119015", "119016", "119021", "119022", "119023", "119024", "119026", "119030", "119032", "119034", "119035", "119036", "119037", "119041", "119042", "119044", "119045", "119046", "119048", "119050", "119051", "119052", "119056", "119057", "119059", "119060", "119064", "119065", "119067", "119069", "119070", "119074", "119077", "119078", "119080", "119081", "119084", "119085", "119090", "119091", "119092", "119097", "119100", "119102", "119108", "119111", "119113", "119115", "119116", "119117", "119121", "119124", "119125", "119127", "119128", "119131", "119133", "119134", "119137", "119138", "119139", "119140", "119144", "119147", "119148", "119149", "119150", "119152", "119153", "119158", "119159", "119162", "119164", "119166", "119167", "119168", "119169", "119170", "119172", "119173", "119177", "119180", "119181", "119183", "119189", "119190", "119191", "119194", "119195", "119196", "119197", "119198", "119200", "119202", "119203", "119205", "119207", "119208", "119212", "119214", "119216", "119217", "119219", "119222", "119224", "119229", "119230", "119231", "119232", "119234", "119235", "119237", "119238", "119241", "119244", "119248", "119249", "119250", "119251", "119252", "119253", "119254", "119258", "119261", "119262", "119264", "119265", "119269", "119270", "119273", "119274", "119276", "119280", "119283", "119284", "119285", "119287", "119289", "119291", "119293", "119294", "119297", "119298", "119299", "119300", "119303", "119305", "119306", "119307", "119310", "119311", "119312", "119318", "119319", "119322", "119324", "119327", "119328", "119329", "119332", "119333", "119335", "119342", "119343", "119346", "119350", "119356", "119357", "119359", "119360", "119363", "119364", "119366", "119367", "119368", "119369", "119371", "119373", "119374", "119377", "119378", "119379", "119380", "119384", "119385", "119386", "119387", "119388", "119389", "119390", "119392", "119395", "119396", "119397", "119398", "119400", "119406", "119408", "119409", "119411", "119413", "119414", "119416", "119417", "119418", "119420", "119421", "119422", "119423", "119424", "119426", "119428", "119430", "119432", "119433", "119440", "119443", "119447", "119449", "119450", "119453", "119456", "119457", "119458", "119459", "119460", "119464", "119466", "119469", "119472", "119473", "119475", "119476", "119479", "119481", "119482", "119484", "119485", "119486", "119487", "119490", "119492", "119494", "119496", "119497", "119498", "119502", "119503", "119504", "119506", "119508", "119509", "119513", "119516", "119517", "119520", "119523", "119524", "119526", "119527", "119529", "119535", "119536", "119537", "119540", "119544", "119546", "119551", "119553", "119554", "119557", "119558", "119559", "119560", "119561", "119562", "119563", "119566", "119567", "119570", "119571", "119573", "119575", "119576", "119577", "119580", "119582", "119583", "119588", "119589", "119591", "119592", "119593", "119596", "119597", "119599", "119600", "119601", "119603", "119604", "119606", "119607", "119609", "119610", "119614", "119616", "119617", "119618", "119619", "119622", "119623", "119625", "119626", "119627", "119635", "119637", "119638", "119639", "119645", "119647", "119649", "119651", "119660", "119662", "119665", "119669", "119670", "119672", "119673", "119675", "119678", "119679", "119681", "119682", "119683", "119684", "119686", "119687", "119688", "119689", "119691", "119694", "119696", "119697", "119698", "119700", "119701", "119702", "119703", "119709", "119710", "119711", "119713", "119714", "119715", "119716", "119717", "119719", "119720", "119724", "119725", "119726", "119727", "119730", "119731", "119732", "119735", "119738", "119739", "119740", "119742", "119743", "119745", "119746", "119747", "119750", "119752", "119753", "119754", "119755", "119756", "119758", "119759", "119761", "119762", "119764", "119766", "119768", "119769", "119771", "119772", "119775", "119778", "119783", "119784", "119785", "119786", "119787", "119788", "119789", "119791", "119794", "119795", "119796", "119798", "119799", "119801", "119802", "119805", "119808", "119811", "119812", "119814", "119816", "119817", "119818", "119819", "119820", "119821", "119823", "119826", "119828", "119830", "119832", "119833", "119836", "119839", "119841", "119842", "119844", "119845", "119847", "119852", "119853", "119855", "119856", "119857", "119859", "119860", "119862", "119864", "119865", "119868", "119869", "119873", "119874", "119875", "119877", "119878", "119879", "119880", "119884", "119885", "119886", "119887", "119888", "119889", "119892", "119893", "119896", "119897", "119898", "119901", "119903", "119904", "119905", "119908", "119910", "119912", "119913", "119914", "119918", "119922", "119923", "119925", "119927", "119928", "119930", "119931", "119933", "119934", "119935", "119936", "119938", "119941", "119942", "119944", "119945", "119948", "119951", "119953", "119954", "119955", "119957", "119958", "119964", "119966", "119967", "119968", "119970", "119971", "119972", "119975", "119979", "119981", "119986", "119988", "119990", "120001", "120002", "120005", "120006", "120009", "120010", "120011", "120012", "120015", "120018", "120019", "120021", "120024", "120025", "120026", "120030", "120032", "120034", "120037", "120040", "120042", "120043", "120045", "120050", "120051", "120052", "120056", "120057", "120058", "120066", "120067", "120068", "120072", "120074", "120076", "120078", "120079", "120083", "120084", "120085", "120087", "120088", "120094", "120097", "120099", "120101", "120104", "120107", "120111", "120112", "120120", "120122", "120123", "120127", "120128", "120129", "120133", "120134", "120135", "120136", "120138", "120139", "120140", "120141", "120142", "120143", "120145", "120149", "120152", "120153", "120154", "120155", "120158", "120160", "120161", "120162", "120163", "120166", "120167", "120170", "120171", "120174", "120177", "120178", "120182", "120183", "120186", "120187", "120190", "120194", "120195", "120196", "120199", "120201", "120208", "120209", "120210", "120211", "120212", "120213", "120214", "120215", "120217", "120222", "120224", "120226", "120228", "120229", "120230", "120231", "120232", "120235", "120236", "120241", "120247", "120248", "120250", "120251", "120252", "120257", "120258", "120259", "120263", "120264", "120267", "120268", "120269", "120270", "120271", "120272", "120273", "120274", "120276", "120279", "120282", "120285", "120290", "120291", "120292", "120295", "120297", "120300", "120301", "120302", "120304", "120307", "120308", "120311", "120313", "120314", "120318", "120319", "120322", "120323", "120326", "120331", "120335", "120337", "120338", "120341", "120342", "120343", "120344", "120347", "120348", "120350", "120354", "120362", "120363", "120365", "120366", "120367", "120368", "120369", "120374", "120375", "120376", "120379", "120380", "120382", "120384", "120385", "120389", "120391", "120393", "120398", "120400", "120401", "120402", "120403", "120409", "120410", "120411", "120414", "120416", "120417", "120419", "120424", "120426", "120427", "120429", "120430", "120431", "120433", "120434", "120436", "120437", "120439", "120440", "120442", "120443", "120446", "120447", "120448", "120451", "120452", "120457", "120460", "120466", "120467", "120470", "120472", "120473", "120474", "120476", "120479", "120481", "120482", "120483", "120486", "120489", "120490", "120492", "120493", "120494", "120495", "120499", "120501", "120505", "120506", "120507", "120510", "120511", "120512", "120513", "120514", "120515", "120518", "120520", "120523", "120527", "120529", "120531", "120532", "120534", "120535", "120537", "120540", "120546", "120549", "120553", "120555", "120557", "120559", "120561", "120565", "120568", "120570", "120572", "120573", "120576", "120577", "120578", "120581", "120583", "120585", "120586", "120589", "120590", "120591", "120593", "120594", "120595", "120596", "120597", "120598", "120599", "120600", "120602", "120605", "120606", "120607", "120609", "120610", "120611", "120612", "120613", "120615", "120619", "120622", "120625", "120627", "120629", "120632", "120633", "120634", "120635", "120637", "120638", "120639", "120640", "120641", "120642", "120644", "120648", "120649", "120653", "120655", "120656", "120663", "120664", "120666", "120667", "120668", "120669", "120670", "120672", "120674", "120677", "120679", "120680", "120681", "120682", "120683", "120684", "120685", "120688", "120689", "120692", "120693", "120694", "120695", "120697", "120698", "120703", "120707", "120709", "120711", "120712", "120714", "120716", "120719", "120721", "120724", "120728", "120730", "120736", "120739", "120740", "120741", "120742", "120744", "120745", "120747", "120748", "120751", "120752", "120753", "120755", "120756", "120758", "120759", "120761", "120763", "120765", "120768", "120769", "120770", "120771", "120772", "120776", "120777", "120778", "120781", "120782", "120784", "120786", "120787", "120791", "120792", "120793", "120794", "120795", "120796", "120797", "120798", "120799", "120800", "120802", "120803", "120804", "120806", "120808", "120811", "120812", "120815", "120818", "120819", "120820", "120821", "120823", "120824", "120828", "120830", "120831", "120832", "120834", "120835", "120838", "120840", "120845", "120846", "120852", "120854", "120857", "120858", "120859", "120860", "120862", "120864", "120865", "120866", "120868", "120869", "120871", "120872", "120875", "120876", "120879", "120880", "120882", "120884", "120885", "120888", "120892", "120896", "120897", "120898", "120899", "120901", "120903", "120909", "120918", "120919", "120920", "120922", "120923", "120924", "120925", "120926", "120927", "120931", "120934", "120936", "120937", "120939", "120940", "120945", "120948", "120949", "120953", "120957", "120959", "120963", "120966", "120967", "120968", "120969", "120970", "120971", "120972", "120979", "120987", "120988", "120991", "120992", "120994", "120995", "120997", "121001", "121003", "121005", "121006", "121007", "121008", "121009", "121010", "121013", "121014", "121017", "121019", "121020", "121022", "121023", "121027", "121028", "121032", "121033", "121035", "121036", "121038", "121043", "121048", "121050", "121052", "121053", "121054", "121055", "121056", "121057", "121059", "121060", "121061", "121062", "121063", "121064", "121068", "121069", "121072", "121075", "121076", "121077", "121078", "121079", "121080", "121081", "121082", "121084", "121085", "121087", "121088", "121089", "121092", "121093", "121096", "121098", "121099", "121101", "121103", "121104", "121105", "121106", "121107", "121109", "121112", "121114", "121115", "121116", "121117", "121119", "121121", "121123", "121125", "121130", "121131", "121133", "121137", "121142", "121143", "121144", "121145", "121147", "121148", "121150", "121152", "121155", "121156", "121158", "121159", "121160", "121162", "121164", "121165", "121170", "121175", "121180", "121183", "121184", "121186", "121187", "121188", "121190", "121191", "121198", "121199", "121201", "121202", "121203", "121204", "121206", "121207", "121208", "121210", "121213", "121214", "121215", "121217", "121219", "121221", "121222", "121223", "121225", "121226", "121228", "121233", "121234", "121237", "121240", "121242", "121245", "121246", "121247", "121248", "121252", "121253", "121255", "121259", "121264", "121265", "121266", "121267", "121268", "121270", "121271", "121272", "121273", "121279", "121281", "121282", "121285", "121287", "121289", "121292", "121294", "121297", "121300", "121301", "121303", "121304", "121305", "121306", "121307", "121308", "121310", "121311", "121319", "121322", "121323", "121324", "121327", "121330", "121332", "121333", "121334", "121337", "121338", "121339", "121340", "121343", "121346", "121347", "121349", "121350", "121352", "121353", "121357", "121359", "121361", "121365", "121366", "121367", "121368", "121370", "121371", "121373", "121374", "121376", "121377", "121378", "121391", "121393", "121394", "121396", "121397", "121402", "121404", "121405", "121411", "121412", "121413", "121415", "121417", "121418", "121423", "121428", "121432", "121433", "121434", "121436", "121437", "121439", "121440", "121441", "121443", "121445", "121447", "121448", "121449", "121450", "121451", "121455", "121456", "121458", "121462", "121465", "121466", "121469", "121470", "121471", "121473", "121474", "121475", "121478", "121479", "121481", "121483", "121486", "121487", "121490", "121493", "121496", "121497", "121499", "121500", "121501", "121504", "121506", "121508", "121509", "121510", "121511", "121512", "121513", "121514", "121515", "121516", "121520", "121521", "121523", "121525", "121526", "121529", "121530", "121533", "121536", "121541", "121545", "121547", "121549", "121553", "121556", "121559", "121563", "121564", "121569", "121570", "121572", "121573", "121574", "121581", "121585", "121589", "121593", "121595", "121603", "121605", "121607", "121611", "121614", "121615", "121616", "121618", "121620", "121621", "121623", "121624", "121629", "121630", "121631", "121632", "121633", "121640", "121642", "121643", "121647", "121648", "121649", "121653", "121654", "121655", "121657", "121658", "121661", "121666", "121667", "121668", "121672", "121673", "121674", "121675", "121679", "121680", "121682", "121683", "121684", "121685", "121690", "121692", "121694", "121700", "121702", "121704", "121707", "121713", "121714", "121719", "121720", "121723", "121726", "121727", "121730", "121733", "121735", "121737", "121740", "121743", "121746", "121747", "121748", "121749", "121752", "121754", "121755", "121757", "121759", "121760", "121761", "121762", "121763", "121764", "121765", "121766", "121771", "121774", "121775", "121780", "121781", "121782", "121784", "121786", "121788", "121792", "121794", "121795", "121796", "121797", "121798", "121800", "121801", "121802", "121803", "121804", "121805", "121807", "121809", "121812", "121815", "121816", "121817", "121820", "121822", "121824", "121825", "121827", "121830", "121831", "121832", "121835", "121838", "121841", "121845", "121846", "121847", "121849", "121855", "121857", "121858", "121859", "121861", "121862", "121863", "121864", "121866", "121867", "121868", "121869", "121870", "121871", "121872", "121879", "121881", "121882", "121883", "121884", "121885", "121887", "121889", "121893", "121896", "121897", "121898", "121900", "121902", "121905", "121910", "121912", "121913", "121919", "121920", "121923", "121924", "121925", "121926", "121927", "121928", "121929", "121933", "121934", "121936", "121938", "121940", "121941", "121944", "121946", "121947", "121948", "121949", "121950", "121951", "121952", "121954", "121955", "121957", "121959", "121960", "121962", "121964", "121965", "121967", "121969", "121971", "121975", "121976", "121977", "121980", "121983", "121984", "121985", "121986", "121987", "121988", "121991", "121992", "121994", "121996", "121997", "121998", "121999", "122002", "122006", "122008", "122009", "122010", "122011", "122015", "122017", "122019", "122025", "122027", "122028", "122029", "122031", "122033", "122034", "122039", "122042", "122044", "122047", "122048", "122049", "122050", "122053", "122058", "122059", "122062", "122063", "122065", "122067", "122070", "122071", "122073", "122075", "122077", "122078", "122079", "122081", "122083", "122085", "122086", "122087", "122088", "122093", "122094", "122095", "122097", "122098", "122099", "122101", "122102", "122105", "122106", "122107", "122112", "122113", "122114", "122119", "122120", "122121", "122122", "122123", "122126", "122127", "122129", "122130", "122132", "122135", "122137", "122141", "122144", "122152", "122155", "122157", "122158", "122159", "122160", "122162", "122164", "122170", "122171", "122173", "122174", "122176", "122177", "122180", "122183", "122185", "122186", "122188", "122193", "122195", "122196", "122198", "122200", "122201", "122205", "122213", "122215", "122217", "122218", "122220", "122222", "122223", "122226", "122228", "122229", "122230", "122232", "122235", "122237", "122239", "122240", "122242", "122244", "122245", "122246", "122247", "122248", "122249", "122253", "122256", "122258", "122259", "122261", "122266", "122267", "122271", "122272", "122273", "122276", "122277", "122279", "122282", "122287", "122288", "122290", "122291", "122293", "122298", "122301", "122303", "122304", "122306", "122308", "122309", "122311", "122312", "122314", "122316", "122317", "122319", "122320", "122321", "122325", "122327", "122328", "122329", "122330", "122332", "122337", "122338", "122339", "122340", "122341", "122343", "122344", "122345", "122348", "122350", "122351", "122352", "122354", "122356", "122357", "122358", "122359", "122360", "122361", "122368", "122371", "122372", "122374", "122375", "122377", "122382", "122388", "122391", "122393", "122399", "122400", "122403", "122408", "122409", "122410", "122412", "122414", "122415", "122416", "122418", "122426", "122429", "122432", "122434", "122435", "122436", "122437", "122440", "122442", "122443", "122444", "122445", "122446", "122449", "122451", "122456", "122457", "122458", "122459", "122460", "122462", "122466", "122467", "122469", "122471", "122472", "122474", "122475", "122476", "122480", "122486", "122487", "122488", "122490", "122492", "122495", "122502", "122503", "122505", "122506", "122511", "122512", "122519", "122520", "122521", "122522", "122523", "122525", "122529", "122531", "122532", "122535", "122538", "122540", "122542", "122549", "122551", "122552", "122555", "122556", "122559", "122561", "122562", "122563", "122564", "122569", "122571", "122574", "122575", "122576", "122580", "122582", "122585", "122586", "122587", "122589", "122591", "122592", "122593", "122595", "122596", "122598", "122600", "122601", "122602", "122605", "122607", "122608", "122612", "122613", "122614", "122618", "122620", "122622", "122623", "122625", "122626", "122628", "122629", "122635", "122637", "122639", "122644", "122653", "122654", "122660", "122663", "122667", "122668", "122670", "122671", "122672", "122673", "122675", "122677", "122679", "122680", "122682", "122683", "122685", "122686", "122687", "122688", "122690", "122691", "122692", "122693", "122695", "122696", "122700", "122704", "122707", "122709", "122710", "122715", "122716", "122721", "122723", "122725", "122727", "122728", "122730", "122735", "122736", "122737", "122738", "122739", "122740", "122741", "122742", "122744", "122745", "122749", "122751", "122752", "122754", "122755", "122758", "122762", "122764", "122766", "122768", "122769", "122770", "122772", "122776", "122778", "122780", "122781", "122782", "122783", "122784", "122785", "122786", "122787", "122794", "122795", "122798", "122799", "122800", "122802", "122803", "122804", "122805", "122807", "122808", "122809", "122814", "122816", "122818", "122819", "122820", "122821", "122827", "122830", "122831", "122832", "122833", "122836", "122837", "122841", "122847", "122848", "122849", "122850", "122851", "122854", "122856", "122861", "122865", "122867", "122868", "122869", "122872", "122874", "122875", "122877", "122878", "122879", "122880", "122881", "122883", "122885", "122886", "122888", "122890", "122892", "122893", "122894", "122898", "122899", "122902", "122904", "122907", "122908", "122910", "122912", "122914", "122916", "122918", "122919", "122920", "122923", "122925", "122927", "122928", "122930", "122932", "122933", "122936", "122940", "122944", "122945", "122948", "122949", "122950", "122951", "122953", "122959", "122962", "122963", "122964", "122965", "122966", "122969", "122972", "122975", "122976", "122977", "122980", "122982", "122986", "122988", "122992", "122994", "122998", "122999", "123000", "123001", "123004", "123006", "123007", "123008", "123009", "123011", "123012", "123015", "123016", "123018", "123019", "123021", "123022", "123023", "123024", "123025", "123029", "123031", "123033", "123035", "123038", "123039", "123040", "123044", "123045", "123047", "123049", "123050", "123051", "123054", "123056", "123058", "123059", "123060", "123062", "123067", "123069", "123070", "123071", "123072", "123079", "123080", "123081", "123082", "123083", "123084", "123085", "123087", "123091", "123095", "123096", "123098", "123099", "123100", "123101", "123102", "123103", "123104", "123105", "123110", "123112", "123113", "123114", "123115", "123116", "123117", "123126", "123127", "123128", "123129", "123131", "123133", "123137", "123138", "123139", "123140", "123142", "123143", "123145", "123147", "123150", "123151", "123154", "123155", "123156", "123159", "123162", "123163", "123164", "123166", "123167", "123168", "123169", "123173", "123174", "123175", "123176", "123177", "123182", "123185", "123186", "123188", "123189", "123190", "123192", "123193", "123194", "123197", "123198", "123200", "123202", "123203", "123204", "123207", "123209", "123210", "123211", "123212", "123213", "123217", "123218", "123219", "123220", "123221", "123222", "123228", "123231", "123232", "123233", "123234", "123235", "123236", "123237", "123243", "123246", "123249", "123250", "123251", "123252", "123253", "123260", "123263", "123264", "123265", "123266", "123267", "123270", "123271", "123273", "123276", "123277", "123278", "123281", "123286", "123288", "123289", "123290", "123295", "123296", "123297", "123298", "123299", "123303", "123305", "123306", "123307", "123309", "123311", "123314", "123315", "123316", "123320", "123321", "123323", "123325", "123328", "123331", "123332", "123335", "123338", "123339", "123340", "123342", "123343", "123348", "123349", "123350", "123351", "123352", "123354", "123355", "123357", "123361", "123365", "123366", "123367", "123369", "123370", "123371", "123372", "123373", "123374", "123375", "123378", "123380", "123381", "123382", "123385", "123388", "123390", "123391", "123392", "123394", "123401", "123402", "123403", "123404", "123405", "123407", "123409", "123411", "123413", "123416", "123417", "123418", "123419", "123422", "123423", "123425", "123426", "123429", "123430", "123431", "123432", "123433", "123435", "123436", "123437", "123438", "123439", "123440", "123441", "123442", "123444", "123445", "123446", "123447", "123450", "123452", "123454", "123456", "123458", "123460", "123463", "123467", "123470", "123471", "123475", "123479", "123481", "123483", "123484", "123485", "123486", "123490", "123492", "123493", "123494", "123496", "123497", "123498", "123499", "123501", "123502", "123503", "123506", "123508", "123511", "123514", "123516", "123517", "123521", "123522", "123525", "123527", "123530", "123536", "123540", "123544", "123545", "123547", "123550", "123551", "123553", "123555", "123556", "123557", "123558", "123559", "123560", "123561", "123563", "123565", "123568", "123570", "123573", "123574", "123577", "123580", "123581", "123586", "123590", "123591", "123592", "123593", "123594", "123595", "123596", "123597", "123598", "123602", "123606", "123607", "123608", "123611", "123617", "123619", "123620", "123623", "123624", "123625", "123626", "123627", "123630", "123631", "123632", "123634", "123635", "123637", "123639", "123640", "123642", "123643", "123644", "123645", "123647", "123648", "123651", "123654", "123655", "123656", "123659", "123660", "123661", "123663", "123668", "123669", "123670", "123672", "123675", "123676", "123677", "123678", "123680", "123681", "123684", "123688", "123690", "123697", "123699", "123701", "123702", "123704", "123705", "123707", "123710", "123711", "123712", "123713", "123715", "123717", "123718", "123720", "123721", "123722", "123723", "123724", "123725", "123727", "123728", "123729", "123732", "123734", "123735", "123736", "123737", "123738", "123741", "123742", "123743", "123746", "123749", "123754", "123756", "123757", "123758", "123760", "123761", "123763", "123764", "123765", "123767", "123768", "123769", "123770", "123771", "123775", "123776", "123778", "123784", "123785", "123786", "123790", "123791", "123792", "123793", "123794", "123799", "123800", "123804", "123806", "123812", "123814", "123815", "123816", "123817", "123818", "123822", "123824", "123825", "123827", "123832", "123833", "123834", "123837", "123838", "123840", "123841", "123842", "123843", "123847", "123849", "123850", "123851", "123856", "123857", "123859", "123860", "123861", "123866", "123868", "123872", "123874", "123875", "123876", "123877", "123878", "123879", "123881", "123884", "123887", "123888", "123889", "123892", "123893", "123894", "123896", "123899", "123900", "123902", "123903", "123904", "123905", "123906", "123909", "123911", "123914", "123916", "123917", "123918", "123920", "123921", "123922", "123923", "123929", "123936", "123940", "123947", "123956", "123957", "123958", "123959", "123961", "123962", "123963", "123969", "123970", "123975", "123977", "123978", "123980", "123981", "123982", "123986", "123987", "123988", "123990", "123992", "123993", "123996", "123997", "123999", "124000", "124001", "124002", "124003", "124005", "124010", "124013", "124014", "124015", "124017", "124018", "124020", "124025", "124026", "124029", "124032", "124033", "124035", "124037", "124038", "124043", "124045", "124048", "124049", "124050", "124051", "124054", "124055", "124056", "124058", "124063", "124065", "124066", "124067", "124069", "124070", "124072", "124076", "124078", "124082", "124083", "124084", "124085", "124087", "124088", "124090", "124093", "124094", "124100", "124102", "124105", "124112", "124114", "124115", "124117", "124118", "124119", "124120", "124122", "124123", "124124", "124125", "124129", "124130", "124132", "124133", "124137", "124139", "124142", "124143", "124144", "124147", "124151", "124154", "124156", "124157", "124163", "124164", "124166", "124167", "124168", "124169", "124171", "124173", "124174", "124175", "124176", "124177", "124179", "124183", "124184", "124185", "124186", "124187", "124189", "124193", "124194", "124195", "124196", "124198", "124200", "124201", "124204", "124207", "124209", "124211", "124215", "124218", "124223", "124225", "124226", "124227", "124228", "124230", "124231", "124232", "124233", "124235", "124236", "124237", "124239", "124241", "124243", "124244", "124249", "124250", "124251", "124252", "124253", "124255", "124263", "124264", "124265", "124266", "124268", "124269", "124271", "124272", "124274", "124277", "124278", "124283", "124284", "124285", "124286", "124287", "124289", "124291", "124292", "124294", "124298", "124300", "124301", "124304", "124306", "124309", "124310", "124312", "124313", "124315", "124318", "124320", "124321", "124323", "124324", "124325", "124326", "124327", "124328", "124329", "124330", "124332", "124333", "124335", "124336", "124341", "124343", "124345", "124347", "124351", "124353", "124354", "124356", "124357", "124358", "124359", "124364", "124365", "124366", "124367", "124368", "124370", "124371", "124372", "124375", "124376", "124377", "124378", "124379", "124380", "124382", "124383", "124385", "124386", "124387", "124389", "124391", "124393", "124396", "124397", "124398", "124399", "124400", "124401", "124402", "124404", "124408", "124409", "124411", "124412", "124413", "124414", "124415", "124416", "124418", "124420", "124422", "124423", "124426", "124428", "124429", "124430", "124431", "124432", "124433", "124436", "124437", "124446", "124447", "124449", "124454", "124456", "124458", "124459", "124460", "124462", "124463", "124464", "124468", "124469", "124475", "124478", "124479", "124481", "124482", "124487", "124488", "124490", "124491", "124492", "124493", "124494", "124496", "124497", "124498", "124499", "124501", "124504", "124505", "124507", "124509", "124510", "124512", "124514", "124515", "124516", "124518", "124519", "124520", "124526", "124527", "124530", "124531", "124534", "124535", "124536", "124537", "124540", "124541", "124547", "124548", "124549", "124550", "124553", "124557", "124559", "124562", "124565", "124569", "124570", "124571", "124573", "124574", "124576", "124579", "124581", "124583", "124585", "124586", "124587", "124590", "124591", "124592", "124593", "124595", "124597", "124599", "124600", "124601", "124602", "124605", "124606", "124607", "124608", "124609", "124613", "124614", "124615", "124616", "124617", "124618", "124619", "124622", "124625", "124628", "124630", "124631", "124634", "124635", "124637", "124640", "124644", "124646", "124655", "124656", "124660", "124661", "124665", "124666", "124668", "124669", "124670", "124673", "124674", "124675", "124676", "124678", "124679", "124681", "124683", "124689", "124690", "124697", "124698", "124700", "124701", "124704", "124705", "124707", "124708", "124709", "124711", "124712", "124718", "124721", "124730", "124731", "124732", "124733", "124735", "124737", "124738", "124741", "124742", "124743", "124744", "124745", "124746", "124748", "124749", "124751", "124752", "124753", "124754", "124756", "124757", "124758", "124759", "124761", "124762", "124763", "124768", "124769", "124771", "124774", "124775", "124777", "124778", "124780", "124781", "124782", "124785", "124792", "124794", "124796", "124797", "124798", "124800", "124801", "124802", "124803", "124804", "124806", "124807", "124809", "124811", "124812", "124816", "124821", "124825", "124826", "124827", "124829", "124831", "124833", "124835", "124837", "124838", "124839", "124840", "124841", "124842", "124843", "124848", "124851", "124853", "124854", "124855", "124858", "124859", "124861", "124866", "124869", "124871", "124872", "124874", "124875", "124879", "124880", "124881", "124882", "124883", "124884", "124885", "124886", "124889", "124890", "124892", "124893", "124896", "124898", "124899", "124900", "124901", "124903", "124904", "124906", "124908", "124909", "124911", "124912", "124913", "124919", "124920", "124921", "124925", "124927", "124929", "124930", "124931", "124933", "124934", "124936", "124938", "124939", "124940", "124941", "124942", "124943", "124945", "124946", "124948", "124950", "124953", "124954", "124956", "124959", "124960", "124962", "124965", "124968", "124969", "124972", "124975", "124976", "124978", "124981", "124983", "124984", "124985", "124988", "124989", "124990", "124992", "124994", "124995", "124998", "125001", "125002", "125003", "125005", "125007", "125009", "125010", "125012", "125014", "125015", "125019", "125020", "125021", "125023", "125024", "125026", "125027", "125031", "125034", "125035", "125038", "125039", "125040", "125042", "125043", "125046", "125048", "125050", "125051", "125053", "125061", "125062", "125063", "125064", "125069", "125073", "125076", "125077", "125078", "125081", "125083", "125084", "125085", "125086", "125087", "125089", "125090", "125091", "125092", "125093", "125095", "125096", "125098", "125099", "125100", "125103", "125104", "125107", "125108", "125110", "125112", "125113", "125116", "125117", "125119", "125120", "125121", "125122", "125123", "125126", "125127", "125129", "125130", "125132", "125133", "125134", "125136", "125139", "125141", "125142", "125144", "125145", "125147", "125148", "125149", "125151", "125152", "125154", "125156", "125157", "125158", "125162", "125163", "125165", "125171", "125172", "125176", "125177", "125180", "125184", "125185", "125186", "125187", "125189", "125194", "125195", "125196", "125200", "125201", "125203", "125204", "125206", "125207", "125210", "125212", "125213", "125214", "125215", "125216", "125217", "125221", "125226", "125233", "125234", "125235", "125236", "125237", "125239", "125240", "125241", "125242", "125245", "125246", "125247", "125249", "125252", "125253", "125256", "125257", "125258", "125260", "125261", "125264", "125265", "125266", "125267", "125269", "125270", "125272", "125273", "125275", "125276", "125278", "125279", "125280", "125284", "125287", "125289", "125293", "125294", "125300", "125301", "125308", "125309", "125310", "125311", "125316", "125317", "125318", "125321", "125326", "125327", "125330", "125331", "125333", "125334", "125335", "125336", "125337", "125339", "125340", "125341", "125343", "125347", "125350", "125351", "125353", "125359", "125361", "125365", "125371", "125374", "125375", "125377", "125379", "125380", "125382", "125384", "125386", "125387", "125389", "125390", "125393", "125397", "125399", "125402", "125403", "125404", "125406", "125407", "125408", "125416", "125421", "125422", "125427", "125428", "125429", "125438", "125440", "125441", "125443", "125444", "125445", "125446", "125447", "125448", "125452", "125455", "125456", "125457", "125458", "125463", "125465", "125466", "125469", "125472", "125479", "125482", "125483", "125484", "125485", "125487", "125490", "125491", "125492", "125493", "125494", "125495", "125496", "125497", "125499", "125501", "125502", "125504", "125505", "125507", "125510", "125515", "125516", "125518", "125520", "125522", "125523", "125524", "125525", "125527", "125528", "125530", "125531", "125534", "125536", "125537", "125538", "125539", "125540", "125541", "125543", "125548", "125549", "125552", "125555", "125556", "125559", "125560", "125562", "125567", "125568", "125570", "125571", "125574", "125575", "125577", "125580", "125583", "125584", "125585", "125586", "125592", "125595", "125596", "125600", "125603", "125607", "125611", "125612", "125613", "125614", "125615", "125616", "125618", "125620", "125624", "125628", "125630", "125631", "125632", "125634", "125635", "125636", "125641", "125645", "125647", "125648", "125649", "125651", "125653", "125655", "125656", "125658", "125662", "125665", "125667", "125669", "125670", "125674", "125676", "125677", "125679", "125681", "125682", "125685", "125686", "125688", "125691", "125692", "125693", "125698", "125699", "125702", "125704", "125705", "125707", "125708", "125709", "125710", "125713", "125716", "125723", "125724", "125726", "125727", "125728", "125730", "125734", "125735", "125736", "125737", "125738", "125742", "125743", "125744", "125745", "125748", "125750", "125751", "125752", "125754", "125756", "125758", "125759", "125762", "125763", "125764", "125766", "125767", "125770", "125771", "125773", "125776", "125781", "125782", "125787", "125789", "125792", "125793", "125796", "125799", "125801", "125804", "125807", "125810", "125812", "125813", "125818", "125819", "125820", "125821", "125822", "125823", "125827", "125829", "125830", "125832", "125834", "125835", "125838", "125840", "125846", "125849", "125850", "125852", "125853", "125854", "125857", "125859", "125861", "125862", "125864", "125865", "125869", "125872", "125874", "125875", "125879", "125881", "125883", "125885", "125886", "125889", "125891", "125892", "125894", "125897", "125899", "125902", "125903", "125906", "125909", "125911", "125913", "125914", "125915", "125918", "125919", "125920", "125922", "125924", "125928", "125934", "125935", "125936", "125937", "125939", "125943", "125945", "125946", "125947", "125948", "125951", "125952", "125954", "125957", "125958", "125959", "125960", "125964", "125966", "125967", "125971", "125972", "125973", "125974", "125975", "125976", "125977", "125979", "125981", "125983", "125987", "125990", "125991", "125996", "125997", "125999", "126000", "126006", "126007", "126014", "126015", "126022", "126023", "126024", "126025", "126026", "126027", "126031", "126032", "126035", "126037", "126038", "126040", "126041", "126042", "126043", "126045", "126050", "126051", "126052", "126055", "126056", "126060", "126061", "126062", "126063", "126065", "126067", "126068", "126069", "126070", "126071", "126072", "126074", "126075", "126077", "126083", "126087", "126091", "126093", "126094", "126095", "126098", "126099", "126101", "126103", "126105", "126106", "126108", "126109", "126110", "126111", "126112", "126114", "126115", "126117", "126119", "126121", "126126", "126129", "126130", "126131", "126132", "126134", "126138", "126140", "126142", "126143", "126146", "126148", "126149", "126152", "126155", "126156", "126157", "126159", "126161", "126167", "126170", "126171", "126173", "126175", "126176", "126177", "126180", "126183", "126187", "126188", "126189", "126192", "126193", "126197", "126199", "126200", "126201", "126202", "126204", "126205", "126208", "126211", "126212", "126214", "126216", "126217", "126218", "126219", "126221", "126222", "126223", "126224", "126225", "126227", "126228", "126229", "126231", "126233", "126234", "126235", "126236", "126240", "126241", "126242", "126244", "126245", "126246", "126248", "126249", "126250", "126252", "126253", "126254", "126255", "126257", "126260", "126263", "126264", "126266", "126267", "126268", "126269", "126272", "126273", "126274", "126276", "126277", "126281", "126282", "126286", "126287", "126290", "126292", "126293", "126294", "126297", "126298", "126299", "126301", "126304", "126305", "126307", "126308", "126309", "126310", "126313", "126314", "126317", "126320", "126321", "126326", "126328", "126329", "126331", "126336", "126347", "126348", "126351", "126352", "126354", "126355", "126356", "126357", "126358", "126360", "126361", "126362", "126365", "126366", "126368", "126369", "126373", "126374", "126375", "126378", "126379", "126380", "126381", "126382", "126385", "126387", "126388", "126391", "126394", "126399", "126400", "126403", "126405", "126406", "126408", "126411", "126413", "126415", "126416", "126423", "126425", "126426", "126433", "126434", "126437", "126438", "126439", "126442", "126443", "126446", "126447", "126448", "126449", "126451", "126455", "126456", "126457", "126460", "126462", "126463", "126464", "126466", "126467", "126470", "126471", "126472", "126473", "126475", "126476", "126479", "126480", "126481", "126482", "126483", "126484", "126485", "126486", "126487", "126491", "126492", "126493", "126495", "126496", "126497", "126498", "126500", "126501", "126503", "126507", "126511", "126515", "126516", "126518", "126519", "126521", "126522", "126525", "126527", "126532", "126533", "126538", "126544", "126545", "126548", "126549", "126551", "126553", "126554", "126557", "126558", "126559", "126562", "126564", "126567", "126569", "126570", "126572", "126573", "126574", "126580", "126581", "126582", "126583", "126586", "126588", "126591", "126592", "126594", "126595", "126596", "126599", "126600", "126605", "126608", "126609", "126611", "126612", "126613", "126614", "126616", "126618", "126619", "126620", "126621", "126624", "126625", "126626", "126629", "126630", "126632", "126636", "126638", "126639", "126641", "126642", "126643", "126644", "126645", "126648", "126649", "126651", "126652", "126653", "126654", "126658", "126659", "126661", "126665", "126668", "126671", "126672", "126675", "126678", "126679", "126681", "126682", "126683", "126684", "126685", "126686", "126689", "126690", "126691", "126692", "126693", "126695", "126696", "126698", "126699", "126705", "126706", "126707", "126710", "126711", "126713", "126714", "126717", "126718", "126720", "126724", "126725", "126726", "126727", "126728", "126729", "126731", "126732", "126736", "126737", "126738", "126739", "126740", "126742", "126745", "126746", "126747", "126748", "126751", "126752", "126755", "126756", "126758", "126762", "126765", "126767", "126772", "126773", "126775", "126776", "126778", "126779", "126781", "126783", "126785", "126786", "126787", "126789", "126791", "126792", "126794", "126795", "126798", "126799", "126801", "126804", "126806", "126808", "126811", "126814", "126815", "126816", "126818", "126819", "126821", "126822", "126824", "126825", "126826", "126827", "126828", "126829", "126831", "126835", "126836", "126839", "126841", "126843", "126844", "126845", "126849", "126850", "126851", "126855", "126856", "126859", "126861", "126865", "126869", "126870", "126876", "126879", "126882", "126883", "126884", "126886", "126887", "126889", "126890", "126893", "126895", "126897", "126898", "126899", "126901", "126905", "126908", "126909", "126912", "126914", "126915", "126916", "126918", "126919", "126920", "126921", "126922", "126923", "126926", "126927", "126928", "126930", "126932", "126933", "126935", "126936", "126938", "126939", "126943", "126945", "126947", "126949", "126950", "126951", "126952", "126953", "126956", "126957", "126958", "126964", "126965", "126974", "126976", "126980", "126981", "126982", "126988", "126989", "126991", "126992", "126996", "126997", "126999", "127001", "127002", "127003", "127004", "127006", "127007", "127015", "127016", "127017", "127021", "127023", "127024", "127025", "127029", "127032", "127038", "127041", "127043", "127044", "127047", "127048", "127051", "127052", "127053", "127056", "127059", "127061", "127066", "127067", "127069", "127070", "127075", "127083", "127084", "127085", "127086", "127087", "127088", "127089", "127090", "127091", "127092", "127094", "127097", "127098", "127099", "127100", "127101", "127102", "127103", "127104", "127113", "127116", "127117", "127118", "127121", "127122", "127124", "127125", "127126", "127127", "127128", "127132", "127133", "127137", "127139", "127144", "127148", "127149", "127151", "127153", "127154", "127155", "127157", "127158", "127160", "127163", "127164", "127166", "127167", "127168", "127169", "127172", "127173", "127176", "127177", "127179", "127180", "127181", "127182", "127186", "127188", "127189", "127193", "127194", "127197", "127199", "127202", "127203", "127207", "127208", "127211", "127213", "127216", "127217", "127219", "127220", "127221", "127222", "127223", "127225", "127226", "127227", "127230", "127232", "127233", "127234", "127237", "127242", "127243", "127244", "127245", "127246", "127247", "127249", "127250", "127254", "127255", "127256", "127258", "127259", "127260", "127263", "127264", "127266", "127268", "127269", "127270", "127271", "127278", "127279", "127280", "127282", "127283", "127289", "127292", "127294", "127297", "127301", "127302", "127309", "127317", "127319", "127322", "127323", "127326", "127330", "127331", "127332", "127334", "127337", "127338", "127339", "127340", "127350", "127355", "127356", "127357", "127358", "127361", "127362", "127363", "127364", "127365", "127366", "127369", "127370", "127375", "127376", "127377", "127381", "127384", "127385", "127388", "127389", "127392", "127393", "127394", "127395", "127397", "127402", "127407", "127408", "127410", "127418", "127419", "127422", "127424", "127425", "127426", "127429", "127431", "127433", "127435", "127437", "127440", "127441", "127445", "127446", "127447", "127453", "127454", "127455", "127456", "127460", "127464", "127465", "127467", "127469", "127470", "127471", "127472", "127473", "127474", "127476", "127477", "127479", "127481", "127482", "127483", "127484", "127485", "127486", "127487", "127488", "127494", "127497", "127498", "127499", "127501", "127502", "127503", "127506", "127507", "127508", "127509", "127510", "127515", "127517", "127518", "127519", "127520", "127521", "127526", "127528", "127535", "127536", "127537", "127539", "127543", "127544", "127546", "127547", "127550", "127552", "127554", "127555", "127557", "127558", "127559", "127560", "127562", "127566", "127570", "127571", "127572", "127573", "127575", "127576", "127584", "127585", "127586", "127587", "127589", "127594", "127597", "127599", "127600", "127602", "127603", "127605", "127606", "127611", "127612", "127613", "127615", "127616", "127618", "127619", "127621", "127625", "127626", "127627", "127628", "127631", "127633", "127635", "127637", "127639", "127643", "127644", "127645", "127648", "127650", "127658", "127659", "127661", "127664", "127667", "127668", "127669", "127671", "127672", "127674", "127675", "127678", "127679", "127680", "127681", "127685", "127687", "127688", "127689", "127690", "127691", "127692", "127694", "127696", "127697", "127699", "127701", "127704", "127710", "127713", "127715", "127717", "127718", "127719", "127720", "127721", "127724", "127726", "127727", "127728", "127729", "127734", "127736", "127737", "127738", "127739", "127740", "127741", "127742", "127743", "127745", "127746", "127748", "127749", "127753", "127755", "127756", "127764", "127767", "127769", "127772", "127777", "127779", "127783", "127784", "127785", "127786", "127788", "127791", "127794", "127796", "127797", "127798", "127802", "127803", "127804", "127809", "127811", "127813", "127815", "127816", "127818", "127819", "127820", "127824", "127825", "127826", "127827", "127828", "127829", "127830", "127831", "127832", "127833", "127835", "127836", "127838", "127839", "127841", "127844", "127845", "127848", "127849", "127850", "127853", "127854", "127857", "127858", "127863", "127864", "127871", "127872", "127874", "127876", "127878", "127881", "127883", "127891", "127892", "127894", "127895", "127897", "127898", "127899", "127901", "127902", "127904", "127906", "127907", "127908", "127910", "127912", "127913", "127914", "127920", "127921", "127922", "127924", "127925", "127928", "127930", "127932", "127933", "127934", "127935", "127936", "127937", "127938", "127942", "127944", "127945", "127946", "127947", "127950", "127952", "127954", "127955", "127956", "127957", "127959", "127960", "127961", "127962", "127963", "127966", "127969", "127971", "127972", "127975", "127978", "127983", "127987", "127989", "127990", "127992", "127993", "127995", "127997", "127998", "128001", "128008", "128009", "128011", "128013", "128019", "128021", "128023", "128025", "128026", "128027", "128028", "128030", "128031", "128033", "128034", "128035", "128036", "128038", "128039", "128042", "128044", "128045", "128047", "128051", "128054", "128055", "128057", "128062", "128068", "128073", "128074", "128077", "128078", "128083", "128086", "128087", "128088", "128090", "128092", "128093", "128094", "128097", "128098", "128099", "128100", "128101", "128102", "128104", "128106", "128107", "128110", "128111", "128112", "128113", "128114", "128117", "128118", "128119", "128120", "128123", "128124", "128125", "128128", "128129", "128131", "128132", "128134", "128135", "128136", "128139", "128140", "128142", "128143", "128145", "128146", "128149", "128150", "128151", "128152", "128153", "128154", "128155", "128158", "128160", "128161", "128162", "128165", "128166", "128167", "128169", "128170", "128172", "128174", "128175", "128176", "128177", "128178", "128184", "128186", "128188", "128190", "128192", "128193", "128196", "128197", "128199", "128202", "128204", "128207", "128209", "128210", "128216", "128217", "128219", "128220", "128222", "128223", "128228", "128229", "128230", "128231", "128232", "128234", "128236", "128237", "128239", "128241", "128242", "128244", "128245", "128246", "128247", "128248", "128249", "128251", "128254", "128255", "128258", "128259", "128260", "128263", "128264", "128265", "128267", "128268", "128270", "128271", "128274", "128275", "128276", "128277", "128280", "128283", "128285", "128286", "128288", "128289", "128290", "128291", "128292", "128294", "128296", "128297", "128300", "128302", "128303", "128304", "128305", "128311", "128314", "128318", "128320", "128323", "128325", "128326", "128328", "128330", "128334", "128335", "128336", "128337", "128339", "128340", "128342", "128343", "128344", "128345", "128347", "128348", "128350", "128352", "128355", "128358", "128359", "128361", "128365", "128367", "128370", "128371", "128373", "128376", "128378", "128380", "128383", "128385", "128387", "128389", "128390", "128392", "128393", "128394", "128396", "128397", "128401", "128402", "128404", "128405", "128409", "128410", "128411", "128413", "128414", "128416", "128417", "128421", "128422", "128428", "128429", "128430", "128433", "128434", "128435", "128436", "128439", "128440", "128441", "128442", "128443", "128446", "128447", "128450", "128451", "128452", "128453", "128457", "128458", "128459", "128460", "128464", "128465", "128466", "128468", "128469", "128470", "128472", "128473", "128475", "128476", "128478", "128480", "128481", "128485", "128487", "128489", "128490", "128491", "128494", "128495", "128497", "128499", "128502", "128503", "128504", "128505", "128509", "128511", "128513", "128515", "128517", "128518", "128520", "128522", "128525", "128530", "128534", "128536", "128537", "128538", "128540", "128543", "128544", "128546", "128549", "128550", "128551", "128552", "128556", "128557", "128558", "128560", "128562", "128563", "128564", "128565", "128566", "128567", "128568", "128571", "128572", "128573", "128575", "128578", "128581", "128584", "128586", "128594", "128595", "128597", "128598", "128602", "128603", "128604", "128612", "128614", "128617", "128619", "128620", "128622", "128623", "128628", "128630", "128632", "128634", "128635", "128636", "128637", "128638", "128639", "128641", "128642", "128644", "128646", "128648", "128649", "128650", "128658", "128660", "128661", "128665", "128666", "128667", "128668", "128670", "128673", "128674", "128675", "128678", "128681", "128683", "128686", "128688", "128689", "128690", "128691", "128692", "128693", "128696", "128697", "128699", "128700", "128701", "128705", "128706", "128707", "128710", "128712", "128713", "128714", "128718", "128721", "128723", "128725", "128726", "128727", "128728", "128731", "128732", "128734", "128735", "128736", "128737", "128738", "128739", "128740", "128742", "128745", "128746", "128747", "128748", "128750", "128751", "128752", "128755", "128756", "128759", "128761", "128763", "128765", "128766", "128768", "128769", "128770", "128772", "128773", "128776", "128779", "128781", "128782", "128784", "128785", "128786", "128787", "128790", "128791", "128793", "128796", "128800", "128801", "128802", "128803", "128805", "128808", "128812", "128816", "128819", "128824", "128825", "128826", "128828", "128830", "128831", "128834", "128837", "128840", "128841", "128842", "128847", "128848", "128849", "128852", "128855", "128856", "128857", "128858", "128859", "128860", "128866", "128867", "128871", "128872", "128873", "128874", "128876", "128879", "128881", "128882", "128885", "128887", "128888", "128891", "128892", "128894", "128898", "128901", "128903", "128906", "128909", "128914", "128915", "128917", "128923", "128925", "128926", "128927", "128928", "128931", "128932", "128935", "128936", "128937", "128940", "128943", "128945", "128950", "128955", "128956", "128958", "128962", "128965", "128966", "128967", "128968", "128971", "128978", "128982", "128984", "128986", "128987", "128990", "128991", "128996", "128997", "129000", "129003", "129004", "129005", "129006", "129007", "129009", "129016", "129018", "129020", "129021", "129022", "129024", "129029", "129031", "129032", "129033", "129034", "129040", "129041", "129044", "129045", "129047", "129050", "129052", "129054", "129055", "129058", "129062", "129064", "129072", "129073", "129074", "129076", "129079", "129080", "129081", "129082", "129083", "129084", "129087", "129091", "129092", "129093", "129094", "129095", "129098", "129099", "129100", "129102", "129106", "129107", "129109", "129111", "129112", "129113", "129114", "129115", "129117", "129118", "129125", "129126", "129129", "129130", "129132", "129133", "129135", "129137", "129140", "129142", "129144", "129145", "129149", "129150", "129151", "129153", "129157", "129158", "129159", "129160", "129161", "129162", "129167", "129169", "129170", "129171", "129173", "129174", "129175", "129177", "129181", "129183", "129184", "129187", "129188", "129191", "129192", "129193", "129194", "129196", "129197", "129199", "129202", "129203", "129204", "129205", "129208", "129212", "129216", "129217", "129218", "129220", "129223", "129225", "129226", "129227", "129230", "129232", "129233", "129235", "129242", "129243", "129245", "129254", "129255", "129256", "129261", "129266", "129267", "129269", "129271", "129273", "129274", "129275", "129276", "129278", "129279", "129283", "129285", "129288", "129289", "129291", "129292", "129293", "129294", "129301", "129303", "129305", "129306", "129308", "129311", "129312", "129316", "129317", "129318", "129320", "129322", "129323", "129325", "129327", "129328", "129332", "129334", "129335", "129336", "129342", "129344", "129345", "129348", "129350", "129356", "129357", "129358", "129360", "129362", "129366", "129369", "129375", "129378", "129380", "129381", "129382", "129383", "129384", "129385", "129386", "129387", "129390", "129391", "129392", "129393", "129395", "129396", "129397", "129398", "129400", "129402", "129403", "129404", "129405", "129406", "129409", "129411", "129413", "129417", "129420", "129424", "129425", "129428", "129431", "129433", "129437", "129442", "129448", "129449", "129455", "129458", "129460", "129461", "129463", "129465", "129467", "129471", "129476", "129477", "129478", "129480", "129481", "129482", "129484", "129486", "129487", "129488", "129489", "129492", "129494", "129496", "129497", "129507", "129512", "129514", "129516", "129518", "129519", "129520", "129523", "129525", "129528", "129529", "129536", "129537", "129538", "129539", "129541", "129542", "129545", "129546", "129547", "129550", "129551", "129552", "129553", "129554", "129555", "129556", "129557", "129558", "129559", "129565", "129566", "129567", "129568", "129570", "129575", "129577", "129579", "129580", "129581", "129582", "129583", "129588", "129589", "129590", "129591", "129593", "129597", "129601", "129602", "129604", "129605", "129606", "129607", "129610", "129616", "129617", "129618", "129619", "129622", "129623", "129625", "129626", "129627", "129628", "129629", "129630", "129632", "129633", "129634", "129636", "129638", "129639", "129643", "129644", "129645", "129647", "129648", "129649", "129650", "129652", "129653", "129656", "129657", "129658", "129659", "129661", "129662", "129664", "129665", "129667", "129669", "129672", "129673", "129675", "129677", "129678", "129680", "129681", "129683", "129685", "129687", "129688", "129689", "129691", "129692", "129693", "129697", "129698", "129699", "129700", "129701", "129703", "129707", "129708", "129710", "129711", "129714", "129721", "129726", "129728", "129729", "129732", "129734", "129736", "129737", "129742", "129743", "129744", "129745", "129749", "129752", "129756", "129758", "129759", "129761", "129763", "129773", "129775", "129777", "129778", "129782", "129783", "129788", "129789", "129792", "129793", "129797", "129799", "129800", "129802", "129803", "129805", "129808", "129811", "129814", "129815", "129816", "129817", "129819", "129822", "129826", "129828", "129829", "129830", "129832", "129834", "129840", "129842", "129844", "129854", "129856", "129858", "129860", "129862", "129863", "129864", "129865", "129866", "129867", "129868", "129869", "129870", "129871", "129872", "129873", "129874", "129878", "129883", "129884", "129888", "129891", "129894", "129896", "129899", "129901", "129903", "129904", "129908", "129909", "129912", "129918", "129919", "129920", "129921", "129922", "129923", "129924", "129925", "129926", "129927", "129929", "129930", "129931", "129932", "129936", "129938", "129939", "129942", "129943", "129945", "129952", "129955", "129956", "129958", "129959", "129961", "129962", "129963", "129967", "129969", "129972", "129973", "129974", "129975", "129976", "129979", "129981", "129982", "129983", "129985", "129987", "129990", "129991", "129995", "129996", "129998", "129999", "130000", "130002", "130004", "130005", "130009", "130014", "130015", "130018", "130019", "130020", "130022", "130024", "130029", "130031", "130034", "130035", "130036", "130037", "130039", "130040", "130041", "130042", "130043", "130044", "130045", "130046", "130051", "130052", "130059", "130060", "130064", "130066", "130067", "130069", "130070", "130071", "130072", "130075", "130079", "130080", "130084", "130087", "130088", "130090", "130094", "130099", "130100", "130101", "130103", "130105", "130106", "130109", "130111", "130114", "130115", "130117", "130119", "130120", "130121", "130122", "130123", "130124", "130126", "130131", "130132", "130133", "130135", "130137", "130141", "130142", "130144", "130146", "130147", "130149", "130150", "130151", "130153", "130156", "130160", "130161", "130163", "130164", "130166", "130169", "130170", "130171", "130175", "130176", "130185", "130186", "130189", "130191", "130193", "130194", "130195", "130197", "130198", "130206", "130207", "130212", "130214", "130217", "130218", "130219", "130220", "130222", "130223", "130224", "130225", "130226", "130228", "130231", "130232", "130233", "130234", "130235", "130238", "130241", "130242", "130250", "130255", "130256", "130257", "130260", "130263", "130264", "130265", "130266", "130268", "130273", "130274", "130276", "130277", "130280", "130281", "130283", "130284", "130285", "130288", "130289", "130290", "130292", "130293", "130295", "130299", "130300", "130303", "130305", "130306", "130308", "130310", "130312", "130313", "130314", "130315", "130317", "130322", "130323", "130325", "130326", "130329", "130330", "130332", "130333", "130336", "130339", "130340", "130341", "130342", "130343", "130344", "130349", "130353", "130356", "130358", "130359", "130364", "130366", "130367", "130368", "130371", "130372", "130375", "130376", "130378", "130381", "130382", "130383", "130386", "130387", "130390", "130391", "130398", "130400", "130402", "130406", "130407", "130408", "130409", "130410", "130412", "130413", "130415", "130416", "130417", "130422", "130424", "130427", "130428", "130431", "130432", "130433", "130434", "130435", "130436", "130437", "130440", "130441", "130443", "130444", "130445", "130446", "130447", "130452", "130454", "130455", "130457", "130459", "130460", "130462", "130463", "130467", "130468", "130470", "130473", "130474", "130476", "130477", "130479", "130481", "130482", "130484", "130485", "130491", "130492", "130494", "130496", "130504", "130505", "130506", "130508", "130509", "130514", "130516", "130517", "130519", "130524", "130525", "130526", "130529", "130530", "130536", "130537", "130541", "130543", "130546", "130547", "130548", "130549", "130553", "130554", "130558", "130560", "130568", "130569", "130570", "130572", "130573", "130575", "130576", "130581", "130583", "130584", "130585", "130586", "130588", "130591", "130592", "130596", "130597", "130598", "130599", "130602", "130608", "130612", "130613", "130618", "130620", "130624", "130625", "130626", "130627", "130632", "130633", "130634", "130637", "130641", "130642", "130643", "130646", "130647", "130649", "130650", "130651", "130652", "130653", "130654", "130655", "130659", "130660", "130661", "130664", "130666", "130667", "130669", "130671", "130674", "130675", "130677", "130678", "130680", "130681", "130685", "130688", "130689", "130694", "130696", "130698", "130702", "130703", "130705", "130706", "130707", "130708", "130712", "130715", "130718", "130722", "130725", "130726", "130727", "130729", "130731", "130732", "130733", "130734", "130735", "130736", "130740", "130741", "130742", "130744", "130745", "130748", "130749", "130750", "130753", "130754", "130758", "130759", "130764", "130768", "130770", "130772", "130774", "130776", "130779", "130781", "130783", "130784", "130787", "130788", "130789", "130791", "130792", "130793", "130794", "130796", "130797", "130798", "130801", "130802", "130803", "130804", "130805", "130806", "130807", "130808", "130809", "130810", "130811", "130813", "130814", "130815", "130816", "130820", "130821", "130823", "130824", "130827", "130828", "130831", "130832", "130834", "130842", "130844", "130845", "130846", "130849", "130852", "130855", "130858", "130862", "130864", "130865", "130869", "130870", "130873", "130875", "130877", "130878", "130880", "130883", "130886", "130887", "130888", "130889", "130890", "130891", "130893", "130894", "130896", "130897", "130898", "130900", "130901", "130902", "130903", "130906", "130908", "130911", "130912", "130914", "130915", "130916", "130918", "130919", "130920", "130921", "130923", "130924", "130926", "130929", "130931", "130932", "130933", "130934", "130937", "130938", "130940", "130941", "130942", "130943", "130948", "130949", "130950", "130954", "130955", "130956", "130958", "130959", "130960", "130966", "130968", "130970", "130972", "130973", "130974", "130975", "130976", "130977", "130979", "130980", "130982", "130983", "130984", "130986", "130987", "130989", "130995", "130998", "130999", "131001", "131003", "131005", "131009", "131010", "131012", "131014", "131016", "131018", "131019", "131023", "131026", "131028", "131030", "131031", "131032", "131033", "131034", "131035", "131037", "131038", "131039", "131040", "131048", "131049", "131050", "131051", "131052", "131053", "131054", "131055", "131059", "131060", "131064", "131065", "131068", "131069", "131070", "131071", "131074", "131076", "131077", "131079", "131080", "131081", "131085", "131086", "131087", "131088", "131089", "131090", "131092", "131094", "131096", "131097", "131100", "131101", "131102", "131103", "131104", "131105", "131106", "131108", "131110", "131112", "131114", "131119", "131122", "131126", "131127", "131131", "131133", "131134", "131143", "131145", "131146", "131148", "131150", "131152", "131156", "131157", "131159", "131160", "131161", "131162", "131164", "131169", "131171", "131172", "131174", "131175", "131176", "131177", "131180", "131181", "131184", "131186", "131187", "131195", "131196", "131200", "131202", "131205", "131206", "131208", "131210", "131211", "131214", "131216", "131218", "131220", "131221", "131222", "131224", "131225", "131227", "131229", "131230", "131231", "131232", "131238", "131241", "131244", "131245", "131246", "131247", "131250", "131255", "131260", "131262", "131263", "131264", "131267", "131268", "131269", "131270", "131276", "131278", "131279", "131283", "131284", "131286", "131290", "131291", "131292", "131294", "131295", "131296", "131300", "131301", "131302", "131303", "131306", "131308", "131309", "131310", "131311", "131312", "131313", "131314", "131317", "131320", "131321", "131322", "131323", "131324", "131325", "131326", "131328", "131332", "131333", "131341", "131343", "131348", "131352", "131354", "131356", "131357", "131365", "131366", "131370", "131372", "131375", "131377", "131379", "131380", "131382", "131383", "131384", "131385", "131387", "131388", "131389", "131390", "131392", "131393", "131394", "131395", "131396", "131398", "131402", "131404", "131405", "131407", "131408", "131411", "131418", "131419", "131420", "131422", "131424", "131428", "131429", "131433", "131436", "131438", "131439", "131441", "131443", "131449", "131451", "131454", "131455", "131459", "131461", "131462", "131464", "131467", "131471", "131473", "131474", "131475", "131476", "131482", "131483", "131487", "131488", "131489", "131491", "131493", "131494", "131499", "131500", "131503", "131505", "131507", "131512", "131513", "131514", "131515", "131516", "131518", "131519", "131520", "131521", "131524", "131526", "131529", "131530", "131534", "131537", "131538", "131540", "131542", "131543", "131544", "131545", "131547", "131548", "131551", "131553", "131555", "131556", "131559", "131561", "131562", "131563", "131564", "131565", "131566", "131567", "131568", "131569", "131576", "131577", "131580", "131582", "131583", "131584", "131585", "131586", "131588", "131589", "131590", "131594", "131596", "131597", "131599", "131600", "131601", "131607", "131608", "131610", "131615", "131617", "131618", "131621", "131622", "131623", "131625", "131628", "131629", "131630", "131631", "131634", "131636", "131638", "131639", "131641", "131642", "131643", "131644", "131645", "131646", "131649", "131651", "131652", "131654", "131655", "131656", "131658", "131660", "131661", "131665", "131667", "131668", "131669", "131672", "131673", "131675", "131676", "131679", "131680", "131681", "131685", "131689", "131690", "131692", "131695", "131697", "131699", "131700", "131703", "131705", "131708", "131710", "131712", "131713", "131716", "131717", "131720", "131722", "131723", "131724", "131726", "131727", "131730", "131739", "131741", "131743", "131745", "131747", "131748", "131749", "131752", "131755", "131757", "131759", "131764", "131771", "131775", "131776", "131778", "131780", "131781", "131782", "131784", "131785", "131786", "131787", "131788", "131794", "131796", "131800", "131801", "131803", "131807", "131808", "131810", "131811", "131814", "131815", "131818", "131819", "131822", "131823", "131824", "131827", "131829", "131837", "131838", "131839", "131840", "131844", "131845", "131848", "131852", "131853", "131854", "131856", "131857", "131858", "131859", "131861", "131862", "131869", "131870", "131872", "131874", "131877", "131881", "131882", "131885", "131889", "131890", "131892", "131896", "131899", "131900", "131901", "131902", "131903", "131906", "131910", "131911", "131912", "131914", "131919", "131922", "131925", "131930", "131934", "131935", "131936", "131938", "131942", "131943", "131945", "131947", "131949", "131950", "131952", "131953", "131954", "131955", "131956", "131959", "131960", "131964", "131965", "131966", "131967", "131968", "131973", "131975", "131976", "131977", "131979", "131980", "131983", "131984", "131985", "131990", "131999", "132001", "132003", "132007", "132008", "132009", "132012", "132013", "132014", "132015", "132017", "132019", "132020", "132022", "132030", "132033", "132035", "132036", "132038", "132040", "132041", "132043", "132044", "132045", "132048", "132052", "132056", "132057", "132058", "132060", "132062", "132066", "132068", "132069", "132074", "132076", "132078", "132079", "132080", "132082", "132084", "132085", "132087", "132089", "132091", "132094", "132095", "132096", "132098", "132099", "132101", "132103", "132108", "132110", "132112", "132113", "132114", "132117", "132118", "132119", "132120", "132122", "132123", "132125", "132127", "132128", "132130", "132133", "132135", "132136", "132137", "132138", "132139", "132141", "132142", "132144", "132150", "132151", "132152", "132153", "132156", "132157", "132159", "132162", "132164", "132165", "132166", "132167", "132168", "132169", "132170", "132171", "132172", "132173", "132174", "132178", "132180", "132182", "132184", "132185", "132186", "132187", "132189", "132190", "132193", "132194", "132196", "132198", "132201", "132205", "132207", "132208", "132209", "132214", "132215", "132216", "132217", "132218", "132219", "132221", "132222", "132224", "132226", "132228", "132229", "132231", "132232", "132234", "132240", "132242", "132243", "132245", "132247", "132248", "132249", "132252", "132253", "132255", "132256", "132257", "132258", "132260", "132265", "132266", "132267", "132269", "132273", "132277", "132279", "132281", "132282", "132285", "132288", "132289", "132292", "132294", "132296", "132297", "132298", "132300", "132301", "132302", "132303", "132308", "132309", "132310", "132311", "132312", "132315", "132316", "132317", "132321", "132322", "132325", "132326", "132327", "132329", "132331", "132334", "132340", "132343", "132345", "132347", "132348", "132349", "132352", "132354", "132357", "132359", "132361", "132363", "132364", "132367", "132368", "132370", "132371", "132372", "132373", "132376", "132377", "132379", "132381", "132383", "132384", "132388", "132389", "132390", "132391", "132392", "132393", "132394", "132396", "132398", "132400", "132402", "132410", "132413", "132417", "132421", "132423", "132425", "132427", "132429", "132431", "132436", "132438", "132440", "132444", "132446", "132447", "132450", "132451", "132454", "132456", "132464", "132466", "132467", "132468", "132469", "132474", "132475", "132476", "132479", "132480", "132483", "132485", "132487", "132489", "132490", "132492", "132494", "132495", "132500", "132501", "132502", "132503", "132505", "132513", "132514", "132516", "132517", "132518", "132519", "132522", "132523", "132524", "132528", "132532", "132534", "132537", "132538", "132543", "132545", "132547", "132550", "132553", "132555", "132556", "132557", "132559", "132561", "132562", "132564", "132565", "132570", "132572", "132574", "132576", "132578", "132580", "132582", "132583", "132585", "132586", "132588", "132591", "132594", "132597", "132598", "132599", "132600", "132602", "132605", "132608", "132611", "132613", "132614", "132615", "132618", "132619", "132621", "132622", "132625", "132626", "132627", "132628", "132631", "132634", "132636", "132637", "132639", "132645", "132646", "132647", "132649", "132651", "132653", "132654", "132656", "132657", "132658", "132661", "132666", "132667", "132668", "132669", "132671", "132675", "132678", "132679", "132680", "132681", "132682", "132683", "132688", "132690", "132695", "132696", "132697", "132700", "132701", "132702", "132703", "132708", "132709", "132711", "132713", "132714", "132716", "132718", "132720", "132722", "132723", "132724", "132726", "132727", "132728", "132729", "132731", "132732", "132733", "132735", "132736", "132741", "132742", "132743", "132744", "132746", "132747", "132748", "132750", "132751", "132753", "132755", "132758", "132762", "132764", "132765", "132769", "132770", "132772", "132773", "132774", "132775", "132776", "132778", "132781", "132784", "132787", "132790", "132791", "132796", "132797", "132800", "132801", "132803", "132807", "132808", "132811", "132812", "132814", "132816", "132817", "132820", "132821", "132824", "132826", "132829", "132830", "132833", "132834", "132839", "132842", "132844", "132845", "132846", "132847", "132849", "132850", "132851", "132853", "132856", "132860", "132861", "132862", "132865", "132866", "132868", "132870", "132871", "132872", "132873", "132881", "132882", "132884", "132887", "132889", "132890", "132891", "132892", "132893", "132896", "132897", "132899", "132900", "132904", "132906", "132909", "132910", "132912", "132913", "132916", "132918", "132921", "132922", "132925", "132926", "132927", "132928", "132931", "132935", "132936", "132938", "132941", "132943", "132944", "132946", "132947", "132948", "132951", "132952", "132953", "132955", "132956", "132960", "132961", "132963", "132964", "132965", "132970", "132974", "132976", "132978", "132979", "132981", "132983", "132987", "132988", "132990", "132991", "132992", "132994", "132995", "132996", "132997", "132999", "133001", "133002", "133004", "133005", "133006", "133008", "133010", "133014", "133015", "133017", "133020", "133025", "133026", "133031", "133032", "133034", "133035", "133036", "133040", "133043", "133047", "133050", "133053", "133054", "133057", "133058", "133060", "133061", "133064", "133066", "133067", "133068", "133069", "133072", "133074", "133075", "133076", "133078", "133079", "133080", "133081", "133082", "133088", "133089", "133090", "133093", "133097", "133098", "133100", "133105", "133110", "133114", "133115", "133120", "133121", "133124", "133125", "133126", "133128", "133129", "133132", "133134", "133135", "133136", "133138", "133139", "133142", "133144", "133145", "133147", "133148", "133152", "133154", "133156", "133157", "133162", "133163", "133164", "133167", "133168", "133173", "133174", "133176", "133177", "133180", "133181", "133182", "133184", "133185", "133186", "133189", "133191", "133192", "133193", "133194", "133199", "133200", "133202", "133203", "133204", "133205", "133210", "133212", "133213", "133215", "133218", "133219", "133222", "133223", "133227", "133228", "133229", "133232", "133233", "133242", "133243", "133247", "133250", "133251", "133252", "133253", "133254", "133256", "133257", "133260", "133263", "133265", "133268", "133269", "133270", "133272", "133274", "133275", "133276", "133279", "133282", "133284", "133285", "133286", "133287", "133289", "133290", "133291", "133296", "133300", "133302", "133303", "133304", "133307", "133308", "133310", "133311", "133312", "133313", "133314", "133319", "133320", "133324", "133326", "133328", "133329", "133334", "133337", "133343", "133345", "133346", "133354", "133355", "133356", "133358", "133360", "133361", "133362", "133365", "133366", "133368", "133371", "133372", "133374", "133376", "133378", "133381", "133383", "133385", "133386", "133387", "133388", "133389", "133390", "133393", "133394", "133397", "133399", "133404", "133405", "133408", "133409", "133413", "133414", "133416", "133417", "133419", "133420", "133421", "133422", "133426", "133427", "133428", "133430", "133434", "133435", "133436", "133437", "133438", "133440", "133442", "133443", "133444", "133451", "133456", "133457", "133460", "133461", "133463", "133464", "133468", "133470", "133471", "133472", "133473", "133475", "133477", "133478", "133479", "133480", "133481", "133482", "133485", "133487", "133488", "133491", "133492", "133497", "133501", "133504", "133507", "133510", "133513", "133514", "133516", "133518", "133520", "133521", "133522", "133523", "133525", "133526", "133528", "133529", "133530", "133531", "133532", "133535", "133537", "133539", "133544", "133545", "133546", "133547", "133548", "133549", "133552", "133553", "133554", "133555", "133557", "133558", "133559", "133562", "133563", "133564", "133566", "133567", "133569", "133570", "133571", "133572", "133575", "133576", "133577", "133578", "133581", "133583", "133584", "133585", "133586", "133589", "133591", "133593", "133597", "133600", "133601", "133602", "133609", "133610", "133611", "133614", "133615", "133616", "133617", "133621", "133625", "133626", "133627", "133628", "133629", "133631", "133633", "133634", "133635", "133636", "133638", "133639", "133640", "133641", "133643", "133645", "133647", "133659", "133661", "133662", "133665", "133669", "133671", "133672", "133674", "133676", "133677", "133679", "133681", "133682", "133683", "133684", "133685", "133687", "133689", "133690", "133691", "133692", "133694", "133695", "133699", "133701", "133703", "133704", "133705", "133706", "133708", "133709", "133711", "133713", "133715", "133717", "133727", "133729", "133730", "133731", "133734", "133735", "133736", "133737", "133740", "133745", "133748", "133749", "133750", "133751", "133755", "133756", "133759", "133760", "133761", "133766", "133768", "133769", "133770", "133772", "133773", "133775", "133776", "133778", "133779", "133781", "133783", "133784", "133785", "133786", "133787", "133788", "133790", "133791", "133792", "133793", "133796", "133799", "133800", "133801", "133803", "133805", "133807", "133808", "133809", "133810", "133811", "133814", "133822", "133823", "133825", "133826", "133830", "133831", "133832", "133835", "133838", "133839", "133840", "133841", "133843", "133846", "133849", "133851", "133853", "133854", "133855", "133856", "133857", "133858", "133860", "133861", "133868", "133869", "133871", "133872", "133875", "133876", "133879", "133881", "133882", "133885", "133886", "133889", "133890", "133891", "133892", "133894", "133896", "133901", "133904", "133906", "133907", "133908", "133909", "133910", "133913", "133915", "133916", "133917", "133918", "133920", "133922", "133924", "133925", "133926", "133928", "133929", "133932", "133936", "133939", "133941", "133946", "133949", "133954", "133955", "133956", "133957", "133958", "133959", "133960", "133962", "133966", "133968", "133975", "133976", "133977", "133978", "133979", "133980", "133981", "133987", "133990", "133993", "133994", "133995", "133996", "133997", "133998", "134000", "134003", "134004", "134006", "134009", "134013", "134015", "134016", "134023", "134026", "134027", "134028", "134029", "134032", "134034", "134035", "134038", "134040", "134042", "134046", "134048", "134051", "134052", "134056", "134057", "134061", "134062", "134064", "134069", "134072", "134073", "134081", "134082", "134086", "134088", "134089", "134092", "134095", "134098", "134100", "134104", "134105", "134106", "134107", "134109", "134110", "134111", "134113", "134115", "134116", "134118", "134119", "134120", "134125", "134126", "134130", "134131", "134132", "134133", "134134", "134136", "134141", "134142", "134144", "134147", "134152", "134154", "134155", "134156", "134157", "134158", "134159", "134161", "134162", "134164", "134165", "134167", "134173", "134174", "134176", "134181", "134183", "134186", "134188", "134189", "134193", "134194", "134195", "134196", "134197", "134198", "134201", "134202", "134203", "134205", "134206", "134207", "134211", "134216", "134218", "134220", "134222", "134226", "134230", "134231", "134232", "134235", "134236", "134237", "134238", "134239", "134240", "134245", "134247", "134249", "134250", "134252", "134254", "134256", "134258", "134259", "134265", "134266", "134267", "134268", "134271", "134274", "134277", "134280", "134282", "134283", "134285", "134287", "134293", "134294", "134296", "134297", "134298", "134304", "134307", "134308", "134309", "134311", "134313", "134314", "134315", "134316", "134318", "134320", "134321", "134324", "134327", "134328", "134329", "134331", "134333", "134334", "134337", "134339", "134340", "134343", "134344", "134346", "134347", "134348", "134351", "134352", "134354", "134355", "134356", "134357", "134358", "134362", "134367", "134368", "134369", "134371", "134375", "134378", "134379", "134383", "134385", "134387", "134389", "134391", "134392", "134393", "134394", "134395", "134396", "134397", "134398", "134399", "134400", "134401", "134404", "134409", "134410", "134411", "134412", "134418", "134420", "134425", "134426", "134428", "134430", "134431", "134432", "134435", "134436", "134437", "134438", "134439", "134440", "134442", "134444", "134449", "134451", "134452", "134454", "134455", "134456", "134457", "134460", "134462", "134464", "134466", "134467", "134470", "134471", "134473", "134474", "134476", "134477", "134478", "134479", "134481", "134482", "134484", "134486", "134491", "134494", "134495", "134498", "134499", "134501", "134503", "134505", "134509", "134512", "134513", "134514", "134515", "134516", "134517", "134520", "134521", "134523", "134526", "134528", "134529", "134531", "134532", "134537", "134540", "134543", "134544", "134546", "134548", "134550", "134554", "134557", "134558", "134559", "134560", "134564", "134565", "134566", "134568", "134569", "134570", "134571", "134574", "134576", "134578", "134582", "134583", "134584", "134586", "134587", "134588", "134590", "134593", "134595", "134596", "134597", "134598", "134599", "134600", "134601", "134603", "134606", "134607", "134609", "134610", "134615", "134616", "134617", "134618", "134619", "134620", "134624", "134626", "134629", "134637", "134638", "134644", "134645", "134647", "134648", "134656", "134657", "134659", "134660", "134662", "134663", "134665", "134667", "134669", "134672", "134673", "134675", "134676", "134678", "134680", "134681", "134683", "134684", "134687", "134688", "134689", "134690", "134691", "134694", "134697", "134698", "134699", "134702", "134705", "134707", "134708", "134710", "134711", "134712", "134715", "134716", "134719", "134720", "134722", "134725", "134726", "134727", "134728", "134729", "134733", "134735", "134736", "134737", "134739", "134740", "134741", "134743", "134744", "134746", "134747", "134748", "134749", "134750", "134751", "134752", "134753", "134754", "134761", "134763", "134765", "134766", "134769", "134772", "134773", "134774", "134776", "134777", "134778", "134779", "134780", "134783", "134793", "134798", "134805", "134808", "134809", "134811", "134815", "134816", "134817", "134818", "134820", "134821", "134822", "134823", "134826", "134827", "134829", "134831", "134832", "134833", "134835", "134836", "134837", "134839", "134841", "134842", "134843", "134846", "134847", "134848", "134851", "134855", "134861", "134862", "134863", "134864", "134866", "134869", "134870", "134873", "134875", "134878", "134880", "134883", "134884", "134885", "134886", "134889", "134890", "134891", "134892", "134893", "134896", "134897", "134898", "134900", "134901", "134902", "134905", "134907", "134910", "134911", "134912", "134915", "134916", "134918", "134919", "134920", "134921", "134922", "134928", "134933", "134935", "134938", "134940", "134941", "134942", "134943", "134945", "134946", "134948", "134953", "134954", "134957", "134962", "134964", "134966", "134968", "134970", "134974", "134976", "134977", "134981", "134983", "134984", "134986", "134990", "134994", "134997", "134998", "135000", "135003", "135004", "135006", "135007", "135008", "135009", "135010", "135013", "135017", "135018", "135022", "135023", "135025", "135026", "135027", "135032", "135033", "135035", "135039", "135041", "135043", "135047", "135050", "135051", "135052", "135054", "135055", "135056", "135057", "135059", "135060", "135061", "135062", "135063", "135065", "135066", "135069", "135070", "135071", "135072", "135073", "135076", "135078", "135080", "135082", "135087", "135091", "135093", "135094", "135096", "135098", "135099", "135101", "135103", "135106", "135107", "135110", "135113", "135117", "135119", "135120", "135122", "135123", "135125", "135129", "135133", "135135", "135137", "135140", "135142", "135143", "135145", "135151", "135162", "135163", "135165", "135167", "135169", "135170", "135171", "135173", "135179", "135180", "135181", "135183", "135184", "135186", "135188", "135189", "135191", "135193", "135194", "135196", "135197", "135198", "135199", "135200", "135202", "135203", "135204", "135205", "135206", "135207", "135208", "135210", "135212", "135213", "135214", "135215", "135216", "135217", "135218", "135220", "135221", "135222", "135223", "135224", "135226", "135228", "135230", "135232", "135233", "135235", "135237", "135238", "135240", "135241", "135242", "135243", "135244", "135247", "135248", "135251", "135252", "135254", "135255", "135256", "135260", "135261", "135262", "135263", "135265", "135268", "135269", "135275", "135276", "135280", "135282", "135283", "135286", "135287", "135289", "135291", "135292", "135294", "135298", "135301", "135303", "135304", "135305", "135306", "135310", "135312", "135315", "135317", "135319", "135320", "135325", "135327", "135328", "135331", "135334", "135335", "135337", "135340", "135341", "135345", "135347", "135349", "135350", "135351", "135353", "135354", "135355", "135356", "135357", "135358", "135361", "135363", "135364", "135366", "135368", "135374", "135375", "135376", "135377", "135378", "135380", "135381", "135383", "135384", "135385", "135388", "135392", "135395", "135400", "135401", "135403", "135404", "135405", "135409", "135412", "135419", "135420", "135421", "135423", "135424", "135425", "135426", "135427", "135428", "135430", "135431", "135433", "135434", "135435", "135438", "135439", "135440", "135444", "135445", "135447", "135448", "135450", "135452", "135459", "135460", "135461", "135468", "135469", "135470", "135472", "135476", "135477", "135480", "135481", "135483", "135485", "135486", "135487", "135488", "135490", "135494", "135495", "135497", "135498", "135499", "135500", "135501", "135502", "135503", "135505", "135508", "135509", "135510", "135516", "135519", "135522", "135523", "135525", "135530", "135534", "135537", "135539", "135540", "135544", "135545", "135549", "135550", "135555", "135556", "135559", "135563", "135564", "135567", "135568", "135569", "135572", "135573", "135574", "135578", "135580", "135582", "135583", "135584", "135586", "135587", "135588", "135589", "135590", "135594", "135596", "135597", "135598", "135599", "135602", "135604", "135610", "135611", "135614", "135615", "135616", "135618", "135619", "135620", "135622", "135626", "135627", "135630", "135633", "135635", "135636", "135637", "135638", "135640", "135642", "135643", "135647", "135648", "135651", "135652", "135653", "135654", "135660", "135662", "135663", "135664", "135665", "135666", "135672", "135675", "135678", "135680", "135684", "135687", "135688", "135689", "135690", "135691", "135693", "135695", "135696", "135698", "135699", "135700", "135701", "135702", "135704", "135709", "135710", "135712", "135714", "135717", "135720", "135721", "135722", "135723", "135724", "135725", "135727", "135729", "135730", "135731", "135733", "135737", "135740", "135741", "135743", "135744", "135745", "135747", "135749", "135750", "135752", "135755", "135757", "135759", "135761", "135762", "135764", "135766", "135767", "135768", "135770", "135772", "135774", "135779", "135780", "135786", "135788", "135790", "135791", "135795", "135796", "135797", "135798", "135799", "135800", "135802", "135803", "135806", "135808", "135812", "135816", "135818", "135820", "135821", "135823", "135825", "135826", "135830", "135833", "135834", "135836", "135837", "135840", "135842", "135843", "135847", "135850", "135851", "135852", "135853", "135856", "135857", "135863", "135865", "135868", "135870", "135871", "135873", "135874", "135876", "135878", "135880", "135881", "135882", "135883", "135885", "135887", "135888", "135889", "135892", "135895", "135896", "135899", "135901", "135905", "135907", "135908", "135909", "135910", "135911", "135915", "135917", "135919", "135922", "135923", "135925", "135927", "135931", "135932", "135933", "135934", "135940", "135941", "135942", "135948", "135949", "135951", "135952", "135953", "135956", "135960", "135963", "135964", "135967", "135968", "135969", "135971", "135972", "135973", "135977", "135978", "135980", "135981", "135982", "135983", "135984", "135985", "135987", "135989", "135991", "135993", "135996", "135997", "135998", "136001", "136004", "136005", "136006", "136007", "136008", "136009", "136010", "136013", "136014", "136016", "136017", "136018", "136019", "136022", "136027", "136029", "136030", "136031", "136033", "136035", "136038", "136043", "136044", "136045", "136048", "136052", "136053", "136054", "136057", "136058", "136059", "136063", "136064", "136066", "136070", "136071", "136072", "136073", "136074", "136075", "136076", "136078", "136079", "136081", "136082", "136084", "136088", "136090", "136092", "136094", "136097", "136098", "136101", "136103", "136104", "136107", "136109", "136111", "136112", "136120", "136122", "136124", "136128", "136130", "136131", "136132", "136135", "136136", "136138", "136139", "136141", "136143", "136146", "136148", "136150", "136151", "136155", "136158", "136161", "136162", "136163", "136165", "136166", "136168", "136169", "136173", "136175", "136178", "136180", "136182", "136185", "136187", "136188", "136192", "136194", "136195", "136197", "136200", "136202", "136203", "136204", "136206", "136218", "136219", "136220", "136223", "136225", "136228", "136231", "136232", "136233", "136234", "136235", "136236", "136237", "136239", "136240", "136241", "136242", "136244", "136246", "136248", "136249", "136251", "136252", "136253", "136255", "136257", "136259", "136260", "136262", "136263", "136265", "136267", "136268", "136269", "136271", "136274", "136276", "136277", "136280", "136281", "136286", "136287", "136288", "136291", "136296", "136301", "136302", "136304", "136305", "136307", "136314", "136315", "136317", "136322", "136323", "136324", "136325", "136326", "136329", "136337", "136339", "136340", "136341", "136343", "136346", "136348", "136350", "136353", "136354", "136355", "136359", "136362", "136363", "136364", "136367", "136369", "136370", "136372", "136375", "136379", "136383", "136387", "136388", "136393", "136400", "136402", "136404", "136406", "136408", "136411", "136412", "136413", "136418", "136419", "136420", "136421", "136423", "136424", "136427", "136431", "136433", "136436", "136437", "136438", "136439", "136441", "136442", "136447", "136449", "136451", "136458", "136463", "136465", "136466", "136467", "136473", "136474", "136476", "136479", "136481", "136483", "136486", "136487", "136490", "136492", "136493", "136496", "136498", "136499", "136504", "136505", "136507", "136509", "136512", "136513", "136515", "136517", "136518", "136520", "136522", "136523", "136525", "136526", "136527", "136529", "136530", "136533", "136535", "136538", "136539", "136541", "136542", "136544", "136547", "136548", "136549", "136551", "136552", "136554", "136556", "136563", "136567", "136570", "136574", "136577", "136582", "136583", "136584", "136585", "136592", "136593", "136594", "136596", "136601", "136604", "136606", "136607", "136609", "136610", "136616", "136618", "136619", "136620", "136623", "136625", "136629", "136630", "136633", "136637", "136642", "136648", "136652", "136653", "136654", "136661", "136662", "136663", "136664", "136666", "136667", "136669", "136670", "136671", "136678", "136679", "136680", "136681", "136682", "136683", "136686", "136688", "136690", "136692", "136694", "136695", "136696", "136697", "136699", "136704", "136707", "136708", "136709", "136710", "136713", "136714", "136715", "136720", "136723", "136724", "136725", "136729", "136734", "136736", "136741", "136742", "136743", "136744", "136745", "136746", "136749", "136753", "136754", "136756", "136757", "136759", "136761", "136766", "136767", "136770", "136771", "136773", "136775", "136776", "136777", "136780", "136781", "136786", "136788", "136789", "136793", "136796", "136798", "136800", "136802", "136804", "136805", "136808", "136810", "136811", "136813", "136815", "136816", "136817", "136818", "136822", "136824", "136825", "136827", "136830", "136831", "136833", "136839", "136842", "136845", "136848", "136849", "136854", "136855", "136861", "136863", "136864", "136866", "136868", "136872", "136873", "136874", "136875", "136876", "136877", "136882", "136883", "136885", "136887", "136889", "136890", "136892", "136894", "136896", "136897", "136898", "136900", "136902", "136903", "136905", "136907", "136910", "136914", "136917", "136921", "136924", "136926", "136929", "136930", "136931", "136932", "136933", "136934", "136935", "136936", "136939", "136940", "136941", "136942", "136946", "136947", "136948", "136950", "136951", "136953", "136954", "136955", "136957", "136958", "136960", "136962", "136964", "136965", "136966", "136970", "136971", "136972", "136976", "136977", "136979", "136984", "136986", "136987", "136988", "136989", "136990", "136991", "136993", "136994", "136995", "136997", "136998", "137000", "137002", "137005", "137008", "137011", "137013", "137015", "137016", "137018", "137023", "137025", "137028", "137029", "137030", "137031", "137032", "137034", "137035", "137036", "137038", "137039", "137040", "137042", "137043", "137046", "137047", "137048", "137049", "137054", "137055", "137057", "137058", "137063", "137065", "137068", "137069", "137070", "137071", "137072", "137074", "137075", "137077", "137078", "137079", "137080", "137082", "137083", "137084", "137087", "137088", "137089", "137092", "137093", "137096", "137097", "137099", "137101", "137102", "137103", "137108", "137109", "137110", "137111", "137112", "137113", "137116", "137119", "137120", "137121", "137123", "137125", "137127", "137128", "137129", "137130", "137132", "137133", "137134", "137139", "137141", "137144", "137147", "137148", "137149", "137151", "137153", "137154", "137155", "137156", "137157", "137159", "137163", "137164", "137165", "137166", "137167", "137169", "137171", "137172", "137173", "137174", "137176", "137178", "137179", "137181", "137182", "137183", "137184", "137185", "137186", "137187", "137188", "137190", "137191", "137192", "137193", "137194", "137199", "137201", "137202", "137204", "137205", "137209", "137212", "137215", "137216", "137218", "137219", "137226", "137227", "137229", "137232", "137235", "137237", "137238", "137241", "137243", "137244", "137245", "137249", "137251", "137253", "137254", "137255", "137256", "137259", "137261", "137262", "137267", "137269", "137271", "137274", "137275", "137277", "137278", "137281", "137282", "137283", "137285", "137286", "137289", "137290", "137292", "137293", "137298", "137302", "137304", "137307", "137311", "137312", "137313", "137315", "137318", "137319", "137320", "137327", "137328", "137329", "137331", "137332", "137333", "137334", "137335", "137337", "137338", "137341", "137343", "137344", "137348", "137349", "137350", "137352", "137353", "137356", "137357", "137358", "137362", "137363", "137365", "137370", "137371", "137372", "137373", "137374", "137375", "137378", "137381", "137384", "137386", "137387", "137388", "137391", "137392", "137393", "137394", "137395", "137397", "137398", "137399", "137400", "137401", "137404", "137406", "137408", "137411", "137413", "137414", "137417", "137418", "137420", "137421", "137424", "137426", "137427", "137429", "137433", "137434", "137435", "137437", "137441", "137442", "137443", "137444", "137445", "137447", "137448", "137449", "137454", "137455", "137459", "137464", "137466", "137467", "137468", "137469", "137471", "137472", "137473", "137475", "137481", "137482", "137484", "137486", "137487", "137488", "137489", "137491", "137497", "137498", "137500", "137502", "137504", "137505", "137506", "137507", "137512", "137514", "137517", "137518", "137521", "137523", "137527", "137530", "137531", "137533", "137535", "137537", "137545", "137546", "137549", "137550", "137551", "137554", "137555", "137556", "137558", "137562", "137563", "137564", "137567", "137568", "137569", "137570", "137571", "137577", "137578", "137580", "137581", "137582", "137585", "137586", "137588", "137589", "137590", "137598", "137599", "137603", "137605", "137606", "137607", "137611", "137612", "137613", "137616", "137617", "137622", "137627", "137629", "137630", "137633", "137634", "137637", "137638", "137640", "137641", "137647", "137649", "137650", "137652", "137654", "137656", "137658", "137660", "137663", "137666", "137668", "137670", "137673", "137674", "137675", "137677", "137680", "137682", "137683", "137686", "137687", "137688", "137690", "137691", "137695", "137696", "137697", "137698", "137699", "137700", "137701", "137703", "137704", "137706", "137707", "137713", "137714", "137717", "137720", "137726", "137728", "137729", "137732", "137736", "137737", "137738", "137740", "137741", "137742", "137743", "137744", "137746", "137748", "137750", "137752", "137753", "137754", "137758", "137760", "137761", "137763", "137764", "137765", "137766", "137767", "137772", "137773", "137774", "137776", "137781", "137782", "137783", "137785", "137786", "137788", "137793", "137794", "137795", "137797", "137798", "137799", "137800", "137804", "137807", "137808", "137809", "137810", "137814", "137815", "137816", "137818", "137819", "137820", "137821", "137822", "137826", "137827", "137830", "137832", "137833", "137835", "137836", "137837", "137838", "137839", "137841", "137842", "137845", "137846", "137848", "137850", "137851", "137854", "137857", "137862", "137863", "137864", "137866", "137868", "137869", "137870", "137871", "137872", "137878", "137879", "137880", "137883", "137886", "137890", "137892", "137897", "137898", "137900", "137901", "137904", "137905", "137906", "137911", "137912", "137915", "137917", "137918", "137919", "137920", "137921", "137923", "137925", "137927", "137928", "137931", "137933", "137934", "137937", "137939", "137940", "137941", "137942", "137943", "137945", "137947", "137948", "137950", "137952", "137953", "137954", "137955", "137956", "137957", "137958", "137959", "137961", "137963", "137967", "137968", "137969", "137972", "137974", "137975", "137976", "137978", "137979", "137980", "137981", "137983", "137984", "137985", "137989", "137993", "137994", "137995", "138000", "138001", "138005", "138006", "138008", "138011", "138012", "138014", "138015", "138016", "138017", "138018", "138022", "138023", "138024", "138032", "138033", "138034", "138035", "138036", "138041", "138042", "138043", "138044", "138045", "138046", "138048", "138050", "138051", "138055", "138057", "138059", "138060", "138061", "138064", "138069", "138071", "138074", "138075", "138078", "138079", "138080", "138081", "138083", "138086", "138087", "138089", "138091", "138092", "138094", "138096", "138100", "138104", "138105", "138107", "138108", "138111", "138113", "138114", "138119", "138120", "138123", "138126", "138127", "138129", "138130", "138134", "138135", "138136", "138140", "138141", "138144", "138147", "138149", "138150", "138151", "138154", "138156", "138157", "138160", "138162", "138163", "138166", "138168", "138171", "138172", "138177", "138178", "138180", "138182", "138183", "138184", "138185", "138187", "138188", "138189", "138194", "138199", "138200", "138201", "138202", "138205", "138206", "138207", "138208", "138211", "138212", "138213", "138215", "138216", "138217", "138218", "138219", "138221", "138222", "138224", "138227", "138228", "138229", "138235", "138237", "138238", "138240", "138241", "138244", "138245", "138246", "138247", "138248", "138250", "138258", "138260", "138262", "138264", "138267", "138268", "138269", "138272", "138273", "138275", "138277", "138281", "138282", "138285", "138291", "138292", "138294", "138295", "138297", "138300", "138303", "138309", "138310", "138312", "138313", "138314", "138315", "138318", "138320", "138321", "138329", "138330", "138331", "138333", "138336", "138338", "138342", "138346", "138349", "138350", "138355", "138358", "138360", "138361", "138362", "138363", "138365", "138366", "138368", "138371", "138372", "138373", "138375", "138376", "138380", "138381", "138382", "138383", "138386", "138388", "138389", "138392", "138393", "138394", "138396", "138397", "138398", "138399", "138400", "138402", "138403", "138408", "138409", "138412", "138417", "138420", "138422", "138423", "138426", "138427", "138429", "138434", "138435", "138437", "138438", "138439", "138440", "138442", "138443", "138444", "138445", "138447", "138448", "138449", "138450", "138452", "138453", "138454", "138457", "138460", "138461", "138462", "138463", "138465", "138468", "138469", "138470", "138474", "138475", "138477", "138478", "138479", "138480", "138481", "138484", "138485", "138486", "138497", "138500", "138501", "138502", "138503", "138504", "138506", "138509", "138510", "138515", "138516", "138517", "138519", "138526", "138527", "138530", "138534", "138537", "138538", "138539", "138545", "138549", "138550", "138554", "138556", "138560", "138561", "138562", "138564", "138569", "138570", "138575", "138583", "138584", "138585", "138586", "138587", "138592", "138593", "138594", "138595", "138597", "138598", "138599", "138600", "138601", "138602", "138603", "138604", "138605", "138606", "138607", "138611", "138612", "138613", "138617", "138618", "138620", "138621", "138622", "138623", "138627", "138628", "138629", "138630", "138631", "138632", "138634", "138635", "138637", "138638", "138640", "138643", "138644", "138645", "138648", "138651", "138652", "138656", "138657", "138659", "138660", "138661", "138663", "138665", "138666", "138669", "138670", "138671", "138672", "138674", "138679", "138681", "138682", "138683", "138686", "138689", "138693", "138695", "138698", "138701", "138702", "138703", "138705", "138706", "138707", "138708", "138709", "138710", "138713", "138718", "138721", "138722", "138727", "138729", "138730", "138731", "138732", "138733", "138735", "138736", "138737", "138738", "138739", "138741", "138747", "138749", "138750", "138751", "138752", "138755", "138756", "138758", "138759", "138764", "138765", "138770", "138771", "138772", "138776", "138779", "138780", "138781", "138782", "138783", "138785", "138786", "138788", "138789", "138792", "138794", "138796", "138798", "138799", "138801", "138802", "138803", "138805", "138810", "138814", "138822", "138824", "138825", "138827", "138828", "138830", "138832", "138836", "138838", "138839", "138841", "138842", "138843", "138846", "138850", "138851", "138852", "138853", "138856", "138858", "138864", "138866", "138868", "138869", "138870", "138871", "138872", "138874", "138875", "138878", "138879", "138881", "138882", "138883", "138884", "138885", "138889", "138892", "138896", "138897", "138898", "138899", "138901", "138902", "138905", "138906", "138907", "138910", "138911", "138912", "138913", "138914", "138915", "138916", "138917", "138920", "138922", "138924", "138927", "138930", "138932", "138933", "138934", "138938", "138939", "138942", "138943", "138944", "138949", "138951", "138952", "138953", "138954", "138956", "138960", "138962", "138963", "138966", "138967", "138969", "138975", "138977", "138979", "138980", "138981", "138984", "138985", "138987", "138989", "138990", "138992", "138994", "138995", "138996", "138997", "138999", "139000", "139001", "139002", "139004", "139006", "139009", "139010", "139012", "139013", "139014", "139015", "139016", "139017", "139022", "139024", "139027", "139029", "139030", "139032", "139033", "139035", "139038", "139039", "139040", "139041", "139042", "139043", "139044", "139045", "139047", "139049", "139050", "139051", "139052", "139057", "139059", "139060", "139063", "139066", "139067", "139069", "139070", "139071", "139073", "139074", "139078", "139080", "139083", "139084", "139086", "139088", "139089", "139090", "139093", "139096", "139097", "139101", "139103", "139104", "139105", "139107", "139108", "139109", "139110", "139111", "139114", "139116", "139117", "139118", "139119", "139121", "139122", "139124", "139125", "139126", "139127", "139129", "139130", "139134", "139137", "139138", "139139", "139140", "139142", "139143", "139145", "139148", "139150", "139151", "139152", "139153", "139154", "139157", "139158", "139159", "139160", "139162", "139163", "139165", "139167", "139169", "139171", "139173", "139174", "139176", "139177", "139179", "139181", "139182", "139184", "139185", "139186", "139188", "139189", "139192", "139194", "139195", "139196", "139198", "139199", "139201", "139203", "139204", "139206", "139208", "139215", "139216", "139217", "139222", "139224", "139225", "139227", "139228", "139229", "139230", "139232", "139235", "139239", "139241", "139242", "139243", "139245", "139246", "139247", "139253", "139254", "139258", "139259", "139260", "139261", "139264", "139267", "139268", "139269", "139271", "139273", "139274", "139276", "139277", "139279", "139283", "139287", "139289", "139293", "139296", "139298", "139300", "139302", "139303", "139305", "139307", "139309", "139312", "139313", "139314", "139316", "139317", "139318", "139319", "139323", "139325", "139326", "139328", "139330", "139334", "139336", "139337", "139338", "139339", "139341", "139342", "139346", "139349", "139352", "139358", "139359", "139362", "139363", "139365", "139366", "139368", "139369", "139370", "139371", "139373", "139377", "139378", "139379", "139380", "139381", "139383", "139385", "139386", "139387", "139391", "139392", "139393", "139394", "139399", "139401", "139406", "139407", "139412", "139414", "139415", "139423", "139425", "139426", "139428", "139430", "139431", "139433", "139435", "139438", "139439", "139440", "139441", "139442", "139445", "139446", "139448", "139449", "139451", "139452", "139455", "139457", "139458", "139460", "139463", "139464", "139466", "139467", "139468", "139470", "139472", "139474", "139475", "139477", "139478", "139482", "139483", "139484", "139485", "139486", "139489", "139490", "139493", "139499", "139501", "139502", "139505", "139506", "139507", "139508", "139509", "139510", "139511", "139512", "139514", "139518", "139519", "139522", "139523", "139526", "139528", "139530", "139535", "139539", "139540", "139543", "139547", "139548", "139551", "139553", "139554", "139557", "139559", "139567", "139572", "139574", "139577", "139578", "139580", "139582", "139584", "139586", "139589", "139590", "139593", "139594", "139596", "139598", "139599", "139600", "139601", "139604", "139605", "139607", "139611", "139612", "139613", "139619", "139620", "139621", "139623", "139624", "139627", "139628", "139636", "139637", "139639", "139640", "139641", "139642", "139643", "139646", "139649", "139651", "139652", "139653", "139657", "139659", "139667", "139669", "139670", "139671", "139672", "139674", "139677", "139678", "139679", "139682", "139685", "139693", "139695", "139697", "139705", "139706", "139710", "139712", "139714", "139716", "139717", "139719", "139720", "139724", "139725", "139728", "139730", "139732", "139733", "139734", "139735", "139736", "139737", "139738", "139739", "139743", "139746", "139747", "139748", "139749", "139751", "139756", "139758", "139761", "139763", "139766", "139768", "139771", "139773", "139774", "139775", "139776", "139777", "139780", "139781", "139786", "139787", "139788", "139789", "139791", "139792", "139794", "139796", "139797", "139798", "139801", "139802", "139803", "139806", "139807", "139808", "139809", "139811", "139812", "139814", "139815", "139819", "139821", "139829", "139834", "139835", "139836", "139838", "139842", "139851", "139857", "139859", "139860", "139861", "139862", "139864", "139867", "139869", "139870", "139871", "139875", "139877", "139878", "139880", "139882", "139883", "139884", "139886", "139887", "139889", "139891", "139893", "139896", "139898", "139900", "139902", "139903", "139906", "139907", "139908", "139910", "139911", "139913", "139914", "139915", "139917", "139918", "139920", "139922", "139923", "139924", "139927", "139931", "139932", "139935", "139936", "139939", "139944", "139949", "139952", "139955", "139956", "139957", "139958", "139959", "139960", "139961", "139963", "139964", "139965", "139967", "139969", "139974", "139975", "139976", "139977", "139981", "139982", "139983", "139984", "139988", "139990", "139991", "139992", "139993", "139994", "139997", "140003", "140007", "140008", "140013", "140015", "140016", "140017", "140018", "140019", "140023", "140024", "140025", "140026", "140027", "140030", "140031", "140034", "140035", "140037", "140038", "140040", "140041", "140045", "140046", "140049", "140052", "140055", "140057", "140058", "140059", "140062", "140067", "140068", "140070", "140072", "140074", "140077", "140078", "140079", "140080", "140081", "140083", "140087", "140088", "140089", "140090", "140091", "140094", "140095", "140101", "140102", "140104", "140105", "140108", "140109", "140110", "140111", "140112", "140115", "140117", "140118", "140119", "140121", "140124", "140125", "140131", "140132", "140133", "140134", "140135", "140136", "140137", "140138", "140141", "140142", "140145", "140146", "140148", "140149", "140151", "140152", "140153", "140155", "140156", "140157", "140160", "140162", "140163", "140165", "140170", "140173", "140174", "140176", "140177", "140179", "140182", "140183", "140184", "140185", "140186", "140187", "140189", "140190", "140191", "140192", "140193", "140195", "140197", "140201", "140202", "140203", "140204", "140210", "140213", "140214", "140217", "140218", "140219", "140223", "140224", "140227", "140228", "140229", "140230", "140232", "140235", "140236", "140238", "140244", "140246", "140248", "140249", "140250", "140251", "140252", "140253", "140256", "140258", "140261", "140262", "140264", "140268", "140269", "140270", "140271", "140274", "140275", "140278", "140279", "140280", "140283", "140285", "140286", "140288", "140290", "140291", "140293", "140296", "140297", "140298", "140299", "140300", "140303", "140304", "140305", "140306", "140307", "140309", "140311", "140313", "140314", "140315", "140316", "140318", "140319", "140320", "140325", "140327", "140328", "140329", "140335", "140336", "140337", "140340", "140341", "140343", "140345", "140347", "140349", "140350", "140355", "140357", "140359", "140361", "140362", "140364", "140365", "140366", "140369", "140370", "140371", "140373", "140374", "140377", "140378", "140379", "140380", "140384", "140385", "140387", "140388", "140389", "140391", "140393", "140394", "140395", "140398", "140401", "140403", "140404", "140406", "140407", "140409", "140412", "140416", "140418", "140420", "140421", "140422", "140424", "140425", "140429", "140431", "140433", "140434", "140435", "140437", "140438", "140439", "140440", "140441", "140442", "140446", "140447", "140450", "140453", "140454", "140455", "140456", "140462", "140463", "140465", "140466", "140471", "140472", "140473", "140475", "140476", "140477", "140478", "140479", "140480", "140483", "140484", "140487", "140489", "140491", "140492", "140494", "140496", "140497", "140498", "140501", "140503", "140504", "140506", "140507", "140510", "140511", "140516", "140517", "140521", "140522", "140527", "140530", "140534", "140537", "140539", "140541", "140542", "140543", "140545", "140546", "140547", "140548", "140549", "140552", "140556", "140557", "140558", "140559", "140560", "140561", "140562", "140565", "140566", "140567", "140568", "140569", "140571", "140573", "140574", "140575", "140576", "140580", "140581", "140582", "140583", "140585", "140587", "140588", "140589", "140590", "140592", "140594", "140599", "140602", "140604", "140606", "140607", "140609", "140611", "140612", "140615", "140619", "140620", "140621", "140627", "140629", "140630", "140631", "140635", "140639", "140640", "140644", "140645", "140649", "140651", "140652", "140654", "140656", "140657", "140661", "140663", "140665", "140667", "140668", "140669", "140670", "140671", "140674", "140675", "140676", "140678", "140680", "140681", "140682", "140683", "140685", "140686", "140687", "140692", "140693", "140694", "140699", "140701", "140702", "140703", "140705", "140707", "140709", "140710", "140715", "140718", "140721", "140723", "140724", "140726", "140730", "140731", "140733", "140735", "140736", "140738", "140739", "140742", "140745", "140746", "140750", "140751", "140753", "140755", "140756", "140757", "140759", "140760", "140761", "140764", "140767", "140768", "140769", "140770", "140774", "140775", "140776", "140777", "140778", "140779", "140781", "140782", "140784", "140786", "140788", "140790", "140791", "140792", "140793", "140794", "140795", "140797", "140804", "140805", "140806", "140811", "140815", "140816", "140823", "140825", "140827", "140829", "140830", "140832", "140834", "140839", "140841", "140844", "140846", "140848", "140849", "140850", "140853", "140854", "140856", "140862", "140863", "140865", "140866", "140867", "140868", "140869", "140870", "140873", "140874", "140877", "140878", "140883", "140884", "140888", "140890", "140893", "140896", "140897", "140898", "140899", "140902", "140904", "140909", "140914", "140915", "140918", "140919", "140920", "140921", "140922", "140923", "140924", "140925", "140926", "140927", "140928", "140929", "140932", "140933", "140936", "140938", "140940", "140941", "140942", "140944", "140949", "140950", "140951", "140952", "140953", "140954", "140957", "140959", "140962", "140972", "140973", "140975", "140980", "140985", "140986", "140988", "140990", "140993", "140994", "140995", "140997", "141001", "141005", "141007", "141008", "141009", "141010", "141024", "141026", "141028", "141029", "141030", "141034", "141037", "141038", "141041", "141042", "141043", "141045", "141047", "141048", "141052", "141054", "141055", "141057", "141060", "141064", "141065", "141067", "141069", "141071", "141072", "141074", "141077", "141078", "141079", "141080", "141081", "141083", "141086", "141087", "141089", "141090", "141097", "141099", "141100", "141101", "141102", "141103", "141107", "141110", "141111", "141112", "141113", "141115", "141116", "141118", "141119", "141120", "141121", "141122", "141124", "141126", "141128", "141135", "141137", "141138", "141139", "141142", "141143", "141144", "141146", "141147", "141148", "141149", "141151", "141156", "141157", "141158", "141159", "141161", "141163", "141166", "141171", "141173", "141177", "141179", "141183", "141186", "141187", "141188", "141189", "141191", "141192", "141195", "141196", "141197", "141198", "141199", "141200", "141201", "141202", "141203", "141205", "141207", "141209", "141210", "141213", "141214", "141215", "141216", "141217", "141220", "141224", "141225", "141226", "141227", "141229", "141230", "141231", "141233", "141235", "141236", "141237", "141239", "141240", "141241", "141243", "141244", "141247", "141248", "141249", "141250", "141253", "141255", "141258", "141259", "141260", "141261", "141262", "141265", "141269", "141271", "141276", "141281", "141282", "141284", "141286", "141288", "141290", "141291", "141292", "141296", "141301", "141302", "141304", "141305", "141306", "141307", "141312", "141314", "141315", "141316", "141320", "141322", "141327", "141328", "141329", "141330", "141332", "141334", "141335", "141336", "141340", "141341", "141342", "141344", "141346", "141347", "141348", "141349", "141353", "141358", "141359", "141360", "141361", "141362", "141363", "141367", "141368", "141373", "141374", "141377", "141380", "141381", "141382", "141383", "141384", "141385", "141388", "141391", "141392", "141393", "141394", "141395", "141396", "141397", "141400", "141401", "141404", "141405", "141406", "141409", "141410", "141411", "141412", "141413", "141414", "141415", "141416", "141417", "141420", "141421", "141422", "141424", "141425", "141434", "141436", "141437", "141438", "141442", "141444", "141446", "141448", "141458", "141461", "141463", "141464", "141465", "141466", "141469", "141475", "141477", "141482", "141483", "141484", "141485", "141488", "141492", "141493", "141494", "141497", "141500", "141501", "141502", "141504", "141505", "141508", "141510", "141511", "141513", "141514", "141515", "141516", "141517", "141518", "141520", "141521", "141523", "141524", "141525", "141527", "141528", "141529", "141530", "141531", "141534", "141539", "141542", "141546", "141547", "141548", "141551", "141555", "141556", "141557", "141559", "141566", "141567", "141571", "141574", "141578", "141579", "141581", "141584", "141585", "141590", "141591", "141594", "141596", "141597", "141598", "141599", "141603", "141606", "141608", "141609", "141611", "141614", "141617", "141619", "141620", "141624", "141625", "141627", "141628", "141631", "141633", "141634", "141635", "141636", "141638", "141639", "141640", "141644", "141646", "141647", "141649", "141650", "141654", "141656", "141658", "141659", "141661", "141664", "141666", "141668", "141669", "141670", "141672", "141675", "141676", "141677", "141678", "141679", "141680", "141681", "141684", "141688", "141689", "141694", "141695", "141696", "141697", "141698", "141699", "141700", "141701", "141702", "141703", "141705", "141707", "141709", "141710", "141713", "141715", "141716", "141717", "141719", "141722", "141723", "141724", "141726", "141727", "141728", "141733", "141735", "141739", "141740", "141745", "141746", "141748", "141749", "141751", "141752", "141753", "141755", "141756", "141758", "141759", "141761", "141762", "141764", "141765", "141766", "141767", "141768", "141770", "141774", "141776", "141777", "141779", "141780", "141783", "141784", "141785", "141793", "141795", "141797", "141798", "141800", "141801", "141803", "141804", "141805", "141809", "141812", "141816", "141817", "141818", "141820", "141821", "141823", "141829", "141833", "141834", "141836", "141839", "141840", "141841", "141844", "141846", "141849", "141855", "141856", "141857", "141858", "141861", "141862", "141863", "141865", "141866", "141869", "141872", "141873", "141874", "141877", "141879", "141880", "141881", "141886", "141887", "141888", "141890", "141892", "141896", "141897", "141898", "141900", "141902", "141903", "141904", "141905", "141908", "141909", "141911", "141912", "141913", "141914", "141915", "141917", "141919", "141920", "141921", "141924", "141925", "141928", "141931", "141932", "141937", "141938", "141941", "141943", "141944", "141945", "141949", "141950", "141952", "141954", "141955", "141956", "141957", "141958", "141960", "141961", "141962", "141967", "141971", "141972", "141974", "141975", "141977", "141979", "141983", "141984", "141989", "141996", "141998", "141999", "142000", "142002", "142003", "142004", "142006", "142008", "142011", "142012", "142016", "142019", "142020", "142021", "142022", "142025", "142026", "142028", "142029", "142030", "142034", "142036", "142038", "142039", "142040", "142041", "142044", "142046", "142048", "142049", "142052", "142054", "142056", "142058", "142059", "142062", "142064", "142065", "142066", "142071", "142072", "142073", "142074", "142076", "142077", "142078", "142079", "142080", "142082", "142083", "142086", "142088", "142091", "142093", "142095", "142096", "142098", "142099", "142101", "142104", "142105", "142106", "142109", "142110", "142113", "142114", "142115", "142116", "142121", "142124", "142127", "142128", "142129", "142130", "142133", "142134", "142135", "142137", "142140", "142141", "142143", "142144", "142146", "142149", "142150", "142152", "142153", "142161", "142162", "142163", "142166", "142169", "142170", "142174", "142179", "142181", "142185", "142187", "142189", "142190", "142194", "142195", "142196", "142197", "142200", "142203", "142204", "142206", "142207", "142209", "142211", "142212", "142213", "142219", "142220", "142222", "142223", "142224", "142226", "142227", "142228", "142234", "142235", "142237", "142238", "142240", "142242", "142243", "142244", "142248", "142249", "142250", "142253", "142254", "142255", "142256", "142258", "142260", "142264", "142265", "142266", "142267", "142268", "142272", "142277", "142278", "142279", "142280", "142281", "142282", "142284", "142285", "142288", "142289", "142290", "142296", "142300", "142301", "142302", "142303", "142306", "142307", "142309", "142315", "142319", "142321", "142322", "142326", "142327", "142328", "142334", "142335", "142336", "142339", "142340", "142341", "142343", "142344", "142346", "142348", "142350", "142351", "142352", "142354", "142356", "142360", "142361", "142362", "142365", "142368", "142369", "142371", "142372", "142375", "142378", "142380", "142389", "142390", "142391", "142394", "142398", "142399", "142403", "142404", "142406", "142407", "142410", "142411", "142414", "142415", "142417", "142418", "142420", "142421", "142424", "142426", "142427", "142428", "142429", "142432", "142436", "142437", "142439", "142440", "142441", "142445", "142447", "142449", "142452", "142454", "142455", "142457", "142460", "142461", "142462", "142465", "142468", "142470", "142471", "142472", "142475", "142477", "142479", "142480", "142481", "142483", "142485", "142489", "142490", "142492", "142494", "142495", "142496", "142499", "142500", "142501", "142503", "142505", "142508", "142509", "142512", "142513", "142515", "142516", "142518", "142520", "142522", "142523", "142525", "142526", "142527", "142528", "142529", "142533", "142534", "142540", "142541", "142544", "142546", "142549", "142550", "142552", "142553", "142556", "142559", "142561", "142562", "142564", "142565", "142568", "142574", "142575", "142577", "142579", "142582", "142584", "142586", "142587", "142588", "142592", "142594", "142595", "142596", "142601", "142602", "142603", "142605", "142608", "142611", "142612", "142613", "142616", "142617", "142618", "142621", "142622", "142625", "142626", "142631", "142634", "142635", "142638", "142641", "142642", "142647", "142648", "142650", "142651", "142652", "142654", "142656", "142657", "142659", "142660", "142661", "142665", "142666", "142667", "142670", "142673", "142677", "142678", "142679", "142685", "142686", "142689", "142692", "142695", "142697", "142698", "142700", "142702", "142705", "142706", "142707", "142708", "142710", "142711", "142712", "142713", "142714", "142715", "142718", "142721", "142723", "142724", "142725", "142730", "142731", "142732", "142733", "142734", "142735", "142736", "142738", "142739", "142741", "142744", "142746", "142747", "142748", "142750", "142756", "142757", "142758", "142759", "142760", "142762", "142763", "142764", "142767", "142768", "142769", "142770", "142773", "142779", "142780", "142783", "142784", "142788", "142789", "142790", "142792", "142793", "142794", "142796", "142797", "142800", "142801", "142802", "142804", "142805", "142807", "142809", "142811", "142814", "142816", "142820", "142821", "142822", "142823", "142825", "142827", "142828", "142829", "142830", "142831", "142832", "142833", "142836", "142838", "142848", "142851", "142853", "142856", "142857", "142858", "142859", "142863", "142865", "142866", "142867", "142870", "142872", "142873", "142876", "142880", "142884", "142885", "142888", "142889", "142891", "142892", "142893", "142894", "142896", "142899", "142901", "142904", "142906", "142908", "142910", "142911", "142912", "142913", "142915", "142922", "142924", "142925", "142927", "142928", "142931", "142934", "142935", "142936", "142938", "142939", "142940", "142941", "142948", "142951", "142953", "142954", "142957", "142958", "142961", "142963", "142964", "142965", "142966", "142968", "142969", "142972", "142973", "142976", "142978", "142979", "142981", "142983", "142984", "142986", "142987", "142988", "142993", "142994", "142995", "142996", "142997", "142998", "142999", "143001", "143005", "143012", "143016", "143017", "143019", "143020", "143023", "143025", "143026", "143029", "143031", "143033", "143034", "143035", "143037", "143039", "143042", "143044", "143045", "143046", "143047", "143048", "143049", "143052", "143055", "143056", "143057", "143060", "143061", "143062", "143063", "143065", "143067", "143069", "143072", "143073", "143074", "143076", "143077", "143078", "143079", "143081", "143082", "143083", "143085", "143086", "143087", "143089", "143090", "143092", "143096", "143098", "143099", "143101", "143102", "143103", "143104", "143105", "143106", "143108", "143113", "143114", "143115", "143117", "143120", "143121", "143124", "143126", "143128", "143132", "143133", "143134", "143135", "143136", "143142", "143143", "143147", "143148", "143152", "143153", "143154", "143156", "143160", "143162", "143163", "143165", "143168", "143169", "143170", "143173", "143175", "143176", "143178", "143179", "143180", "143182", "143183", "143187", "143190", "143193", "143194", "143196", "143197", "143198", "143201", "143202", "143206", "143207", "143210", "143212", "143213", "143215", "143216", "143217", "143219", "143220", "143224", "143227", "143228", "143229", "143230", "143232", "143235", "143236", "143242", "143245", "143246", "143247", "143251", "143252", "143253", "143256", "143257", "143258", "143259", "143260", "143261", "143262", "143264", "143265", "143266", "143267", "143269", "143270", "143272", "143274", "143276", "143278", "143279", "143281", "143284", "143285", "143286", "143288", "143289", "143292", "143293", "143296", "143297", "143298", "143300", "143301", "143304", "143306", "143308", "143309", "143310", "143311", "143312", "143314", "143315", "143317", "143318", "143320", "143324", "143325", "143326", "143328", "143330", "143331", "143332", "143333", "143334", "143336", "143337", "143342", "143343", "143344", "143346", "143348", "143349", "143350", "143352", "143353", "143355", "143360", "143361", "143365", "143367", "143368", "143369", "143371", "143372", "143375", "143376", "143377", "143381", "143382", "143384", "143385", "143386", "143387", "143390", "143392", "143394", "143395", "143398", "143399", "143402", "143403", "143404", "143405", "143407", "143408", "143412", "143413", "143415", "143416", "143418", "143419", "143420", "143421", "143422", "143424", "143425", "143426", "143427", "143429", "143434", "143435", "143436", "143437", "143438", "143439", "143441", "143443", "143444", "143448", "143450", "143452", "143454", "143456", "143457", "143459", "143461", "143462", "143464", "143465", "143468", "143470", "143472", "143473", "143474", "143475", "143479", "143480", "143481", "143482", "143485", "143488", "143490", "143493", "143495", "143496", "143498", "143499", "143502", "143503", "143507", "143509", "143510", "143512", "143513", "143515", "143517", "143521", "143522", "143523", "143526", "143527", "143528", "143529", "143530", "143535", "143537", "143538", "143540", "143541", "143542", "143544", "143548", "143549", "143550", "143551", "143554", "143555", "143558", "143562", "143565", "143568", "143570", "143571", "143572", "143573", "143576", "143577", "143578", "143579", "143580", "143583", "143586", "143587", "143590", "143591", "143592", "143596", "143597", "143599", "143601", "143602", "143606", "143607", "143608", "143611", "143612", "143615", "143619", "143620", "143622", "143623", "143628", "143636", "143637", "143638", "143640", "143641", "143642", "143645", "143646", "143650", "143651", "143656", "143659", "143660", "143661", "143664", "143665", "143667", "143668", "143669", "143671", "143674", "143675", "143677", "143678", "143679", "143680", "143683", "143685", "143687", "143689", "143690", "143691", "143693", "143695", "143696", "143698", "143699", "143702", "143703", "143704", "143706", "143707", "143708", "143710", "143711", "143713", "143714", "143719", "143721", "143727", "143732", "143733", "143734", "143737", "143740", "143742", "143743", "143745", "143747", "143749", "143753", "143755", "143756", "143757", "143758", "143759", "143760", "143761", "143762", "143763", "143764", "143767", "143768", "143769", "143771", "143773", "143780", "143781", "143782", "143787", "143790", "143791", "143792", "143796", "143799", "143800", "143801", "143808", "143809", "143810", "143812", "143813", "143816", "143818", "143819", "143820", "143824", "143827", "143828", "143830", "143834", "143836", "143837", "143847", "143849", "143852", "143855", "143859", "143860", "143862", "143865", "143868", "143869", "143870", "143871", "143874", "143884", "143885", "143886", "143887", "143895", "143896", "143901", "143904", "143907", "143908", "143910", "143911", "143916", "143921", "143922", "143923", "143925", "143928", "143929", "143931", "143932", "143933", "143934", "143935", "143936", "143938", "143940", "143941", "143945", "143948", "143951", "143952", "143955", "143956", "143957", "143958", "143968", "143970", "143972", "143975", "143977", "143981", "143984", "143985", "143987", "143988", "143989", "143991", "143994", "143999", "144000", "144001", "144004", "144005", "144007", "144008", "144009", "144010", "144011", "144016", "144019", "144022", "144023", "144024", "144025", "144026", "144027", "144030", "144033", "144035", "144036", "144043", "144044", "144045", "144046", "144048", "144050", "144051", "144052", "144053", "144055", "144059", "144061", "144062", "144065", "144066", "144067", "144069", "144072", "144075", "144076", "144079", "144080", "144083", "144084", "144085", "144086", "144088", "144089", "144090", "144091", "144093", "144094", "144099", "144103", "144104", "144107", "144111", "144112", "144113", "144118", "144119", "144120", "144122", "144123", "144125", "144126", "144130", "144133", "144134", "144135", "144137", "144139", "144140", "144141", "144143", "144146", "144149", "144150", "144151", "144155", "144157", "144158", "144159", "144160", "144161", "144162", "144164", "144166", "144168", "144170", "144171", "144173", "144175", "144176", "144178", "144180", "144181", "144188", "144189", "144190", "144191", "144194", "144198", "144201", "144202", "144203", "144204", "144210", "144214", "144215", "144217", "144224", "144227", "144229", "144230", "144236", "144237", "144240", "144241", "144245", "144246", "144247", "144249", "144250", "144251", "144255", "144256", "144261", "144262", "144264", "144266", "144267", "144272", "144274", "144275", "144279", "144280", "144281", "144282", "144283", "144284", "144289", "144291", "144292", "144293", "144295", "144297", "144299", "144300", "144302", "144304", "144308", "144309", "144310", "144320", "144325", "144326", "144329", "144330", "144331", "144332", "144333", "144337", "144343", "144346", "144348", "144349", "144350", "144351", "144353", "144354", "144356", "144363", "144366", "144367", "144370", "144372", "144373", "144375", "144379", "144380", "144381", "144382", "144384", "144385", "144388", "144393", "144396", "144397", "144398", "144403", "144404", "144407", "144411", "144413", "144414", "144415", "144416", "144421", "144422", "144427", "144430", "144431", "144432", "144433", "144435", "144437", "144438", "144441", "144442", "144444", "144446", "144448", "144450", "144453", "144458", "144459", "144462", "144465", "144466", "144470", "144472", "144476", "144477", "144478", "144479", "144480", "144482", "144484", "144488", "144491", "144492", "144496", "144506", "144513", "144514", "144518", "144520", "144521", "144524", "144526", "144527", "144528", "144529", "144530", "144531", "144534", "144537", "144539", "144541", "144542", "144543", "144544", "144546", "144548", "144549", "144550", "144556", "144557", "144558", "144567", "144569", "144573", "144574", "144575", "144578", "144579", "144580", "144582", "144583", "144584", "144585", "144586", "144589", "144590", "144595", "144599", "144600", "144601", "144603", "144611", "144613", "144615", "144617", "144618", "144619", "144623", "144625", "144630", "144632", "144634", "144635", "144637", "144640", "144641", "144642", "144644", "144646", "144647", "144649", "144652", "144653", "144654", "144656", "144659", "144660", "144665", "144667", "144669", "144670", "144671", "144674", "144677", "144679", "144680", "144681", "144684", "144686", "144687", "144688", "144691", "144693", "144695", "144696", "144697", "144698", "144700", "144703", "144705", "144706", "144707", "144709", "144710", "144711", "144716", "144719", "144721", "144722", "144723", "144724", "144726", "144727", "144728", "144729", "144731", "144732", "144734", "144738", "144741", "144742", "144744", "144745", "144746", "144747", "144749", "144750", "144751", "144752", "144755", "144757", "144758", "144759", "144760", "144764", "144767", "144768", "144771", "144772", "144775", "144776", "144777", "144778", "144781", "144783", "144784", "144786", "144787", "144788", "144789", "144790", "144792", "144793", "144796", "144797", "144798", "144800", "144803", "144805", "144808", "144811", "144813", "144815", "144817", "144821", "144825", "144826", "144829", "144830", "144833", "144835", "144836", "144837", "144839", "144840", "144842", "144844", "144845", "144846", "144847", "144848", "144849", "144851", "144852", "144855", "144856", "144857", "144858", "144859", "144861", "144863", "144864", "144865", "144866", "144867", "144869", "144870", "144873", "144877", "144880", "144881", "144886", "144887", "144888", "144891", "144894", "144896", "144897", "144902", "144904", "144909", "144910", "144912", "144913", "144914", "144915", "144917", "144918", "144920", "144924", "144925", "144926", "144929", "144930", "144932", "144934", "144936", "144937", "144939", "144943", "144944", "144945", "144948", "144953", "144955", "144956", "144959", "144963", "144964", "144965", "144967", "144969", "144972", "144976", "144978", "144980", "144983", "144985", "144986", "144988", "144989", "144993", "144994", "144995", "144997", "144998", "144999", "145002", "145004", "145006", "145011", "145012", "145014", "145017", "145020", "145022", "145028", "145029", "145036", "145037", "145039", "145040", "145041", "145042", "145046", "145048", "145052", "145053", "145054", "145056", "145059", "145060", "145062", "145065", "145068", "145069", "145070", "145071", "145072", "145076", "145078", "145081", "145084", "145086", "145087", "145089", "145090", "145091", "145094", "145095", "145097", "145098", "145102", "145103", "145107", "145108", "145110", "145113", "145114", "145116", "145120", "145122", "145124", "145127", "145129", "145130", "145131", "145132", "145133", "145136", "145143", "145144", "145147", "145151", "145153", "145154", "145155", "145156", "145159", "145160", "145163", "145165", "145166", "145172", "145174", "145175", "145178", "145180", "145181", "145183", "145185", "145188", "145189", "145191", "145192", "145193", "145195", "145200", "145204", "145208", "145211", "145213", "145219", "145221", "145222", "145224", "145225", "145228", "145230", "145231", "145232", "145233", "145234", "145236", "145237", "145238", "145240", "145244", "145246", "145247", "145250", "145255", "145258", "145260", "145261", "145264", "145265", "145266", "145268", "145269", "145271", "145272", "145273", "145274", "145276", "145279", "145280", "145281", "145283", "145284", "145288", "145289", "145298", "145299", "145303", "145306", "145307", "145308", "145309", "145320", "145324", "145325", "145326", "145328", "145329", "145332", "145333", "145334", "145336", "145337", "145339", "145340", "145341", "145342", "145343", "145346", "145348", "145353", "145356", "145357", "145358", "145359", "145362", "145366", "145368", "145370", "145371", "145373", "145374", "145375", "145377", "145381", "145382", "145383", "145385", "145386", "145389", "145392", "145395", "145396", "145397", "145398", "145401", "145405", "145406", "145410", "145412", "145413", "145418", "145419", "145420", "145422", "145425", "145428", "145429", "145431", "145432", "145435", "145440", "145446", "145447", "145448", "145451", "145454", "145457", "145459", "145463", "145464", "145465", "145466", "145469", "145471", "145473", "145474", "145475", "145476", "145477", "145480", "145481", "145483", "145485", "145486", "145488", "145489", "145493", "145495", "145498", "145499", "145500", "145501", "145503", "145504", "145505", "145506", "145507", "145509", "145514", "145516", "145519", "145522", "145523", "145525", "145527", "145529", "145530", "145531", "145533", "145534", "145538", "145539", "145543", "145546", "145547", "145550", "145552", "145553", "145554", "145555", "145556", "145557", "145560", "145566", "145569", "145570", "145571", "145572", "145573", "145574", "145576", "145577", "145579", "145580", "145583", "145588", "145590", "145594", "145596", "145598", "145600", "145603", "145604", "145605", "145606", "145607", "145611", "145613", "145614", "145616", "145618", "145619", "145620", "145622", "145623", "145628", "145631", "145632", "145635", "145637", "145641", "145645", "145650", "145651", "145652", "145653", "145654", "145655", "145656", "145658", "145662", "145666", "145670", "145671", "145675", "145678", "145679", "145680", "145683", "145686", "145689", "145691", "145693", "145696", "145698", "145700", "145701", "145702", "145703", "145706", "145711", "145712", "145713", "145716", "145717", "145719", "145722", "145726", "145727", "145728", "145730", "145737", "145740", "145742", "145743", "145744", "145746", "145747", "145748", "145749", "145750", "145755", "145760", "145761", "145763", "145767", "145772", "145773", "145775", "145776", "145777", "145780", "145781", "145783", "145789", "145790", "145791", "145792", "145793", "145796", "145799", "145800", "145801", "145802", "145803", "145805", "145807", "145809", "145814", "145815", "145817", "145820", "145821", "145822", "145823", "145824", "145827", "145829", "145830", "145831", "145837", "145838", "145839", "145840", "145841", "145843", "145850", "145852", "145853", "145855", "145858", "145860", "145868", "145870", "145871", "145872", "145873", "145875", "145877", "145880", "145883", "145884", "145885", "145886", "145889", "145890", "145893", "145894", "145895", "145897", "145899", "145900", "145902", "145909", "145910", "145911", "145912", "145914", "145915", "145918", "145920", "145921", "145922", "145925", "145926", "145927", "145928", "145929", "145932", "145933", "145934", "145937", "145938", "145940", "145942", "145943", "145944", "145950", "145951", "145952", "145953", "145955", "145958", "145960", "145961", "145963", "145965", "145966", "145967", "145968", "145971", "145972", "145973", "145974", "145975", "145977", "145978", "145980", "145981", "145982", "145983", "145984", "145987", "145988", "145989", "145990", "145992", "145993", "145994", "145998", "145999", "146000", "146001", "146002", "146009", "146011", "146014", "146016", "146017", "146018", "146020", "146024", "146025", "146026", "146028", "146029", "146030", "146032", "146033", "146043", "146045", "146047", "146049", "146050", "146051", "146052", "146053", "146054", "146055", "146060", "146061", "146062", "146063", "146068", "146071", "146074", "146077", "146080", "146081", "146083", "146084", "146085", "146086", "146087", "146088", "146090", "146092", "146094", "146095", "146096", "146100", "146101", "146102", "146105", "146107", "146108", "146110", "146111", "146112", "146114", "146115", "146117", "146119", "146120", "146121", "146123", "146126", "146127", "146128", "146130", "146131", "146135", "146137", "146139", "146140", "146144", "146146", "146147", "146148", "146150", "146152", "146153", "146154", "146157", "146163", "146165", "146169", "146172", "146174", "146180", "146181", "146184", "146188", "146189", "146196", "146198", "146199", "146200", "146202", "146205", "146206", "146208", "146209", "146210", "146211", "146212", "146213", "146214", "146218", "146219", "146220", "146222", "146226", "146227", "146230", "146231", "146232", "146233", "146241", "146243", "146245", "146249", "146251", "146252", "146256", "146257", "146258", "146261", "146262", "146264", "146266", "146267", "146268", "146270", "146272", "146276", "146277", "146278", "146279", "146281", "146282", "146283", "146284", "146285", "146288", "146289", "146290", "146295", "146296", "146303", "146304", "146307", "146308", "146309", "146310", "146313", "146314", "146318", "146319", "146321", "146323", "146325", "146329", "146334", "146336", "146339", "146340", "146341", "146342", "146343", "146346", "146348", "146351", "146353", "146355", "146358", "146359", "146360", "146362", "146363", "146364", "146365", "146366", "146368", "146371", "146375", "146376", "146377", "146380", "146381", "146382", "146383", "146384", "146385", "146386", "146389", "146391", "146392", "146393", "146395", "146397", "146398", "146399", "146402", "146405", "146406", "146407", "146408", "146410", "146412", "146413", "146418", "146419", "146420", "146421", "146422", "146423", "146425", "146426", "146428", "146432", "146434", "146436", "146440", "146444", "146445", "146446", "146447", "146448", "146450", "146452", "146453", "146454", "146457", "146458", "146459", "146461", "146462", "146464", "146465", "146466", "146467", "146468", "146469", "146470", "146473", "146474", "146476", "146482", "146485", "146487", "146489", "146490", "146492", "146493", "146495", "146496", "146500", "146502", "146504", "146505", "146508", "146510", "146512", "146513", "146515", "146517", "146520", "146521", "146523", "146526", "146528", "146529", "146530", "146533", "146538", "146539", "146541", "146545", "146548", "146549", "146552", "146553", "146559", "146560", "146562", "146563", "146566", "146567", "146568", "146570", "146571", "146572", "146575", "146576", "146578", "146580", "146583", "146585", "146586", "146587", "146589", "146590", "146592", "146593", "146595", "146598", "146604", "146611", "146614", "146616", "146617", "146620", "146621", "146622", "146623", "146624", "146625", "146626", "146627", "146629", "146630", "146632", "146633", "146635", "146638", "146641", "146646", "146647", "146649", "146650", "146651", "146652", "146654", "146655", "146658", "146659", "146661", "146663", "146665", "146666", "146667", "146670", "146671", "146673", "146675", "146676", "146678", "146680", "146681", "146682", "146684", "146685", "146686", "146690", "146691", "146693", "146694", "146695", "146696", "146699", "146701", "146704", "146706", "146714", "146715", "146717", "146719", "146721", "146723", "146724", "146725", "146726", "146727", "146728", "146730", "146736", "146737", "146738", "146740", "146745", "146747", "146750", "146751", "146754", "146755", "146756", "146757", "146761", "146762", "146763", "146764", "146765", "146767", "146769", "146770", "146772", "146773", "146775", "146776", "146777", "146780", "146786", "146790", "146792", "146794", "146795", "146797", "146799", "146802", "146803", "146804", "146805", "146806", "146807", "146809", "146812", "146814", "146815", "146816", "146817", "146818", "146821", "146822", "146824", "146827", "146829", "146831", "146834", "146835", "146837", "146839", "146841", "146842", "146844", "146845", "146848", "146851", "146858", "146862", "146865", "146866", "146868", "146869", "146870", "146871", "146872", "146873", "146874", "146875", "146882", "146883", "146884", "146885", "146887", "146890", "146893", "146895", "146897", "146898", "146900", "146903", "146904", "146905", "146911", "146913", "146914", "146916", "146919", "146920", "146923", "146924", "146926", "146927", "146929", "146931", "146933", "146936", "146937", "146939", "146940", "146941", "146942", "146943", "146944", "146945", "146948", "146949", "146953", "146954", "146957", "146959", "146963", "146966", "146968", "146972", "146974", "146979", "146981", "146984", "146985", "146986", "146989", "146991", "146993", "146995", "146996", "147004", "147008", "147010", "147012", "147014", "147016", "147017", "147019", "147024", "147025", "147026", "147028", "147029", "147030", "147032", "147035", "147036", "147037", "147039", "147040", "147043", "147046", "147049", "147054", "147056", "147057", "147058", "147060", "147061", "147062", "147063", "147066", "147067", "147069", "147071", "147072", "147074", "147076", "147077", "147078", "147079", "147080", "147081", "147083", "147085", "147086", "147087", "147091", "147094", "147095", "147096", "147097", "147098", "147100", "147104", "147106", "147108", "147110", "147114", "147115", "147116", "147117", "147118", "147119", "147123", "147124", "147125", "147126", "147127", "147133", "147136", "147137", "147138", "147139", "147142", "147144", "147145", "147146", "147149", "147150", "147151", "147152", "147153", "147157", "147158", "147159", "147160", "147161", "147163", "147164", "147165", "147167", "147168", "147169", "147170", "147172", "147173", "147174", "147176", "147178", "147179", "147183", "147185", "147186", "147187", "147193", "147197", "147199", "147204", "147206", "147207", "147209", "147210", "147211", "147212", "147215", "147217", "147219", "147220", "147223", "147226", "147232", "147233", "147237", "147239", "147240", "147241", "147243", "147244", "147245", "147246", "147251", "147252", "147253", "147257", "147258", "147259", "147261", "147262", "147267", "147269", "147274", "147275", "147276", "147278", "147279", "147280", "147281", "147283", "147284", "147285", "147287", "147288", "147289", "147290", "147291", "147292", "147293", "147295", "147299", "147303", "147304", "147306", "147308", "147309", "147310", "147312", "147313", "147314", "147315", "147317", "147319", "147320", "147321", "147322", "147324", "147326", "147327", "147329", "147331", "147334", "147337", "147338", "147344", "147346", "147347", "147348", "147350", "147353", "147355", "147357", "147359", "147360", "147361", "147362", "147365", "147366", "147367", "147368", "147369", "147370", "147371", "147372", "147374", "147377", "147381", "147383", "147384", "147385", "147386", "147388", "147390", "147391", "147393", "147394", "147398", "147399", "147400", "147403", "147404", "147405", "147406", "147407", "147409", "147410", "147415", "147416", "147418", "147420", "147427", "147428", "147430", "147432", "147433", "147434", "147444", "147445", "147446", "147447", "147450", "147451", "147452", "147453", "147454", "147456", "147459", "147460", "147461", "147463", "147464", "147469", "147470", "147471", "147472", "147473", "147474", "147475", "147477", "147479", "147480", "147481", "147489", "147491", "147493", "147495", "147497", "147502", "147505", "147506", "147508", "147509", "147512", "147514", "147516", "147517", "147518", "147520", "147523", "147525", "147527", "147528", "147531", "147538", "147540", "147544", "147547", "147548", "147550", "147553", "147554", "147556", "147557", "147558", "147559", "147561", "147563", "147566", "147568", "147570", "147572", "147574", "147575", "147578", "147579", "147581", "147583", "147585", "147587", "147588", "147589", "147591", "147595", "147596", "147597", "147598", "147599", "147600", "147602", "147603", "147604", "147605", "147609", "147610", "147612", "147616", "147617", "147618", "147623", "147624", "147626", "147627", "147628", "147629", "147631", "147635", "147636", "147638", "147639", "147640", "147642", "147643", "147646", "147649", "147652", "147653", "147654", "147656", "147661", "147662", "147666", "147667", "147668", "147669", "147670", "147671", "147674", "147675", "147676", "147677", "147680", "147681", "147683", "147684", "147685", "147688", "147690", "147691", "147693", "147694", "147695", "147697", "147699", "147701", "147702", "147703", "147704", "147705", "147707", "147708", "147710", "147711", "147712", "147714", "147717", "147718", "147722", "147724", "147727", "147729", "147730", "147732", "147737", "147738", "147739", "147742", "147743", "147749", "147750", "147751", "147752", "147755", "147756", "147760", "147763", "147767", "147768", "147769", "147770", "147777", "147779", "147782", "147784", "147787", "147788", "147791", "147792", "147793", "147795", "147798", "147802", "147803", "147807", "147809", "147810", "147815", "147816", "147818", "147820", "147823", "147827", "147828", "147830", "147835", "147836", "147837", "147838", "147839", "147841", "147843", "147845", "147848", "147851", "147852", "147856", "147858", "147859", "147861", "147862", "147866", "147867", "147871", "147872", "147875", "147876", "147877", "147878", "147883", "147885", "147888", "147889", "147891", "147892", "147893", "147894", "147897", "147900", "147902", "147907", "147908", "147910", "147911", "147918", "147919", "147920", "147921", "147922", "147923", "147925", "147926", "147928", "147929", "147930", "147931", "147933", "147934", "147935", "147937", "147941", "147943", "147944", "147945", "147946", "147948", "147950", "147951", "147952", "147953", "147955", "147956", "147959", "147960", "147964", "147966", "147967", "147970", "147971", "147976", "147977", "147980", "147983", "147984", "147987", "147989", "147992", "147995", "147996", "147999", "148000", "148002", "148005", "148007", "148008", "148009", "148011", "148013", "148015", "148016", "148018", "148020", "148021", "148022", "148023", "148024", "148025", "148028", "148030", "148031", "148033", "148036", "148037", "148040", "148045", "148046", "148050", "148053", "148054", "148055", "148056", "148059", "148060", "148061", "148062", "148064", "148066", "148071", "148072", "148073", "148075", "148076", "148077", "148079", "148080", "148081", "148084", "148085", "148086", "148088", "148089", "148092", "148093", "148096", "148098", "148100", "148102", "148103", "148104", "148106", "148108", "148109", "148110", "148113", "148114", "148115", "148116", "148117", "148119", "148120", "148121", "148122", "148123", "148124", "148125", "148126", "148127", "148129", "148131", "148132", "148134", "148136", "148137", "148138", "148139", "148141", "148144", "148146", "148148", "148151", "148152", "148154", "148156", "148160", "148168", "148169", "148170", "148174", "148175", "148176", "148178", "148179", "148181", "148184", "148186", "148189", "148191", "148193", "148201", "148206", "148208", "148209", "148210", "148211", "148212", "148213", "148214", "148216", "148217", "148221", "148222", "148223", "148224", "148225", "148226", "148227", "148229", "148231", "148232", "148233", "148235", "148236", "148241", "148242", "148245", "148250", "148253", "148255", "148256", "148257", "148259", "148262", "148265", "148266", "148267", "148268", "148269", "148270", "148271", "148272", "148273", "148274", "148278", "148281", "148282", "148283", "148290", "148295", "148296", "148297", "148298", "148301", "148303", "148305", "148306", "148307", "148308", "148309", "148312", "148317", "148321", "148323", "148324", "148325", "148326", "148328", "148329", "148330", "148331", "148334", "148335", "148338", "148339", "148341", "148344", "148345", "148350", "148351", "148352", "148354", "148358", "148360", "148361", "148362", "148364", "148369", "148371", "148375", "148378", "148379", "148382", "148383", "148384", "148385", "148387", "148388", "148392", "148393", "148396", "148398", "148400", "148401", "148404", "148408", "148409", "148410", "148411", "148414", "148416", "148418", "148419", "148421", "148422", "148423", "148426", "148427", "148428", "148429", "148430", "148432", "148434", "148440", "148442", "148443", "148444", "148445", "148446", "148447", "148453", "148455", "148456", "148457", "148458", "148462", "148463", "148466", "148467", "148469", "148471", "148472", "148473", "148475", "148477", "148480", "148483", "148484", "148485", "148487", "148489", "148490", "148493", "148494", "148496", "148498", "148499", "148500", "148501", "148502", "148505", "148507", "148509", "148513", "148516", "148517", "148519", "148520", "148521", "148523", "148524", "148528", "148530", "148531", "148533", "148535", "148536", "148538", "148541", "148542", "148543", "148544", "148545", "148554", "148556", "148558", "148560", "148561", "148563", "148567", "148568", "148569", "148572", "148573", "148577", "148579", "148582", "148585", "148586", "148587", "148589", "148591", "148593", "148596", "148600", "148603", "148604", "148605", "148606", "148607", "148613", "148614", "148616", "148619", "148621", "148622", "148623", "148624", "148625", "148626", "148629", "148630", "148632", "148634", "148636", "148638", "148639", "148641", "148642", "148644", "148647", "148648", "148649", "148650", "148654", "148655", "148656", "148657", "148658", "148659", "148660", "148664", "148665", "148666", "148667", "148668", "148672", "148673", "148674", "148677", "148679", "148680", "148682", "148683", "148684", "148686", "148690", "148691", "148693", "148695", "148696", "148698", "148700", "148701", "148703", "148704", "148710", "148711", "148712", "148713", "148715", "148717", "148720", "148722", "148730", "148731", "148732", "148735", "148738", "148740", "148741", "148742", "148743", "148747", "148751", "148752", "148754", "148755", "148758", "148759", "148767", "148771", "148772", "148773", "148775", "148776", "148780", "148783", "148786", "148787", "148790", "148792", "148798", "148799", "148801", "148802", "148803", "148805", "148807", "148808", "148812", "148813", "148817", "148819", "148820", "148821", "148823", "148824", "148825", "148827", "148828", "148829", "148832", "148833", "148839", "148840", "148841", "148844", "148845", "148848", "148849", "148854", "148856", "148857", "148858", "148861", "148862", "148864", "148865", "148866", "148868", "148870", "148871", "148872", "148875", "148877", "148878", "148880", "148881", "148883", "148888", "148890", "148891", "148894", "148895", "148897", "148899", "148900", "148903", "148907", "148909", "148910", "148913", "148914", "148915", "148919", "148921", "148924", "148925", "148927", "148928", "148929", "148930", "148934", "148935", "148938", "148942", "148945", "148947", "148951", "148952", "148955", "148956", "148957", "148958", "148959", "148960", "148962", "148963", "148964", "148965", "148966", "148967", "148971", "148972", "148973", "148975", "148978", "148981", "148982", "148984", "148986", "148989", "148990", "148992", "148993", "148995", "149000", "149007", "149008", "149009", "149012", "149014", "149015", "149021", "149022", "149025", "149026", "149027", "149029", "149030", "149031", "149032", "149033", "149034", "149035", "149037", "149038", "149040", "149041", "149042", "149045", "149047", "149049", "149050", "149052", "149053", "149059", "149060", "149062", "149067", "149068", "149069", "149070", "149072", "149073", "149074", "149075", "149076", "149078", "149080", "149081", "149084", "149086", "149088", "149090", "149091", "149092", "149093", "149094", "149095", "149097", "149100", "149101", "149104", "149107", "149108", "149112", "149114", "149116", "149117", "149119", "149120", "149123", "149124", "149126", "149127", "149128", "149129", "149131", "149133", "149135", "149136", "149137", "149138", "149139", "149140", "149142", "149145", "149148", "149149", "149154", "149156", "149160", "149161", "149162", "149169", "149170", "149171", "149172", "149175", "149178", "149180", "149183", "149186", "149187", "149188", "149189", "149192", "149196", "149197", "149198", "149199", "149200", "149202", "149203", "149205", "149206", "149207", "149211", "149213", "149215", "149216", "149219", "149220", "149221", "149223", "149225", "149226", "149230", "149233", "149234", "149237", "149239", "149240", "149242", "149245", "149247", "149248", "149249", "149251", "149254", "149256", "149259", "149260", "149261", "149262", "149264", "149265", "149267", "149270", "149272", "149273", "149274", "149276", "149278", "149280", "149281", "149282", "149283", "149284", "149285", "149286", "149289", "149295", "149296", "149297", "149298", "149300", "149301", "149303", "149309", "149310", "149311", "149312", "149313", "149314", "149317", "149318", "149319", "149321", "149322", "149324", "149328", "149329", "149332", "149333", "149336", "149338", "149339", "149342", "149343", "149344", "149347", "149348", "149353", "149354", "149360", "149362", "149363", "149369", "149370", "149372", "149374", "149376", "149378", "149382", "149385", "149386", "149389", "149393", "149394", "149398", "149399", "149400", "149403", "149410", "149422", "149423", "149424", "149425", "149426", "149428", "149429", "149430", "149432", "149434", "149435", "149438", "149439", "149441", "149442", "149443", "149445", "149446", "149448", "149449", "149450", "149453", "149457", "149458", "149459", "149463", "149464", "149465", "149466", "149470", "149471", "149474", "149475", "149477", "149478", "149479", "149481", "149482", "149483", "149484", "149486", "149491", "149492", "149493", "149494", "149495", "149496", "149497", "149499", "149501", "149503", "149504", "149507", "149508", "149509", "149511", "149512", "149514", "149515", "149518", "149519", "149521", "149524", "149530", "149532", "149533", "149535", "149536", "149537", "149539", "149542", "149544", "149545", "149546", "149548", "149549", "149551", "149552", "149556", "149557", "149559", "149561", "149563", "149564", "149565", "149566", "149567", "149568", "149570", "149571", "149572", "149573", "149575", "149579", "149580", "149581", "149584", "149585", "149587", "149588", "149590", "149591", "149592", "149595", "149597", "149598", "149599", "149603", "149606", "149607", "149608", "149611", "149613", "149615", "149617", "149621", "149625", "149626", "149627", "149628", "149632", "149634", "149635", "149636", "149637", "149639", "149640", "149641", "149642", "149643", "149644", "149645", "149646", "149647", "149648", "149649", "149650", "149651", "149652", "149653", "149655", "149659", "149662", "149663", "149664", "149665", "149666", "149667", "149668", "149673", "149677", "149678", "149683", "149684", "149686", "149690", "149691", "149695", "149700", "149701", "149702", "149706", "149707", "149708", "149711", "149712", "149713", "149714", "149715", "149716", "149717", "149718", "149720", "149721", "149724", "149725", "149727", "149728", "149730", "149731", "149733", "149735", "149736", "149738", "149739", "149741", "149742", "149744", "149746", "149753", "149755", "149756", "149762", "149766", "149767", "149772", "149776", "149781", "149782", "149785", "149787", "149788", "149789", "149791", "149792", "149799", "149801", "149802", "149804", "149805", "149806", "149815", "149816", "149817", "149819", "149821", "149823", "149824", "149826", "149827", "149830", "149833", "149837", "149839", "149840", "149844", "149845", "149847", "149850", "149851", "149853", "149858", "149860", "149861", "149864", "149867", "149870", "149871", "149872", "149873", "149874", "149876", "149878", "149879", "149880", "149881", "149882", "149883", "149886", "149889", "149890", "149891", "149893", "149894", "149897", "149902", "149903", "149904", "149906", "149907", "149908", "149909", "149912", "149913", "149914", "149917", "149918", "149919", "149920", "149922", "149925", "149927", "149931", "149932", "149933", "149934", "149935", "149936", "149938", "149941", "149942", "149945", "149946", "149947", "149950", "149951", "149956", "149957", "149959", "149961", "149963", "149965", "149966", "149967", "149968", "149969", "149970", "149971", "149972", "149973", "149974", "149975", "149976", "149977", "149978", "149981", "149982", "149985", "149987", "149988", "149989", "149991", "149992", "149993", "149994", "149995", "149996", "149997", "149998", "149999", "150002", "150003", "150005", "150006", "150007", "150008", "150012", "150013", "150014", "150017", "150020", "150022", "150024", "150026", "150029", "150030", "150032", "150034", "150035", "150036", "150038", "150043", "150044", "150045", "150046", "150047", "150048", "150053", "150054", "150059", "150062", "150063", "150068", "150069", "150071", "150077", "150078", "150079", "150081", "150082", "150084", "150088", "150097", "150098", "150099", "150100", "150102", "150104", "150105", "150109", "150110", "150112", "150115", "150117", "150118", "150120", "150121", "150122", "150123", "150124", "150125", "150126", "150127", "150128", "150129", "150130", "150131", "150136", "150137", "150139", "150144", "150145", "150146", "150147", "150148", "150150", "150151", "150152", "150153", "150154", "150155", "150156", "150157", "150158", "150159", "150163", "150164", "150165", "150167", "150168", "150170", "150171", "150173", "150175", "150177", "150178", "150180", "150182", "150183", "150184", "150186", "150189", "150196", "150197", "150198", "150199", "150200", "150201", "150202", "150204", "150206", "150208", "150210", "150213", "150214", "150218", "150219", "150221", "150222", "150223", "150224", "150225", "150229", "150230", "150235", "150236", "150237", "150238", "150239", "150241", "150244", "150246", "150247", "150249", "150251", "150254", "150256", "150258", "150262", "150265", "150267", "150268", "150270", "150271", "150272", "150277", "150279", "150280", "150282", "150283", "150287", "150288", "150290", "150291", "150292", "150293", "150294", "150295", "150296", "150297", "150300", "150301", "150302", "150309", "150310", "150313", "150315", "150318", "150319", "150324", "150328", "150331", "150335", "150337", "150339", "150340", "150344", "150348", "150351", "150356", "150359", "150361", "150362", "150363", "150364", "150365", "150366", "150369", "150370", "150372", "150373", "150375", "150376", "150377", "150378", "150379", "150381", "150382", "150383", "150384", "150385", "150387", "150388", "150392", "150393", "150400", "150401", "150403", "150406", "150408", "150409", "150411", "150412", "150415", "150416", "150418", "150420", "150424", "150425", "150429", "150430", "150431", "150432", "150433", "150434", "150435", "150437", "150439", "150441", "150442", "150445", "150447", "150448", "150449", "150450", "150453", "150454", "150455", "150458", "150459", "150465", "150467", "150468", "150469", "150470", "150472", "150475", "150478", "150480", "150481", "150485", "150486", "150492", "150493", "150496", "150498", "150500", "150501", "150503", "150504", "150505", "150509", "150512", "150513", "150514", "150517", "150520", "150522", "150523", "150524", "150525", "150528", "150531", "150537", "150538", "150539", "150541", "150543", "150544", "150545", "150553", "150554", "150555", "150556", "150557", "150558", "150560", "150561", "150563", "150567", "150568", "150571", "150573", "150574", "150576", "150577", "150579", "150581", "150583", "150584", "150586", "150589", "150590", "150593", "150594", "150596", "150600", "150601", "150602", "150603", "150604", "150605", "150607", "150611", "150614", "150617", "150618", "150619", "150623", "150625", "150633", "150634", "150635", "150637", "150638", "150640", "150641", "150642", "150643", "150644", "150645", "150648", "150649", "150651", "150653", "150658", "150666", "150667", "150670", "150672", "150673", "150675", "150676", "150681", "150682", "150687", "150688", "150689", "150694", "150695", "150700", "150702", "150704", "150705", "150708", "150710", "150715", "150717", "150718", "150722", "150724", "150725", "150726", "150728", "150730", "150731", "150732", "150735", "150737", "150739", "150740", "150744", "150746", "150748", "150749", "150750", "150751", "150755", "150757", "150759", "150762", "150769", "150770", "150771", "150774", "150775", "150777", "150779", "150780", "150781", "150784", "150786", "150788", "150789", "150790", "150791", "150792", "150793", "150795", "150798", "150799", "150801", "150802", "150803", "150806", "150808", "150809", "150810", "150811", "150813", "150818", "150819", "150822", "150823", "150825", "150828", "150829", "150831", "150833", "150834", "150837", "150840", "150842", "150844", "150845", "150846", "150847", "150850", "150853", "150854", "150855", "150858", "150859", "150860", "150861", "150862", "150864", "150865", "150867", "150870", "150871", "150872", "150878", "150879", "150882", "150883", "150884", "150885", "150886", "150888", "150889", "150891", "150895", "150898", "150900", "150904", "150906", "150909", "150913", "150916", "150917", "150918", "150919", "150921", "150922", "150923", "150928", "150929", "150930", "150931", "150932", "150934", "150936", "150937", "150938", "150944", "150945", "150946", "150948", "150949", "150951", "150953", "150954", "150958", "150959", "150961", "150963", "150964", "150965", "150968", "150970", "150973", "150974", "150979", "150980", "150981", "150982", "150983", "150986", "150988", "150993", "150995", "150997", "150998", "151000", "151001", "151005", "151009", "151011", "151013", "151014", "151015", "151017", "151019", "151021", "151022", "151023", "151026", "151027", "151033", "151035", "151036", "151037", "151040", "151042", "151043", "151044", "151045", "151046", "151048", "151052", "151057", "151058", "151061", "151062", "151063", "151064", "151066", "151069", "151073", "151076", "151078", "151079", "151080", "151090", "151091", "151093", "151094", "151097", "151098", "151103", "151106", "151107", "151110", "151111", "151112", "151114", "151116", "151117", "151118", "151120", "151122", "151123", "151125", "151126", "151127", "151129", "151130", "151132", "151136", "151138", "151140", "151141", "151142", "151143", "151144", "151147", "151148", "151149", "151150", "151151", "151152", "151156", "151157", "151163", "151164", "151165", "151167", "151171", "151174", "151175", "151178", "151179", "151180", "151181", "151182", "151183", "151185", "151186", "151192", "151193", "151194", "151196", "151197", "151198", "151199", "151200", "151201", "151202", "151203", "151204", "151205", "151207", "151212", "151213", "151214", "151216", "151218", "151220", "151221", "151223", "151224", "151225", "151226", "151227", "151228", "151230", "151234", "151236", "151237", "151239", "151240", "151241", "151242", "151243", "151244", "151251", "151252", "151253", "151256", "151259", "151263", "151265", "151266", "151267", "151268", "151269", "151270", "151273", "151274", "151277", "151278", "151281", "151283", "151286", "151287", "151292", "151294", "151295", "151296", "151299", "151304", "151305", "151307", "151308", "151310", "151311", "151313", "151314", "151315", "151317", "151318", "151319", "151320", "151321", "151322", "151324", "151326", "151328", "151330", "151333", "151335", "151336", "151340", "151341", "151342", "151343", "151345", "151346", "151347", "151348", "151351", "151352", "151353", "151357", "151360", "151362", "151363", "151365", "151366", "151367", "151368", "151370", "151371", "151376", "151377", "151378", "151379", "151380", "151381", "151383", "151384", "151385", "151386", "151387", "151389", "151391", "151392", "151393", "151396", "151399", "151403", "151404", "151405", "151408", "151410", "151411", "151417", "151418", "151420", "151421", "151424", "151425", "151427", "151429", "151430", "151431", "151432", "151433", "151438", "151439", "151442", "151443", "151447", "151448", "151450", "151451", "151455", "151456", "151457", "151458", "151459", "151462", "151464", "151466", "151467", "151471", "151472", "151475", "151476", "151477", "151481", "151482", "151483", "151484", "151485", "151489", "151491", "151492", "151493", "151494", "151495", "151496", "151500", "151501", "151502", "151503", "151510", "151511", "151514", "151517", "151520", "151521", "151522", "151523", "151525", "151527", "151528", "151529", "151530", "151531", "151532", "151534", "151536", "151537", "151538", "151539", "151543", "151545", "151546", "151547", "151550", "151551", "151555", "151556", "151557", "151559", "151560", "151561", "151563", "151564", "151565", "151567", "151570", "151572", "151573", "151577", "151579", "151580", "151582", "151583", "151587", "151589", "151590", "151591", "151594", "151599", "151602", "151603", "151605", "151607", "151608", "151609", "151613", "151614", "151615", "151617", "151618", "151620", "151622", "151623", "151629", "151630", "151634", "151640", "151641", "151642", "151644", "151647", "151648", "151649", "151651", "151654", "151655", "151659", "151660", "151661", "151663", "151666", "151667", "151668", "151669", "151671", "151672", "151674", "151676", "151679", "151682", "151689", "151692", "151693", "151695", "151696", "151698", "151699"]]
+}
\ No newline at end of file
diff --git a/AutoDL-Projects/configs/nas-benchmark/LESS.config b/AutoDL-Projects/configs/nas-benchmark/LESS.config
new file mode 100644
index 0000000..05e308e
--- /dev/null
+++ b/AutoDL-Projects/configs/nas-benchmark/LESS.config
@@ -0,0 +1,13 @@
+{
+ "scheduler": ["str", "cos"],
+ "eta_min" : ["float", "0.0"],
+ "epochs" : ["int", "12"],
+ "warmup" : ["int", "0"],
+ "optim" : ["str", "SGD"],
+ "LR" : ["float", "0.1"],
+ "decay" : ["float", "0.0005"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "1"],
+ "criterion": ["str", "Softmax"],
+ "batch_size": ["int", "256"]
+}
diff --git a/AutoDL-Projects/configs/nas-benchmark/algos/DARTS.config b/AutoDL-Projects/configs/nas-benchmark/algos/DARTS.config
new file mode 100644
index 0000000..4fb4a27
--- /dev/null
+++ b/AutoDL-Projects/configs/nas-benchmark/algos/DARTS.config
@@ -0,0 +1,13 @@
+{
+ "scheduler": ["str", "cos"],
+ "LR" : ["float", "0.025"],
+ "eta_min" : ["float", "0.001"],
+ "epochs" : ["int", "50"],
+ "warmup" : ["int", "0"],
+ "optim" : ["str", "SGD"],
+ "decay" : ["float", "0.0005"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "1"],
+ "criterion": ["str", "Softmax"],
+ "batch_size": ["int", "64"]
+}
diff --git a/AutoDL-Projects/configs/nas-benchmark/algos/ENAS.config b/AutoDL-Projects/configs/nas-benchmark/algos/ENAS.config
new file mode 100644
index 0000000..5e32b86
--- /dev/null
+++ b/AutoDL-Projects/configs/nas-benchmark/algos/ENAS.config
@@ -0,0 +1,17 @@
+{
+ "scheduler": ["str", "cos"],
+ "LR" : ["float", "0.05"],
+ "eta_min" : ["float", "0.0005"],
+ "epochs" : ["int", "250"],
+ "T_max" : ["int", "10"],
+ "warmup" : ["int", "0"],
+ "optim" : ["str", "SGD"],
+ "decay" : ["float", "0.00025"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "1"],
+ "controller_lr" : ["float", "0.001"],
+ "controller_betas": ["float", [0, 0.999]],
+ "controller_eps" : ["float", 0.001],
+ "criterion": ["str", "Softmax"],
+ "batch_size": ["int", "128"]
+}
diff --git a/AutoDL-Projects/configs/nas-benchmark/algos/GDAS.config b/AutoDL-Projects/configs/nas-benchmark/algos/GDAS.config
new file mode 100644
index 0000000..8fca4d7
--- /dev/null
+++ b/AutoDL-Projects/configs/nas-benchmark/algos/GDAS.config
@@ -0,0 +1,13 @@
+{
+ "scheduler": ["str", "cos"],
+ "LR" : ["float", "0.025"],
+ "eta_min" : ["float", "0.001"],
+ "epochs" : ["int", "250"],
+ "warmup" : ["int", "0"],
+ "optim" : ["str", "SGD"],
+ "decay" : ["float", "0.0005"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "1"],
+ "criterion": ["str", "Softmax"],
+ "batch_size": ["int", "64"]
+}
diff --git a/AutoDL-Projects/configs/nas-benchmark/algos/R-EA.config b/AutoDL-Projects/configs/nas-benchmark/algos/R-EA.config
new file mode 100644
index 0000000..05e9979
--- /dev/null
+++ b/AutoDL-Projects/configs/nas-benchmark/algos/R-EA.config
@@ -0,0 +1,13 @@
+{
+ "scheduler": ["str", "cos"],
+ "eta_min" : ["float", "0.001"],
+ "epochs" : ["int", "25"],
+ "warmup" : ["int", "0"],
+ "optim" : ["str", "SGD"],
+ "LR" : ["float", "0.025"],
+ "decay" : ["float", "0.0005"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "1"],
+ "criterion": ["str", "Softmax"],
+ "batch_size": ["int", "64"]
+}
diff --git a/AutoDL-Projects/configs/nas-benchmark/algos/RANDOM.config b/AutoDL-Projects/configs/nas-benchmark/algos/RANDOM.config
new file mode 100644
index 0000000..e2d956d
--- /dev/null
+++ b/AutoDL-Projects/configs/nas-benchmark/algos/RANDOM.config
@@ -0,0 +1,14 @@
+{
+ "scheduler": ["str", "cos"],
+ "LR" : ["float", "0.025"],
+ "eta_min" : ["float", "0.001"],
+ "epochs" : ["int", "250"],
+ "warmup" : ["int", "0"],
+ "optim" : ["str", "SGD"],
+ "decay" : ["float", "0.0005"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "1"],
+ "criterion": ["str", "Softmax"],
+ "batch_size": ["int", "64"],
+ "test_batch_size": ["int", "512"]
+}
diff --git a/AutoDL-Projects/configs/nas-benchmark/algos/SETN.config b/AutoDL-Projects/configs/nas-benchmark/algos/SETN.config
new file mode 100644
index 0000000..e2d956d
--- /dev/null
+++ b/AutoDL-Projects/configs/nas-benchmark/algos/SETN.config
@@ -0,0 +1,14 @@
+{
+ "scheduler": ["str", "cos"],
+ "LR" : ["float", "0.025"],
+ "eta_min" : ["float", "0.001"],
+ "epochs" : ["int", "250"],
+ "warmup" : ["int", "0"],
+ "optim" : ["str", "SGD"],
+ "decay" : ["float", "0.0005"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "1"],
+ "criterion": ["str", "Softmax"],
+ "batch_size": ["int", "64"],
+ "test_batch_size": ["int", "512"]
+}
diff --git a/AutoDL-Projects/configs/nas-benchmark/algos/weight-sharing.config b/AutoDL-Projects/configs/nas-benchmark/algos/weight-sharing.config
new file mode 100644
index 0000000..18199c9
--- /dev/null
+++ b/AutoDL-Projects/configs/nas-benchmark/algos/weight-sharing.config
@@ -0,0 +1,14 @@
+{
+ "scheduler": ["str", "cos"],
+ "LR" : ["float", "0.025"],
+ "eta_min" : ["float", "0.001"],
+ "epochs" : ["int", "100"],
+ "warmup" : ["int", "0"],
+ "optim" : ["str", "SGD"],
+ "decay" : ["float", "0.0005"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "1"],
+ "criterion": ["str", "Softmax"],
+ "batch_size": ["int", "64"],
+ "test_batch_size": ["int", "512"]
+}
diff --git a/AutoDL-Projects/configs/nas-benchmark/cifar-split.txt b/AutoDL-Projects/configs/nas-benchmark/cifar-split.txt
new file mode 100644
index 0000000..56b7665
--- /dev/null
+++ b/AutoDL-Projects/configs/nas-benchmark/cifar-split.txt
@@ -0,0 +1,4 @@
+{
+ "train" : ["int" , ["0", "5", "7", "11", "13", "15", "16", "17", "20", "24", "26", "28", "30", "31", "32", "34", "36", "37", "39", "40", "43", "46", "48", "49", "50", "52", "53", "55", "56", "58", "60", "66", "68", "69", "74", "75", "77", "78", "79", "81", "86", "88", "90", "93", "94", "96", "97", "100", "101", "103", "104", "106", "107", "109", "111", "112", "113", "114", "115", "117", "118", "120", "122", "123", "124", "125", "126", "128", "129", "131", "132", "134", "135", "136", "137", "139", "140", "141", "142", "144", "147", "148", "151", "152", "155", "156", "158", "161", "162", "164", "165", "166", "167", "168", "169", "170", "171", "172", "173", "174", "175", "178", "179", "185", "188", "189", "192", "193", "195", "196", "197", "203", "204", "205", "206", "207", "209", "210", "211", "212", "213", "216", "217", "225", "226", "227", "228", "229", "231", "233", "241", "243", "245", "247", "250", "251", "252", "254", "255", "256", "257", "259", "262", "263", "268", "269", "271", "272", "273", "275", "276", "278", "280", "282", "284", "287", "288", "291", "295", "296", "297", "300", "301", "302", "303", "305", "312", "315", "317", "318", "319", "322", "323", "327", "328", "329", "332", "333", "335", "336", "338", "340", "341", "343", "347", "351", "355", "361", "364", "367", "369", "370", "371", "372", "375", "376", "380", "381", "386", "387", "388", "389", "397", "398", "399", "400", "402", "403", "405", "406", "408", "412", "414", "415", "422", "424", "425", "430", "431", "432", "433", "434", "435", "438", "439", "440", "443", "444", "445", "451", "452", "453", "454", "456", "457", "461", "465", "466", "469", "471", "476", "478", "483", "484", "487", "493", "497", "498", "500", "503", "504", "506", "507", "508", "510", "513", "514", "516", "522", "525", "527", "529", "531", "532", "533", "535", "539", "544", "545", "546", "547", "548", "549", "551", "553", "554", "557", "564", "565", "567", "568", "572", "573", "578", "579", "582", "584", "585", "589", "590", "591", "595", "596", "597", "598", "600", "601", "602", "604", "605", "608", "612", "615", "619", "620", "621", "624", "625", "626", "627", "629", "631", "634", "637", "639", "641", "643", "645", "649", "650", "652", "653", "655", "666", "668", "670", "671", "673", "674", "676", "677", "679", "680", "683", "686", "687", "688", "691", "694", "695", "696", "700", "705", "707", "710", "716", "717", "721", "722", "724", "727", "729", "731", "732", "734", "735", "737", "738", "739", "741", "742", "748", "751", "752", "756", "760", "761", "765", "768", "771", "774", "775", "777", "781", "783", "784", "785", "787", "789", "790", "791", "793", "794", "797", "798", "799", "800", "803", "807", "809", "811", "812", "815", "816", "817", "819", "820", "821", "822", "823", "825", "827", "828", "831", "832", "833", "837", "838", "841", "842", "846", "853", "854", "855", "857", "859", "861", "864", "868", "869", "870", "871", "872", "873", "876", "881", "885", "887", "889", "896", "897", "899", "900", "901", "902", "903", "905", "906", "907", "909", "910", "911", "912", "913", "914", "918", "919", "922", "923", "925", "927", "934", "935", "937", "944", "945", "946", "948", "951", "953", "954", "957", "958", "959", "960", "961", "964", "965", "966", "967", "968", "970", "972", "973", "975", "978", "979", "980", "981", "986", "987", "988", "990", "991", "992", "993", "994", "995", "996", "997", "1005", "1006", "1008", "1009", "1012", "1014", "1015", "1018", "1021", "1022", "1023", "1024", "1029", "1030", "1032", "1035", "1037", "1038", "1042", "1043", "1044", "1047", "1049", "1052", "1053", "1055", "1056", "1057", "1062", "1063", "1065", "1066", "1067", "1068", "1071", "1074", "1076", "1077", "1079", "1080", "1081", "1084", "1085", "1087", "1091", "1094", "1096", "1100", "1101", "1102", "1103", "1106", "1107", "1108", "1109", "1110", "1111", "1112", "1113", "1115", "1116", "1117", "1118", "1119", "1123", "1129", "1132", "1135", "1137", "1138", "1139", "1140", "1142", "1143", "1144", "1150", "1151", "1154", "1155", "1156", "1157", "1158", "1160", "1162", "1165", "1166", "1171", "1175", "1177", "1179", "1180", "1181", "1184", "1185", "1186", "1187", "1193", "1194", "1199", "1202", "1208", "1213", "1214", "1217", "1219", "1220", "1223", "1225", "1226", "1227", "1228", "1229", "1231", "1233", "1235", "1236", "1237", "1238", "1239", "1242", "1243", "1244", "1245", "1246", "1249", "1251", "1252", "1256", "1257", "1260", "1264", "1266", "1269", "1272", "1274", "1276", "1277", "1278", "1279", "1280", "1282", "1283", "1285", "1286", "1287", "1288", "1289", "1291", "1292", "1294", "1295", "1297", "1298", "1300", "1302", "1304", "1305", "1306", "1308", "1310", "1311", "1313", "1316", "1317", "1318", "1319", "1320", "1321", "1322", "1324", "1325", "1327", "1329", "1331", "1334", "1335", "1338", "1339", "1341", "1342", "1348", "1351", "1352", "1354", "1355", "1357", "1363", "1367", "1369", "1372", "1375", "1376", "1378", "1380", "1381", "1383", "1386", "1388", "1389", "1390", "1391", "1392", "1393", "1395", "1396", "1401", "1403", "1406", "1410", "1414", "1415", "1419", "1420", "1421", "1422", "1425", "1426", "1427", "1429", "1432", "1434", "1439", "1444", "1445", "1446", "1448", "1450", "1454", "1456", "1458", "1460", "1461", "1463", "1467", "1469", "1472", "1475", "1479", "1482", "1483", "1484", "1486", "1487", "1490", "1492", "1493", "1497", "1503", "1504", "1506", "1507", "1510", "1511", "1512", "1513", "1516", "1518", "1520", "1522", "1523", "1524", "1525", "1526", "1527", "1531", "1532", "1534", "1536", "1538", "1539", "1541", "1544", "1545", "1546", "1547", "1548", "1550", "1551", "1552", "1553", "1555", "1556", "1559", "1561", "1563", "1564", "1566", "1570", "1579", "1580", "1581", "1585", "1586", "1587", "1589", "1590", "1591", "1593", "1594", "1595", "1604", "1605", "1608", "1609", "1612", "1614", "1620", "1622", "1623", "1625", "1626", "1628", "1632", "1634", "1635", "1636", "1637", "1638", "1639", "1640", "1641", "1642", "1651", "1652", "1654", "1656", "1660", "1661", "1663", "1664", "1665", "1668", "1669", "1670", "1671", "1673", "1674", "1676", "1677", "1684", "1685", "1686", "1687", "1688", "1690", "1691", "1695", "1697", "1699", "1700", "1701", "1704", "1705", "1709", "1710", "1711", "1712", "1713", "1715", "1717", "1718", "1720", "1721", "1722", "1723", "1724", "1733", "1734", "1739", "1740", "1741", "1742", "1744", "1746", "1748", "1749", "1750", "1752", "1754", "1756", "1757", "1759", "1760", "1761", "1763", "1765", "1766", "1767", "1768", "1769", "1770", "1771", "1772", "1775", "1776", "1777", "1778", "1784", "1788", "1790", "1791", "1792", "1798", "1803", "1805", "1806", "1810", "1812", "1815", "1817", "1819", "1820", "1826", "1829", "1831", "1833", "1834", "1835", "1837", "1840", "1841", "1844", "1845", "1846", "1849", "1850", "1851", "1852", "1853", "1855", "1862", "1864", "1865", "1869", "1871", "1872", "1874", "1876", "1880", "1882", "1883", "1885", "1887", "1888", "1889", "1891", "1892", "1893", "1895", "1896", "1897", "1899", "1900", "1901", "1904", "1905", "1906", "1908", "1912", "1914", "1915", "1916", "1920", "1923", "1924", "1925", "1926", "1932", "1934", "1935", "1936", "1937", "1939", "1943", "1945", "1946", "1947", "1949", "1951", "1955", "1956", "1962", "1966", "1969", "1970", "1971", "1972", "1973", "1974", "1975", "1979", "1980", "1981", "1983", "1985", "1986", "1990", "1991", "1992", "1997", "1998", "2001", "2002", "2003", "2005", "2006", "2008", "2009", "2010", "2015", "2016", "2018", "2019", "2020", "2021", "2022", "2023", "2028", "2029", "2030", "2031", "2033", "2037", "2040", "2042", "2047", "2049", "2051", "2053", "2055", "2056", "2061", "2062", "2065", "2066", "2067", "2068", "2069", "2070", "2071", "2072", "2074", "2076", "2079", "2081", "2083", "2084", "2085", "2086", "2088", "2091", "2092", "2093", "2096", "2098", "2099", "2100", "2102", "2103", "2104", "2105", "2106", "2107", "2110", "2111", "2113", "2114", "2119", "2122", "2125", "2126", "2127", "2128", "2131", "2135", "2138", "2140", "2142", "2143", "2145", "2147", "2149", "2150", "2151", "2152", "2153", "2156", "2157", "2159", "2160", "2161", "2163", "2168", "2170", "2173", "2174", "2175", "2176", "2179", "2180", "2181", "2182", "2183", "2187", "2188", "2189", "2193", "2194", "2196", "2198", "2200", "2201", "2204", "2205", "2206", "2207", "2211", "2213", "2214", "2215", "2217", "2218", "2226", "2227", "2229", "2230", "2233", "2234", "2235", "2240", "2241", "2242", "2245", "2248", "2249", "2250", "2251", "2252", "2254", "2255", "2257", "2258", "2259", "2260", "2266", "2267", "2269", "2271", "2272", "2273", "2274", "2275", "2276", "2284", "2286", "2289", "2291", "2294", "2295", "2299", "2301", "2302", "2303", "2304", "2309", "2312", "2313", "2315", "2316", "2318", "2319", "2321", "2322", "2323", "2324", "2325", "2327", "2329", "2330", "2333", "2338", "2340", "2343", "2344", "2346", "2347", "2349", "2350", "2351", "2352", "2353", "2355", "2358", "2359", "2361", "2363", "2365", "2368", "2370", "2372", "2373", "2376", "2382", "2383", "2386", "2389", "2390", "2392", "2398", "2399", "2401", "2411", "2413", "2414", "2416", "2418", "2422", "2424", "2429", "2430", "2432", "2434", "2439", "2440", "2441", "2442", "2445", "2447", "2448", "2449", "2450", "2451", "2453", "2457", "2458", "2459", "2461", "2465", "2466", "2469", "2470", "2472", "2473", "2474", "2476", "2478", "2481", "2483", "2484", "2485", "2486", "2488", "2489", "2493", "2496", "2498", "2499", "2501", "2502", "2504", "2505", "2506", "2508", "2514", "2515", "2516", "2518", "2520", "2521", "2524", "2525", "2528", "2529", "2530", "2531", "2532", "2537", "2539", "2540", "2542", "2543", "2544", "2545", "2546", "2548", "2549", "2551", "2554", "2556", "2563", "2564", "2566", "2567", "2568", "2569", "2570", "2573", "2577", "2579", "2580", "2581", "2584", "2585", "2586", "2587", "2588", "2589", "2590", "2592", "2593", "2594", "2596", "2597", "2599", "2602", "2603", "2604", "2605", "2607", "2610", "2611", "2612", "2614", "2615", "2616", "2617", "2619", "2621", "2622", "2624", "2625", "2627", "2628", "2629", "2630", "2634", "2636", "2637", "2640", "2641", "2642", "2645", "2646", "2649", "2651", "2652", "2653", "2655", "2656", "2657", "2659", "2661", "2663", "2665", "2666", "2668", "2670", "2671", "2674", "2676", "2677", "2678", "2679", "2680", "2681", "2682", "2684", "2685", "2686", "2687", "2688", "2690", "2691", "2693", "2697", "2698", "2700", "2706", "2707", "2708", "2710", "2711", "2713", "2714", "2715", "2716", "2719", "2720", "2721", "2731", "2734", "2735", "2736", "2739", "2740", "2743", "2744", "2746", "2748", "2752", "2753", "2756", "2757", "2759", "2760", "2761", "2762", "2763", "2764", "2765", "2770", "2771", "2774", "2775", "2776", "2779", "2781", "2782", "2785", "2787", "2790", "2792", "2793", "2794", "2795", "2796", "2798", "2802", "2803", "2806", "2808", "2809", "2810", "2811", "2815", "2822", "2824", "2826", "2827", "2828", "2829", "2830", "2834", "2835", "2836", "2837", "2839", "2842", "2843", "2844", "2849", "2850", "2851", "2853", "2854", "2856", "2857", "2866", "2867", "2868", "2872", "2874", "2875", "2876", "2879", "2880", "2886", "2887", "2892", "2894", "2895", "2896", "2898", "2900", "2901", "2902", "2905", "2906", "2908", "2909", "2910", "2913", "2914", "2915", "2916", "2917", "2919", "2923", "2924", "2925", "2927", "2929", "2930", "2934", "2935", "2938", "2939", "2940", "2942", "2943", "2945", "2946", "2947", "2948", "2950", "2952", "2957", "2959", "2962", "2965", "2967", "2968", "2971", "2974", "2975", "2976", "2977", "2978", "2985", "2988", "2989", "2990", "2991", "2992", "2998", "3002", "3003", "3004", "3005", "3006", "3007", "3008", "3009", "3011", "3012", "3013", "3014", "3015", "3016", "3017", "3019", "3021", "3022", "3028", "3033", "3036", "3039", "3045", "3046", "3047", "3050", "3051", "3057", "3058", "3059", "3060", "3061", "3065", "3066", "3067", "3068", "3070", "3072", "3074", "3078", "3080", "3085", "3087", "3088", "3089", "3090", "3091", "3096", "3100", "3101", "3103", "3110", "3111", "3112", "3114", "3115", "3117", "3119", "3121", "3122", "3123", "3124", "3126", "3127", "3130", "3133", "3137", "3139", "3140", "3141", "3143", "3145", "3146", "3150", "3151", "3154", "3157", "3159", "3160", "3163", "3165", "3166", "3167", "3169", "3171", "3174", "3175", "3176", "3178", "3179", "3180", "3184", "3185", "3186", "3188", "3190", "3193", "3194", "3197", "3198", "3202", "3203", "3206", "3208", "3209", "3211", "3212", "3213", "3215", "3217", "3220", "3222", "3225", "3228", "3229", "3230", "3231", "3232", "3234", "3236", "3241", "3243", "3248", "3249", "3250", "3252", "3261", "3263", "3264", "3265", "3267", "3269", "3270", "3271", "3273", "3274", "3276", "3280", "3281", "3282", "3283", "3284", "3285", "3287", "3288", "3289", "3291", "3293", "3294", "3295", "3297", "3298", "3299", "3300", "3301", "3308", "3310", "3311", "3312", "3315", "3316", "3318", "3319", "3320", "3331", "3332", "3333", "3335", "3338", "3339", "3340", "3341", "3342", "3343", "3344", "3345", "3349", "3352", "3355", "3356", "3358", "3359", "3362", "3365", "3366", "3367", "3368", "3370", "3373", "3375", "3376", "3378", "3379", "3384", "3386", "3388", "3390", "3391", "3392", "3396", "3398", "3400", "3402", "3404", "3405", "3406", "3407", "3408", "3410", "3412", "3416", "3420", "3421", "3422", "3423", "3425", "3426", "3427", "3428", "3430", "3431", "3432", "3434", "3435", "3436", "3440", "3442", "3444", "3445", "3447", "3448", "3449", "3451", "3453", "3455", "3457", "3458", "3462", "3463", "3466", "3468", "3472", "3475", "3476", "3479", "3480", "3482", "3483", "3484", "3485", "3488", "3490", "3491", "3492", "3493", "3494", "3496", "3500", "3504", "3509", "3512", "3513", "3515", "3517", "3518", "3522", "3524", "3527", "3528", "3529", "3530", "3534", "3536", "3537", "3539", "3541", "3544", "3546", "3547", "3550", "3551", "3552", "3553", "3554", "3555", "3558", "3563", "3564", "3567", "3569", "3570", "3572", "3577", "3578", "3579", "3580", "3583", "3586", "3592", "3593", "3596", "3597", "3598", "3600", "3601", "3602", "3605", "3606", "3608", "3610", "3613", "3616", "3617", "3618", "3621", "3622", "3624", "3629", "3632", "3634", "3635", "3639", "3641", "3642", "3643", "3645", "3648", "3650", "3658", "3659", "3661", "3664", "3666", "3667", "3671", "3672", "3673", "3674", "3676", "3677", "3678", "3679", "3681", "3686", "3687", "3689", "3690", "3692", "3693", "3696", "3697", "3700", "3701", "3703", "3708", "3709", "3710", "3711", "3712", "3714", "3717", "3718", "3720", "3721", "3723", "3724", "3726", "3728", "3729", "3731", "3732", "3735", "3736", "3738", "3740", "3742", "3744", "3745", "3747", "3748", "3750", "3751", "3756", "3760", "3761", "3764", "3769", "3771", "3774", "3777", "3779", "3780", "3784", "3788", "3795", "3799", "3803", "3804", "3807", "3808", "3810", "3811", "3813", "3814", "3817", "3823", "3826", "3827", "3828", "3829", "3830", "3834", "3835", "3837", "3839", "3842", "3844", "3845", "3846", "3851", "3852", "3853", "3854", "3856", "3859", "3862", "3865", "3866", "3867", "3868", "3869", "3870", "3872", "3874", "3875", "3876", "3877", "3881", "3882", "3883", "3885", "3888", "3890", "3891", "3892", "3893", "3894", "3895", "3896", "3898", "3900", "3901", "3902", "3903", "3905", "3908", "3911", "3916", "3917", "3918", "3919", "3922", "3924", "3925", "3926", "3927", "3929", "3930", "3931", "3932", "3934", "3936", "3937", "3943", "3944", "3945", "3946", "3947", "3950", "3952", "3954", "3955", "3956", "3957", "3959", "3960", "3961", "3963", "3964", "3968", "3971", "3973", "3978", "3980", "3981", "3982", "3983", "3984", "3985", "3986", "3987", "3991", "3992", "3993", "3994", "3997", "3999", "4000", "4002", "4003", "4006", "4007", "4008", "4009", "4010", "4015", "4016", "4018", "4020", "4021", "4027", "4032", "4033", "4035", "4036", "4038", "4040", "4041", "4045", "4047", "4052", "4053", "4054", "4057", "4058", "4059", "4061", "4062", "4065", "4069", "4071", "4072", "4073", "4074", "4076", "4079", "4080", "4085", "4086", "4088", "4089", "4091", "4093", "4095", "4096", "4097", "4098", "4100", "4101", "4102", "4103", "4104", "4109", "4112", "4114", "4117", "4119", "4122", "4125", "4127", "4128", "4129", "4133", "4135", "4137", "4138", "4139", "4141", "4142", "4147", "4148", "4151", "4152", "4156", "4157", "4158", "4159", "4160", "4162", "4166", "4169", "4170", "4171", "4176", "4179", "4180", "4181", "4182", "4188", "4191", "4194", "4195", "4199", "4200", "4201", "4202", "4203", "4205", "4207", "4215", "4216", "4219", "4225", "4226", "4228", "4229", "4230", "4233", "4236", "4244", "4245", "4246", "4247", "4248", "4249", "4250", "4256", "4257", "4258", "4260", "4265", "4267", "4270", "4275", "4277", "4279", "4281", "4282", "4283", "4284", "4289", "4291", "4293", "4295", "4297", "4298", "4299", "4302", "4303", "4304", "4305", "4306", "4307", "4309", "4310", "4312", "4314", "4315", "4316", "4318", "4319", "4323", "4326", "4328", "4331", "4333", "4335", "4336", "4338", "4340", "4341", "4344", "4348", "4349", "4350", "4352", "4353", "4356", "4357", "4358", "4360", "4361", "4362", "4365", "4369", "4370", "4372", "4374", "4375", "4376", "4377", "4378", "4382", "4388", "4389", "4391", "4392", "4393", "4399", "4405", "4406", "4408", "4409", "4410", "4411", "4412", "4413", "4417", "4422", "4423", "4426", "4428", "4432", "4433", "4434", "4435", "4437", "4438", "4439", "4441", "4444", "4445", "4446", "4450", "4451", "4452", "4453", "4454", "4455", "4456", "4457", "4459", "4461", "4464", "4466", "4467", "4471", "4473", "4474", "4475", "4476", "4477", "4478", "4481", "4484", "4485", "4488", "4490", "4496", "4497", "4502", "4503", "4506", "4509", "4510", "4511", "4512", "4513", "4514", "4517", "4521", "4524", "4526", "4527", "4528", "4532", "4534", "4536", "4537", "4538", "4540", "4541", "4546", "4547", "4548", "4549", "4551", "4552", "4554", "4555", "4557", "4558", "4560", "4561", "4562", "4563", "4564", "4565", "4567", "4568", "4573", "4575", "4578", "4580", "4581", "4584", "4589", "4590", "4596", "4597", "4600", "4602", "4603", "4606", "4607", "4608", "4609", "4611", "4613", "4618", "4619", "4620", "4621", "4623", "4624", "4627", "4628", "4629", "4634", "4643", "4644", "4649", "4652", "4653", "4654", "4656", "4661", "4663", "4666", "4667", "4668", "4669", "4670", "4673", "4675", "4680", "4687", "4691", "4692", "4693", "4694", "4695", "4697", "4700", "4701", "4702", "4703", "4704", "4705", "4707", "4708", "4710", "4711", "4713", "4714", "4715", "4716", "4717", "4718", "4719", "4722", "4724", "4726", "4727", "4728", "4729", "4732", "4736", "4739", "4740", "4741", "4742", "4743", "4744", "4745", "4748", "4749", "4750", "4753", "4756", "4757", "4760", "4763", "4766", "4767", "4769", "4770", "4771", "4776", "4777", "4781", "4786", "4788", "4791", "4793", "4794", "4798", "4799", "4800", "4801", "4802", "4803", "4809", "4810", "4811", "4812", "4814", "4816", "4818", "4819", "4820", "4823", "4824", "4826", "4827", "4828", "4830", "4833", "4835", "4839", "4841", "4844", "4845", "4847", "4848", "4849", "4854", "4859", "4862", "4863", "4866", "4871", "4873", "4875", "4876", "4877", "4879", "4880", "4885", "4886", "4889", "4891", "4892", "4894", "4895", "4897", "4898", "4899", "4900", "4902", "4903", "4906", "4907", "4908", "4909", "4910", "4912", "4915", "4917", "4919", "4921", "4922", "4923", "4926", "4932", "4939", "4941", "4942", "4944", "4946", "4948", "4950", "4952", "4955", "4956", "4960", "4961", "4968", "4969", "4970", "4972", "4975", "4976", "4977", "4978", "4980", "4982", "4983", "4984", "4986", "4987", "4989", "4990", "4991", "4996", "4997", "4998", "4999", "5001", "5002", "5003", "5005", "5007", "5010", "5013", "5014", "5015", "5016", "5018", "5024", "5027", "5030", "5031", "5032", "5036", "5038", "5039", "5040", "5042", "5046", "5047", "5048", "5049", "5050", "5051", "5052", "5053", "5054", "5055", "5056", "5058", "5059", "5060", "5062", "5063", "5065", "5067", "5074", "5075", "5077", "5078", "5080", "5082", "5084", "5085", "5086", "5087", "5093", "5094", "5095", "5097", "5099", "5101", "5102", "5103", "5104", "5106", "5107", "5108", "5110", "5112", "5113", "5115", "5117", "5118", "5119", "5123", "5124", "5126", "5128", "5130", "5131", "5132", "5133", "5134", "5135", "5136", "5140", "5142", "5143", "5145", "5147", "5148", "5150", "5154", "5158", "5162", "5163", "5164", "5165", "5167", "5168", "5169", "5170", "5172", "5174", "5175", "5176", "5177", "5179", "5180", "5182", "5184", "5186", "5187", "5190", "5192", "5193", "5194", "5195", "5198", "5201", "5202", "5204", "5205", "5207", "5208", "5209", "5210", "5212", "5213", "5215", "5217", "5220", "5226", "5227", "5228", "5229", "5230", "5231", "5232", "5235", "5236", "5239", "5241", "5243", "5245", "5246", "5247", "5248", "5249", "5251", "5253", "5255", "5256", "5257", "5259", "5260", "5261", "5262", "5265", "5266", "5267", "5268", "5269", "5270", "5271", "5273", "5274", "5275", "5279", "5280", "5281", "5282", "5283", "5285", "5287", "5290", "5293", "5295", "5296", "5299", "5300", "5301", "5303", "5306", "5309", "5310", "5311", "5312", "5313", "5315", "5317", "5319", "5322", "5323", "5325", "5326", "5327", "5330", "5331", "5332", "5334", "5335", "5337", "5338", "5339", "5346", "5347", "5350", "5351", "5352", "5355", "5359", "5360", "5364", "5365", "5366", "5368", "5370", "5371", "5373", "5376", "5377", "5378", "5385", "5389", "5390", "5391", "5396", "5397", "5400", "5402", "5404", "5405", "5406", "5407", "5409", "5415", "5419", "5421", "5424", "5425", "5429", "5434", "5435", "5437", "5439", "5440", "5441", "5442", "5444", "5445", "5446", "5447", "5448", "5450", "5451", "5453", "5456", "5467", "5471", "5474", "5475", "5476", "5477", "5478", "5479", "5482", "5486", "5487", "5489", "5493", "5494", "5497", "5500", "5501", "5502", "5503", "5505", "5506", "5507", "5512", "5513", "5514", "5515", "5516", "5518", "5519", "5520", "5521", "5522", "5525", "5527", "5528", "5529", "5532", "5533", "5534", "5536", "5537", "5539", "5545", "5546", "5547", "5549", "5551", "5553", "5554", "5558", "5559", "5561", "5565", "5566", "5567", "5568", "5569", "5572", "5575", "5578", "5582", "5586", "5588", "5589", "5590", "5596", "5601", "5606", "5607", "5609", "5611", "5614", "5615", "5616", "5617", "5618", "5620", "5623", "5624", "5625", "5626", "5627", "5628", "5634", "5635", "5638", "5639", "5640", "5644", "5645", "5647", "5648", "5649", "5653", "5657", "5659", "5663", "5667", "5676", "5678", "5679", "5683", "5686", "5688", "5691", "5695", "5697", "5698", "5699", "5700", "5701", "5703", "5704", "5705", "5706", "5709", "5711", "5713", "5716", "5717", "5719", "5721", "5722", "5723", "5726", "5731", "5732", "5733", "5734", "5739", "5741", "5742", "5743", "5744", "5745", "5746", "5747", "5751", "5752", "5754", "5755", "5761", "5763", "5764", "5766", "5768", "5769", "5770", "5771", "5772", "5773", "5775", "5776", "5780", "5781", "5782", "5784", "5785", "5788", "5789", "5792", "5794", "5795", "5796", "5798", "5799", "5804", "5812", "5813", "5814", "5815", "5816", "5818", "5819", "5821", "5822", "5824", "5826", "5827", "5830", "5834", "5835", "5840", "5842", "5844", "5846", "5847", "5849", "5850", "5852", "5853", "5854", "5855", "5856", "5864", "5865", "5866", "5872", "5874", "5876", "5877", "5880", "5881", "5882", "5888", "5889", "5891", "5893", "5894", "5895", "5896", "5898", "5901", "5902", "5904", "5905", "5906", "5907", "5909", "5914", "5915", "5917", "5918", "5920", "5921", "5924", "5925", "5926", "5929", "5930", "5931", "5933", "5934", "5935", "5937", "5941", "5943", "5944", "5946", "5947", "5950", "5955", "5957", "5958", "5960", "5962", "5963", "5966", "5967", "5971", "5973", "5976", "5980", "5981", "5982", "5985", "5987", "5988", "5989", "5990", "5998", "5999", "6002", "6008", "6009", "6011", "6013", "6016", "6019", "6023", "6025", "6028", "6030", "6033", "6035", "6037", "6038", "6039", "6040", "6041", "6043", "6046", "6047", "6050", "6052", "6058", "6059", "6062", "6063", "6064", "6065", "6066", "6067", "6071", "6074", "6076", "6078", "6079", "6082", "6083", "6085", "6087", "6088", "6089", "6091", "6092", "6093", "6094", "6097", "6099", "6105", "6106", "6107", "6111", "6112", "6118", "6120", "6121", "6122", "6123", "6124", "6126", "6130", "6131", "6132", "6135", "6137", "6138", "6139", "6140", "6141", "6142", "6145", "6146", "6147", "6149", "6152", "6153", "6154", "6155", "6161", "6163", "6165", "6166", "6167", "6178", "6181", "6184", "6186", "6188", "6190", "6192", "6195", "6196", "6200", "6203", "6208", "6210", "6212", "6214", "6216", "6217", "6225", "6227", "6228", "6231", "6232", "6235", "6240", "6241", "6244", "6246", "6249", "6250", "6251", "6253", "6254", "6255", "6256", "6257", "6258", "6262", "6264", "6267", "6268", "6271", "6272", "6274", "6275", "6276", "6278", "6279", "6281", "6282", "6283", "6284", "6291", "6292", "6293", "6294", "6298", "6300", "6301", "6304", "6305", "6306", "6307", "6309", "6311", "6312", "6314", "6315", "6316", "6319", "6321", "6326", "6332", "6334", "6335", "6339", "6340", "6341", "6346", "6348", "6350", "6354", "6355", "6356", "6357", "6360", "6363", "6364", "6366", "6367", "6369", "6370", "6374", "6376", "6381", "6385", "6386", "6388", "6390", "6392", "6396", "6397", "6400", "6401", "6403", "6405", "6406", "6407", "6408", "6413", "6414", "6416", "6419", "6422", "6424", "6427", "6428", "6429", "6431", "6432", "6436", "6441", "6443", "6445", "6446", "6451", "6452", "6454", "6456", "6460", "6462", "6464", "6466", "6468", "6469", "6470", "6471", "6472", "6473", "6475", "6477", "6478", "6483", "6485", "6487", "6488", "6491", "6492", "6494", "6497", "6499", "6500", "6502", "6504", "6507", "6509", "6512", "6513", "6516", "6521", "6523", "6527", "6528", "6529", "6530", "6533", "6534", "6535", "6537", "6539", "6540", "6541", "6542", "6543", "6544", "6545", "6546", "6547", "6550", "6552", "6555", "6557", "6558", "6560", "6563", "6565", "6567", "6568", "6569", "6570", "6573", "6574", "6576", "6578", "6580", "6582", "6583", "6585", "6586", "6587", "6588", "6589", "6593", "6596", "6597", "6605", "6608", "6609", "6611", "6612", "6613", "6615", "6617", "6618", "6619", "6622", "6623", "6624", "6626", "6629", "6630", "6635", "6636", "6637", "6638", "6639", "6641", "6642", "6643", "6644", "6650", "6652", "6653", "6654", "6665", "6667", "6668", "6669", "6670", "6672", "6674", "6678", "6679", "6680", "6682", "6684", "6686", "6687", "6688", "6691", "6695", "6696", "6697", "6698", "6699", "6700", "6709", "6711", "6712", "6713", "6717", "6718", "6719", "6721", "6722", "6723", "6724", "6725", "6727", "6730", "6731", "6732", "6735", "6736", "6740", "6742", "6745", "6750", "6751", "6754", "6755", "6756", "6758", "6759", "6760", "6767", "6768", "6774", "6775", "6777", "6779", "6780", "6781", "6782", "6784", "6785", "6786", "6787", "6788", "6790", "6794", "6795", "6796", "6797", "6803", "6805", "6809", "6810", "6812", "6813", "6814", "6815", "6816", "6817", "6819", "6820", "6824", "6825", "6826", "6829", "6831", "6836", "6839", "6840", "6842", "6843", "6845", "6846", "6847", "6849", "6853", "6857", "6858", "6860", "6861", "6862", "6863", "6864", "6869", "6870", "6874", "6876", "6880", "6884", "6885", "6888", "6890", "6892", "6893", "6898", "6899", "6902", "6904", "6910", "6911", "6912", "6913", "6915", "6918", "6919", "6920", "6921", "6924", "6925", "6927", "6928", "6933", "6934", "6935", "6938", "6941", "6942", "6944", "6951", "6952", "6955", "6956", "6957", "6959", "6960", "6966", "6970", "6972", "6976", "6977", "6979", "6980", "6981", "6982", "6984", "6987", "6988", "6989", "6992", "6994", "6995", "6998", "6999", "7004", "7006", "7007", "7009", "7010", "7011", "7012", "7020", "7022", "7025", "7026", "7028", "7034", "7035", "7037", "7041", "7042", "7046", "7048", "7050", "7053", "7054", "7056", "7057", "7058", "7059", "7062", "7064", "7065", "7066", "7067", "7069", "7070", "7071", "7073", "7074", "7075", "7076", "7078", "7079", "7086", "7087", "7089", "7092", "7096", "7097", "7101", "7102", "7105", "7107", "7108", "7111", "7113", "7114", "7115", "7116", "7118", "7119", "7127", "7128", "7130", "7133", "7137", "7138", "7140", "7141", "7143", "7144", "7145", "7146", "7147", "7149", "7150", "7151", "7155", "7156", "7162", "7164", "7167", "7170", "7171", "7172", "7174", "7175", "7177", "7181", "7182", "7185", "7191", "7193", "7194", "7195", "7196", "7198", "7199", "7201", "7208", "7209", "7210", "7211", "7215", "7219", "7220", "7230", "7232", "7233", "7235", "7238", "7239", "7242", "7246", "7247", "7248", "7249", "7254", "7255", "7258", "7261", "7262", "7263", "7264", "7265", "7266", "7268", "7269", "7272", "7277", "7282", "7283", "7284", "7285", "7287", "7288", "7289", "7290", "7295", "7296", "7297", "7300", "7302", "7303", "7310", "7311", "7313", "7317", "7321", "7322", "7324", "7326", "7328", "7330", "7331", "7333", "7337", "7340", "7341", "7347", "7349", "7352", "7353", "7357", "7358", "7360", "7362", "7367", "7370", "7372", "7374", "7379", "7380", "7381", "7383", "7385", "7386", "7388", "7391", "7392", "7395", "7396", "7398", "7399", "7401", "7402", "7405", "7407", "7408", "7409", "7410", "7412", "7413", "7417", "7419", "7420", "7422", "7423", "7425", "7426", "7428", "7430", "7432", "7436", "7437", "7440", "7442", "7443", "7444", "7445", "7446", "7448", "7449", "7451", "7452", "7453", "7454", "7455", "7456", "7459", "7460", "7461", "7462", "7463", "7464", "7466", "7468", "7469", "7470", "7471", "7472", "7473", "7478", "7479", "7482", "7483", "7484", "7487", "7490", "7491", "7493", "7494", "7495", "7496", "7498", "7499", "7501", "7504", "7506", "7507", "7508", "7510", "7513", "7514", "7515", "7518", "7522", "7525", "7526", "7527", "7528", "7529", "7530", "7532", "7533", "7536", "7538", "7539", "7540", "7543", "7545", "7546", "7547", "7549", "7550", "7551", "7552", "7555", "7556", "7560", "7563", "7564", "7566", "7567", "7569", "7570", "7571", "7573", "7578", "7580", "7581", "7582", "7583", "7586", "7588", "7590", "7591", "7593", "7594", "7598", "7604", "7606", "7607", "7609", "7610", "7611", "7614", "7615", "7616", "7619", "7621", "7622", "7623", "7625", "7626", "7627", "7628", "7630", "7631", "7635", "7636", "7637", "7639", "7640", "7641", "7644", "7645", "7646", "7650", "7652", "7654", "7656", "7658", "7660", "7661", "7662", "7663", "7667", "7668", "7669", "7673", "7676", "7678", "7681", "7682", "7684", "7687", "7688", "7689", "7690", "7691", "7693", "7697", "7699", "7703", "7704", "7706", "7707", "7709", "7710", "7712", "7716", "7717", "7719", "7720", "7721", "7722", "7723", "7724", "7728", "7729", "7732", "7735", "7737", "7738", "7740", "7744", "7745", "7747", "7748", "7749", "7751", "7752", "7754", "7756", "7757", "7758", "7759", "7763", "7764", "7765", "7766", "7768", "7770", "7777", "7778", "7780", "7781", "7782", "7787", "7791", "7792", "7794", "7795", "7796", "7797", "7798", "7803", "7805", "7808", "7809", "7813", "7814", "7815", "7817", "7818", "7822", "7823", "7826", "7827", "7828", "7830", "7831", "7835", "7836", "7837", "7838", "7839", "7840", "7842", "7845", "7847", "7848", "7851", "7853", "7855", "7858", "7859", "7861", "7862", "7863", "7865", "7870", "7872", "7874", "7878", "7880", "7888", "7889", "7890", "7891", "7893", "7894", "7896", "7897", "7898", "7900", "7901", "7903", "7905", "7909", "7911", "7913", "7914", "7915", "7916", "7917", "7918", "7919", "7920", "7923", "7925", "7926", "7927", "7929", "7931", "7932", "7933", "7934", "7935", "7936", "7937", "7939", "7940", "7941", "7946", "7947", "7949", "7950", "7953", "7954", "7955", "7959", "7961", "7964", "7965", "7966", "7967", "7968", "7973", "7974", "7975", "7976", "7983", "7984", "7987", "7991", "7992", "7993", "7994", "7998", "7999", "8002", "8005", "8007", "8008", "8010", "8012", "8013", "8021", "8023", "8025", "8026", "8028", "8029", "8031", "8032", "8034", "8035", "8036", "8037", "8040", "8041", "8042", "8043", "8045", "8046", "8048", "8049", "8051", "8053", "8057", "8058", "8061", "8063", "8064", "8065", "8066", "8068", "8071", "8073", "8074", "8078", "8079", "8080", "8081", "8083", "8084", "8087", "8088", "8093", "8097", "8101", "8102", "8104", "8107", "8108", "8109", "8110", "8112", "8113", "8114", "8115", "8117", "8119", "8121", "8123", "8124", "8127", "8128", "8129", "8130", "8133", "8134", "8135", "8136", "8137", "8138", "8139", "8140", "8144", "8145", "8151", "8154", "8155", "8158", "8160", "8162", "8166", "8171", "8172", "8173", "8176", "8177", "8178", "8179", "8181", "8184", "8185", "8186", "8187", "8192", "8194", "8195", "8197", "8198", "8199", "8200", "8201", "8206", "8207", "8209", "8210", "8211", "8212", "8213", "8214", "8215", "8216", "8223", "8224", "8229", "8230", "8235", "8239", "8240", "8241", "8246", "8247", "8252", "8253", "8255", "8257", "8258", "8259", "8263", "8264", "8266", "8268", "8270", "8271", "8275", "8276", "8277", "8278", "8279", "8280", "8285", "8286", "8287", "8288", "8293", "8294", "8296", "8297", "8298", "8299", "8303", "8304", "8305", "8306", "8309", "8312", "8315", "8316", "8319", "8320", "8324", "8325", "8328", "8332", "8333", "8334", "8336", "8338", "8339", "8340", "8341", "8345", "8350", "8355", "8356", "8359", "8360", "8363", "8364", "8368", "8369", "8372", "8373", "8375", "8379", "8382", "8384", "8386", "8391", "8392", "8394", "8395", "8396", "8397", "8398", "8402", "8404", "8405", "8407", "8408", "8414", "8415", "8416", "8417", "8419", "8420", "8422", "8423", "8424", "8426", "8428", "8429", "8430", "8434", "8435", "8436", "8437", "8439", "8445", "8447", "8449", "8451", "8452", "8454", "8460", "8465", "8466", "8467", "8471", "8473", "8478", "8483", "8484", "8485", "8486", "8487", "8488", "8490", "8495", "8496", "8500", "8503", "8505", "8509", "8511", "8512", "8514", "8516", "8518", "8521", "8522", "8523", "8524", "8525", "8527", "8531", "8535", "8537", "8538", "8541", "8542", "8544", "8548", "8550", "8553", "8554", "8556", "8558", "8559", "8561", "8562", "8564", "8567", "8568", "8572", "8573", "8574", "8576", "8580", "8583", "8586", "8587", "8590", "8591", "8593", "8594", "8595", "8596", "8597", "8598", "8600", "8602", "8605", "8608", "8610", "8612", "8613", "8614", "8615", "8616", "8617", "8618", "8619", "8622", "8625", "8626", "8627", "8629", "8630", "8631", "8632", "8635", "8636", "8639", "8645", "8646", "8649", "8650", "8652", "8654", "8658", "8660", "8661", "8662", "8670", "8671", "8673", "8676", "8677", "8678", "8679", "8682", "8685", "8689", "8694", "8695", "8698", "8701", "8702", "8704", "8706", "8708", "8710", "8712", "8713", "8714", "8715", "8717", "8720", "8722", "8723", "8729", "8730", "8731", "8733", "8736", "8738", "8740", "8741", "8743", "8744", "8746", "8749", "8750", "8752", "8756", "8758", "8759", "8763", "8770", "8772", "8773", "8778", "8779", "8782", "8783", "8784", "8786", "8788", "8790", "8793", "8797", "8799", "8802", "8803", "8806", "8809", "8812", "8813", "8814", "8815", "8816", "8818", "8820", "8822", "8826", "8828", "8829", "8831", "8832", "8833", "8836", "8839", "8841", "8843", "8844", "8846", "8847", "8849", "8852", "8854", "8857", "8858", "8859", "8863", "8865", "8866", "8868", "8869", "8871", "8873", "8876", "8877", "8879", "8880", "8882", "8884", "8886", "8890", "8894", "8895", "8897", "8901", "8908", "8909", "8910", "8911", "8912", "8913", "8915", "8917", "8919", "8920", "8925", "8927", "8928", "8929", "8930", "8932", "8933", "8936", "8939", "8940", "8944", "8945", "8946", "8948", "8950", "8951", "8956", "8960", "8964", "8967", "8968", "8969", "8971", "8974", "8982", "8983", "8984", "8992", "8994", "8995", "8996", "8997", "9000", "9004", "9005", "9006", "9007", "9008", "9012", "9013", "9014", "9017", "9018", "9020", "9021", "9023", "9028", "9029", "9031", "9034", "9038", "9040", "9041", "9042", "9044", "9045", "9047", "9048", "9051", "9053", "9054", "9055", "9056", "9059", "9060", "9061", "9062", "9070", "9072", "9074", "9076", "9077", "9083", "9084", "9085", "9087", "9089", "9091", "9093", "9094", "9099", "9100", "9101", "9104", "9105", "9106", "9107", "9109", "9110", "9111", "9114", "9115", "9116", "9117", "9118", "9119", "9121", "9124", "9126", "9127", "9131", "9134", "9135", "9136", "9138", "9139", "9141", "9142", "9144", "9148", "9150", "9151", "9152", "9155", "9156", "9160", "9161", "9162", "9165", "9169", "9170", "9173", "9180", "9183", "9185", "9186", "9187", "9189", "9190", "9191", "9192", "9196", "9201", "9204", "9207", "9208", "9209", "9211", "9213", "9214", "9215", "9217", "9218", "9219", "9223", "9226", "9228", "9230", "9231", "9233", "9235", "9236", "9237", "9238", "9239", "9241", "9244", "9246", "9248", "9249", "9250", "9252", "9255", "9258", "9259", "9261", "9267", "9270", "9273", "9276", "9277", "9278", "9281", "9285", "9287", "9292", "9293", "9299", "9300", "9303", "9306", "9308", "9310", "9314", "9317", "9325", "9326", "9327", "9328", "9329", "9330", "9331", "9335", "9336", "9337", "9340", "9342", "9343", "9344", "9351", "9356", "9358", "9361", "9364", "9365", "9368", "9369", "9370", "9372", "9374", "9375", "9379", "9380", "9382", "9387", "9388", "9391", "9392", "9393", "9396", "9397", "9399", "9400", "9401", "9402", "9407", "9408", "9410", "9411", "9412", "9413", "9417", "9420", "9421", "9422", "9423", "9427", "9429", "9438", "9439", "9440", "9441", "9444", "9446", "9448", "9451", "9455", "9457", "9460", "9462", "9463", "9464", "9476", "9477", "9479", "9484", "9485", "9487", "9489", "9490", "9495", "9496", "9497", "9498", "9501", "9502", "9503", "9506", "9507", "9508", "9509", "9510", "9512", "9514", "9516", "9517", "9519", "9520", "9522", "9523", "9526", "9529", "9530", "9538", "9540", "9542", "9543", "9544", "9546", "9547", "9555", "9557", "9561", "9564", "9565", "9568", "9569", "9571", "9575", "9577", "9584", "9589", "9590", "9592", "9593", "9602", "9604", "9605", "9608", "9613", "9615", "9617", "9618", "9620", "9621", "9624", "9626", "9627", "9628", "9630", "9633", "9634", "9635", "9636", "9638", "9640", "9642", "9643", "9644", "9646", "9648", "9649", "9650", "9652", "9656", "9657", "9658", "9660", "9661", "9662", "9663", "9666", "9667", "9669", "9673", "9676", "9677", "9678", "9681", "9683", "9684", "9686", "9687", "9689", "9691", "9692", "9695", "9696", "9698", "9699", "9703", "9708", "9709", "9710", "9712", "9722", "9725", "9726", "9727", "9728", "9730", "9731", "9735", "9737", "9739", "9743", "9744", "9749", "9750", "9751", "9753", "9754", "9755", "9756", "9757", "9758", "9761", "9762", "9765", "9766", "9770", "9771", "9773", "9774", "9776", "9777", "9781", "9783", "9784", "9786", "9791", "9793", "9794", "9797", "9799", "9802", "9803", "9804", "9806", "9808", "9810", "9811", "9812", "9816", "9817", "9820", "9822", "9823", "9824", "9825", "9826", "9827", "9830", "9832", "9833", "9834", "9842", "9843", "9844", "9845", "9847", "9848", "9849", "9850", "9855", "9856", "9857", "9858", "9859", "9862", "9863", "9864", "9866", "9868", "9869", "9871", "9873", "9875", "9876", "9877", "9880", "9882", "9886", "9888", "9890", "9898", "9899", "9900", "9901", "9902", "9903", "9904", "9907", "9909", "9910", "9915", "9918", "9919", "9921", "9922", "9923", "9924", "9925", "9926", "9928", "9930", "9931", "9932", "9935", "9937", "9939", "9940", "9941", "9943", "9948", "9951", "9952", "9953", "9954", "9956", "9957", "9958", "9959", "9960", "9961", "9962", "9964", "9965", "9968", "9969", "9972", "9973", "9974", "9975", "9977", "9980", "9981", "9982", "9989", "9991", "9992", "9993", "9997", "9998", "10000", "10001", "10002", "10004", "10008", "10009", "10010", "10012", "10013", "10014", "10017", "10018", "10019", "10020", "10022", "10023", "10025", "10026", "10028", "10031", "10032", "10035", "10041", "10043", "10044", "10045", "10046", "10048", "10049", "10051", "10052", "10053", "10054", "10056", "10057", "10059", "10060", "10061", "10062", "10067", "10068", "10070", "10071", "10073", "10074", "10080", "10081", "10082", "10083", "10086", "10087", "10090", "10092", "10093", "10094", "10097", "10101", "10102", "10105", "10106", "10107", "10109", "10114", "10116", "10117", "10118", "10119", "10121", "10122", "10126", "10127", "10129", "10130", "10132", "10133", "10134", "10136", "10137", "10143", "10145", "10147", "10153", "10158", "10159", "10160", "10162", "10163", "10164", "10166", "10170", "10171", "10172", "10173", "10178", "10185", "10186", "10188", "10193", "10194", "10195", "10196", "10198", "10199", "10200", "10201", "10202", "10203", "10204", "10206", "10207", "10210", "10211", "10212", "10214", "10216", "10217", "10219", "10220", "10226", "10229", "10235", "10241", "10242", "10245", "10247", "10248", "10251", "10252", "10253", "10255", "10256", "10257", "10258", "10260", "10262", "10268", "10269", "10270", "10271", "10274", "10276", "10277", "10279", "10280", "10285", "10288", "10291", "10294", "10298", "10300", "10304", "10305", "10309", "10312", "10315", "10320", "10323", "10331", "10332", "10334", "10337", "10342", "10344", "10350", "10352", "10353", "10354", "10355", "10356", "10360", "10361", "10363", "10364", "10372", "10374", "10376", "10380", "10383", "10390", "10395", "10396", "10399", "10403", "10405", "10406", "10409", "10415", "10416", "10417", "10419", "10420", "10422", "10423", "10424", "10427", "10428", "10433", "10434", "10435", "10436", "10437", "10438", "10440", "10443", "10444", "10446", "10448", "10449", "10450", "10453", "10455", "10456", "10457", "10458", "10459", "10460", "10461", "10463", "10468", "10470", "10472", "10474", "10476", "10477", "10478", "10479", "10480", "10482", "10483", "10485", "10487", "10489", "10493", "10494", "10495", "10496", "10499", "10507", "10509", "10511", "10513", "10515", "10517", "10522", "10523", "10524", "10525", "10526", "10528", "10530", "10532", "10535", "10537", "10538", "10540", "10541", "10542", "10544", "10549", "10557", "10558", "10560", "10562", "10563", "10565", "10567", "10568", "10569", "10572", "10579", "10580", "10582", "10584", "10586", "10588", "10590", "10591", "10593", "10601", "10604", "10605", "10607", "10608", "10609", "10610", "10612", "10613", "10614", "10615", "10616", "10619", "10621", "10622", "10623", "10625", "10627", "10628", "10629", "10630", "10631", "10632", "10635", "10640", "10641", "10644", "10645", "10648", "10649", "10650", "10651", "10656", "10657", "10659", "10660", "10663", "10664", "10665", "10666", "10667", "10670", "10671", "10672", "10673", "10674", "10676", "10677", "10678", "10680", "10681", "10685", "10686", "10688", "10690", "10692", "10695", "10700", "10701", "10705", "10706", "10707", "10708", "10709", "10710", "10714", "10716", "10718", "10719", "10722", "10724", "10727", "10729", "10735", "10736", "10742", "10744", "10745", "10753", "10754", "10755", "10757", "10758", "10759", "10762", "10764", "10765", "10766", "10767", "10771", "10772", "10773", "10776", "10778", "10781", "10786", "10788", "10791", "10792", "10793", "10794", "10795", "10798", "10802", "10803", "10805", "10806", "10807", "10810", "10811", "10813", "10814", "10815", "10816", "10818", "10819", "10820", "10821", "10822", "10824", "10826", "10827", "10829", "10832", "10833", "10834", "10835", "10838", "10841", "10842", "10846", "10848", "10849", "10851", "10852", "10855", "10856", "10859", "10860", "10864", "10865", "10867", "10870", "10874", "10877", "10879", "10881", "10882", "10883", "10884", "10885", "10886", "10887", "10889", "10890", "10893", "10898", "10899", "10900", "10901", "10902", "10904", "10910", "10911", "10914", "10915", "10919", "10920", "10921", "10922", "10924", "10928", "10930", "10932", "10935", "10937", "10938", "10939", "10942", "10946", "10947", "10949", "10950", "10952", "10955", "10956", "10958", "10959", "10960", "10963", "10964", "10965", "10966", "10971", "10972", "10973", "10976", "10977", "10978", "10979", "10981", "10985", "10987", "10989", "10993", "10994", "10996", "10997", "10998", "10999", "11000", "11001", "11004", "11005", "11009", "11011", "11012", "11019", "11021", "11022", "11023", "11025", "11026", "11028", "11031", "11032", "11034", "11035", "11038", "11039", "11042", "11043", "11044", "11045", "11047", "11048", "11049", "11051", "11058", "11059", "11065", "11066", "11067", "11068", "11069", "11074", "11080", "11081", "11083", "11086", "11090", "11091", "11092", "11093", "11094", "11098", "11100", "11101", "11104", "11105", "11106", "11107", "11111", "11115", "11119", "11120", "11124", "11128", "11130", "11134", "11135", "11136", "11138", "11140", "11141", "11142", "11143", "11144", "11145", "11146", "11147", "11148", "11149", "11150", "11151", "11152", "11153", "11154", "11157", "11159", "11160", "11161", "11162", "11163", "11167", "11168", "11169", "11171", "11172", "11174", "11177", "11181", "11184", "11185", "11192", "11195", "11200", "11202", "11204", "11205", "11209", "11210", "11212", "11217", "11218", "11221", "11222", "11225", "11226", "11227", "11228", "11230", "11232", "11233", "11238", "11239", "11243", "11248", "11251", "11252", "11253", "11254", "11255", "11257", "11259", "11260", "11264", "11267", "11270", "11272", "11276", "11278", "11279", "11280", "11281", "11283", "11284", "11285", "11287", "11291", "11294", "11296", "11298", "11300", "11301", "11303", "11304", "11305", "11306", "11307", "11309", "11310", "11311", "11312", "11313", "11318", "11322", "11324", "11325", "11332", "11333", "11334", "11336", "11339", "11343", "11344", "11346", "11347", "11348", "11353", "11354", "11356", "11357", "11359", "11362", "11364", "11365", "11366", "11367", "11368", "11369", "11371", "11376", "11377", "11378", "11380", "11381", "11382", "11383", "11384", "11385", "11388", "11390", "11391", "11395", "11397", "11403", "11405", "11406", "11407", "11408", "11409", "11412", "11413", "11414", "11415", "11417", "11418", "11420", "11421", "11423", "11425", "11427", "11428", "11431", "11432", "11436", "11439", "11441", "11443", "11446", "11449", "11452", "11454", "11456", "11459", "11461", "11462", "11465", "11466", "11467", "11468", "11469", "11470", "11471", "11472", "11473", "11477", "11478", "11479", "11484", "11486", "11489", "11490", "11491", "11493", "11494", "11495", "11496", "11497", "11499", "11500", "11501", "11502", "11505", "11508", "11509", "11512", "11513", "11514", "11516", "11518", "11519", "11521", "11522", "11524", "11526", "11528", "11529", "11530", "11531", "11533", "11536", "11538", "11539", "11540", "11542", "11543", "11546", "11547", "11548", "11549", "11550", "11553", "11554", "11558", "11561", "11562", "11563", "11567", "11568", "11569", "11571", "11572", "11573", "11575", "11576", "11577", "11578", "11579", "11580", "11582", "11583", "11584", "11586", "11591", "11596", "11598", "11600", "11602", "11604", "11605", "11606", "11609", "11612", "11615", "11617", "11619", "11620", "11621", "11622", "11624", "11625", "11626", "11628", "11631", "11636", "11638", "11639", "11640", "11641", "11642", "11643", "11644", "11645", "11646", "11648", "11649", "11653", "11654", "11655", "11659", "11660", "11661", "11663", "11664", "11665", "11668", "11669", "11671", "11672", "11673", "11674", "11678", "11679", "11681", "11682", "11684", "11686", "11688", "11691", "11693", "11695", "11698", "11701", "11702", "11703", "11708", "11709", "11710", "11718", "11720", "11721", "11722", "11723", "11726", "11727", "11728", "11730", "11734", "11735", "11736", "11737", "11738", "11739", "11741", "11742", "11743", "11744", "11747", "11749", "11750", "11752", "11754", "11755", "11756", "11757", "11760", "11761", "11763", "11768", "11770", "11772", "11774", "11776", "11778", "11784", "11787", "11790", "11792", "11794", "11798", "11799", "11801", "11802", "11803", "11804", "11809", "11810", "11811", "11816", "11817", "11822", "11823", "11824", "11827", "11828", "11829", "11830", "11831", "11836", "11840", "11843", "11845", "11848", "11851", "11853", "11854", "11857", "11858", "11859", "11863", "11865", "11869", "11870", "11873", "11874", "11875", "11880", "11882", "11883", "11884", "11885", "11887", "11890", "11892", "11894", "11896", "11900", "11901", "11904", "11905", "11906", "11907", "11909", "11911", "11912", "11915", "11916", "11920", "11921", "11926", "11927", "11928", "11929", "11931", "11935", "11938", "11940", "11945", "11947", "11952", "11954", "11957", "11958", "11961", "11962", "11964", "11965", "11968", "11969", "11975", "11977", "11980", "11981", "11982", "11985", "11988", "11989", "11990", "11991", "11995", "11998", "12000", "12001", "12002", "12003", "12010", "12011", "12012", "12015", "12016", "12017", "12018", "12019", "12024", "12025", "12027", "12028", "12029", "12032", "12036", "12039", "12040", "12041", "12042", "12043", "12046", "12049", "12050", "12051", "12053", "12056", "12057", "12058", "12059", "12060", "12062", "12064", "12072", "12073", "12074", "12075", "12077", "12079", "12080", "12082", "12084", "12086", "12087", "12091", "12094", "12095", "12096", "12097", "12098", "12099", "12101", "12106", "12107", "12108", "12114", "12116", "12117", "12118", "12119", "12120", "12125", "12126", "12127", "12128", "12129", "12130", "12131", "12132", "12133", "12134", "12135", "12136", "12138", "12139", "12140", "12143", "12145", "12146", "12148", "12150", "12152", "12153", "12157", "12162", "12164", "12166", "12167", "12169", "12170", "12172", "12173", "12178", "12179", "12180", "12181", "12182", "12184", "12185", "12187", "12190", "12192", "12193", "12194", "12195", "12197", "12198", "12202", "12203", "12206", "12209", "12210", "12211", "12213", "12221", "12222", "12224", "12225", "12227", "12230", "12233", "12234", "12235", "12236", "12237", "12238", "12240", "12242", "12243", "12244", "12246", "12249", "12250", "12251", "12253", "12254", "12256", "12257", "12258", "12260", "12264", "12269", "12270", "12271", "12272", "12273", "12274", "12275", "12276", "12277", "12279", "12281", "12282", "12284", "12285", "12286", "12288", "12293", "12296", "12298", "12299", "12301", "12306", "12307", "12308", "12314", "12315", "12316", "12319", "12321", "12323", "12325", "12327", "12329", "12333", "12336", "12337", "12339", "12341", "12342", "12346", "12348", "12350", "12352", "12353", "12354", "12356", "12357", "12358", "12359", "12360", "12364", "12365", "12367", "12370", "12371", "12374", "12375", "12377", "12379", "12382", "12384", "12385", "12386", "12392", "12393", "12395", "12396", "12398", "12400", "12401", "12402", "12411", "12416", "12418", "12419", "12421", "12425", "12428", "12429", "12430", "12431", "12441", "12443", "12445", "12446", "12447", "12450", "12451", "12452", "12453", "12454", "12456", "12457", "12459", "12463", "12467", "12468", "12469", "12471", "12472", "12473", "12474", "12475", "12476", "12479", "12480", "12482", "12484", "12485", "12486", "12487", "12488", "12490", "12495", "12498", "12499", "12501", "12502", "12511", "12513", "12517", "12520", "12523", "12526", "12527", "12528", "12530", "12531", "12532", "12533", "12534", "12535", "12539", "12540", "12541", "12544", "12547", "12549", "12551", "12553", "12555", "12558", "12559", "12560", "12561", "12564", "12568", "12569", "12571", "12577", "12578", "12579", "12584", "12585", "12587", "12588", "12589", "12590", "12591", "12592", "12596", "12601", "12603", "12604", "12606", "12610", "12611", "12614", "12615", "12616", "12619", "12621", "12624", "12629", "12632", "12633", "12635", "12637", "12639", "12641", "12642", "12644", "12645", "12646", "12647", "12648", "12649", "12651", "12652", "12655", "12659", "12661", "12663", "12665", "12666", "12667", "12670", "12672", "12673", "12674", "12675", "12677", "12679", "12681", "12684", "12685", "12687", "12689", "12691", "12692", "12696", "12699", "12700", "12702", "12704", "12705", "12707", "12710", "12712", "12713", "12715", "12716", "12717", "12718", "12720", "12722", "12728", "12729", "12730", "12731", "12733", "12739", "12740", "12744", "12745", "12746", "12747", "12749", "12751", "12752", "12758", "12761", "12765", "12767", "12769", "12770", "12771", "12772", "12779", "12780", "12782", "12787", "12789", "12791", "12793", "12795", "12796", "12798", "12799", "12800", "12801", "12802", "12803", "12804", "12805", "12806", "12808", "12809", "12811", "12812", "12813", "12816", "12817", "12821", "12823", "12824", "12825", "12830", "12831", "12832", "12834", "12837", "12839", "12843", "12844", "12845", "12846", "12847", "12850", "12853", "12861", "12863", "12864", "12865", "12867", "12869", "12870", "12872", "12878", "12879", "12880", "12882", "12883", "12885", "12886", "12887", "12888", "12889", "12890", "12891", "12893", "12894", "12897", "12898", "12905", "12908", "12909", "12910", "12911", "12912", "12913", "12914", "12918", "12919", "12924", "12925", "12926", "12928", "12929", "12930", "12931", "12932", "12933", "12935", "12936", "12937", "12939", "12940", "12942", "12943", "12944", "12946", "12950", "12951", "12952", "12954", "12957", "12959", "12960", "12962", "12965", "12966", "12969", "12970", "12974", "12975", "12976", "12977", "12978", "12981", "12982", "12983", "12985", "12986", "12987", "12988", "12989", "12992", "12996", "12997", "13001", "13003", "13004", "13008", "13010", "13011", "13012", "13015", "13017", "13018", "13019", "13023", "13024", "13025", "13026", "13027", "13028", "13030", "13033", "13037", "13038", "13039", "13041", "13042", "13045", "13046", "13047", "13048", "13052", "13055", "13056", "13057", "13058", "13060", "13062", "13063", "13066", "13067", "13071", "13076", "13078", "13079", "13080", "13081", "13083", "13084", "13085", "13087", "13088", "13089", "13090", "13095", "13096", "13097", "13100", "13101", "13104", "13107", "13108", "13111", "13112", "13114", "13115", "13116", "13117", "13118", "13124", "13126", "13127", "13131", "13133", "13134", "13137", "13142", "13143", "13146", "13147", "13148", "13149", "13151", "13152", "13155", "13158", "13160", "13162", "13163", "13164", "13168", "13169", "13171", "13172", "13174", "13175", "13176", "13181", "13182", "13184", "13185", "13186", "13187", "13189", "13190", "13193", "13195", "13196", "13200", "13201", "13202", "13206", "13207", "13208", "13209", "13211", "13212", "13214", "13217", "13220", "13221", "13224", "13227", "13231", "13232", "13237", "13238", "13240", "13243", "13244", "13247", "13249", "13250", "13252", "13254", "13256", "13258", "13259", "13266", "13267", "13269", "13270", "13274", "13276", "13277", "13278", "13279", "13280", "13284", "13286", "13288", "13289", "13290", "13292", "13293", "13295", "13296", "13297", "13300", "13301", "13303", "13307", "13308", "13310", "13313", "13317", "13318", "13321", "13324", "13328", "13330", "13331", "13334", "13337", "13338", "13339", "13341", "13346", "13347", "13349", "13351", "13358", "13361", "13362", "13370", "13371", "13372", "13374", "13376", "13377", "13378", "13379", "13381", "13382", "13384", "13386", "13387", "13388", "13390", "13391", "13392", "13394", "13395", "13396", "13399", "13402", "13407", "13408", "13410", "13416", "13417", "13419", "13422", "13424", "13425", "13426", "13427", "13429", "13430", "13431", "13432", "13433", "13434", "13435", "13436", "13437", "13438", "13439", "13441", "13442", "13445", "13448", "13449", "13450", "13451", "13452", "13454", "13455", "13456", "13458", "13460", "13462", "13463", "13472", "13473", "13474", "13475", "13476", "13477", "13480", "13481", "13482", "13483", "13484", "13485", "13486", "13488", "13489", "13492", "13493", "13495", "13496", "13499", "13500", "13501", "13502", "13503", "13504", "13506", "13507", "13509", "13511", "13514", "13519", "13521", "13522", "13523", "13526", "13527", "13528", "13529", "13530", "13537", "13538", "13539", "13540", "13543", "13544", "13545", "13551", "13552", "13553", "13557", "13558", "13560", "13561", "13565", "13566", "13567", "13568", "13569", "13570", "13571", "13572", "13573", "13574", "13575", "13576", "13586", "13587", "13589", "13590", "13592", "13594", "13595", "13596", "13599", "13600", "13601", "13602", "13604", "13610", "13615", "13623", "13626", "13627", "13628", "13629", "13631", "13634", "13635", "13637", "13638", "13639", "13640", "13641", "13642", "13643", "13645", "13646", "13650", "13653", "13654", "13656", "13657", "13658", "13660", "13661", "13664", "13665", "13666", "13667", "13672", "13673", "13674", "13675", "13680", "13682", "13683", "13685", "13686", "13690", "13692", "13695", "13698", "13702", "13704", "13710", "13712", "13714", "13715", "13716", "13718", "13720", "13722", "13723", "13726", "13730", "13731", "13732", "13733", "13734", "13735", "13744", "13745", "13747", "13748", "13751", "13756", "13758", "13759", "13761", "13762", "13763", "13768", "13769", "13770", "13774", "13777", "13778", "13779", "13785", "13786", "13788", "13789", "13790", "13791", "13792", "13795", "13800", "13803", "13805", "13808", "13811", "13812", "13813", "13819", "13821", "13822", "13824", "13826", "13828", "13830", "13831", "13832", "13834", "13835", "13836", "13837", "13843", "13846", "13847", "13848", "13849", "13853", "13854", "13857", "13861", "13866", "13868", "13870", "13871", "13875", "13877", "13878", "13879", "13885", "13889", "13892", "13893", "13894", "13895", "13896", "13898", "13899", "13904", "13907", "13908", "13910", "13911", "13915", "13916", "13917", "13918", "13922", "13924", "13925", "13927", "13928", "13930", "13932", "13936", "13940", "13942", "13944", "13946", "13948", "13949", "13953", "13956", "13960", "13961", "13962", "13965", "13967", "13973", "13976", "13977", "13978", "13980", "13984", "13988", "13990", "13993", "13994", "13995", "13997", "13999", "14001", "14004", "14005", "14008", "14010", "14011", "14013", "14014", "14016", "14018", "14020", "14021", "14024", "14025", "14026", "14030", "14031", "14035", "14037", "14040", "14042", "14043", "14044", "14045", "14048", "14049", "14051", "14053", "14056", "14060", "14061", "14062", "14063", "14065", "14068", "14069", "14071", "14072", "14073", "14074", "14075", "14076", "14080", "14085", "14087", "14088", "14089", "14090", "14095", "14096", "14098", "14099", "14100", "14104", "14106", "14108", "14112", "14113", "14117", "14120", "14121", "14122", "14123", "14125", "14127", "14128", "14130", "14132", "14133", "14134", "14139", "14141", "14145", "14148", "14149", "14151", "14158", "14159", "14160", "14161", "14164", "14169", "14170", "14171", "14173", "14174", "14177", "14178", "14179", "14182", "14186", "14187", "14188", "14190", "14192", "14201", "14204", "14208", "14214", "14218", "14220", "14223", "14224", "14225", "14226", "14227", "14228", "14229", "14231", "14233", "14235", "14236", "14238", "14240", "14243", "14245", "14246", "14249", "14250", "14251", "14253", "14255", "14258", "14260", "14261", "14265", "14266", "14268", "14270", "14273", "14274", "14275", "14276", "14278", "14279", "14280", "14282", "14286", "14289", "14293", "14295", "14296", "14298", "14299", "14300", "14302", "14308", "14310", "14311", "14312", "14314", "14316", "14317", "14319", "14321", "14326", "14327", "14328", "14329", "14330", "14331", "14332", "14336", "14337", "14338", "14340", "14341", "14344", "14345", "14349", "14352", "14353", "14355", "14356", "14357", "14358", "14359", "14361", "14362", "14364", "14365", "14366", "14367", "14368", "14369", "14371", "14372", "14373", "14374", "14376", "14380", "14382", "14385", "14386", "14388", "14391", "14393", "14394", "14396", "14399", "14402", "14406", "14411", "14412", "14413", "14414", "14418", "14422", "14425", "14426", "14428", "14433", "14435", "14437", "14439", "14440", "14441", "14443", "14444", "14445", "14448", "14449", "14453", "14455", "14456", "14457", "14458", "14459", "14460", "14461", "14462", "14463", "14465", "14466", "14467", "14468", "14469", "14470", "14471", "14472", "14474", "14475", "14476", "14478", "14485", "14487", "14489", "14490", "14492", "14493", "14494", "14497", "14499", "14500", "14501", "14502", "14507", "14508", "14510", "14511", "14512", "14513", "14514", "14515", "14516", "14517", "14518", "14519", "14520", "14521", "14522", "14523", "14526", "14527", "14528", "14529", "14530", "14531", "14534", "14535", "14536", "14538", "14539", "14540", "14542", "14543", "14544", "14551", "14552", "14553", "14554", "14555", "14557", "14558", "14559", "14560", "14561", "14563", "14564", "14565", "14568", "14569", "14573", "14574", "14575", "14578", "14580", "14581", "14583", "14589", "14591", "14592", "14593", "14594", "14599", "14603", "14604", "14606", "14607", "14608", "14609", "14610", "14611", "14614", "14615", "14617", "14618", "14621", "14622", "14625", "14626", "14627", "14629", "14631", "14632", "14633", "14634", "14635", "14636", "14638", "14639", "14640", "14644", "14648", "14650", "14651", "14653", "14655", "14657", "14658", "14659", "14661", "14662", "14664", "14666", "14667", "14668", "14672", "14679", "14683", "14684", "14686", "14688", "14690", "14694", "14695", "14696", "14697", "14699", "14700", "14701", "14706", "14708", "14709", "14710", "14712", "14714", "14716", "14721", "14722", "14723", "14725", "14726", "14727", "14728", "14733", "14734", "14735", "14736", "14737", "14738", "14739", "14740", "14741", "14742", "14743", "14744", "14747", "14748", "14750", "14752", "14756", "14760", "14761", "14762", "14764", "14765", "14768", "14771", "14772", "14773", "14776", "14777", "14778", "14780", "14781", "14782", "14783", "14784", "14786", "14791", "14793", "14794", "14801", "14802", "14804", "14805", "14810", "14812", "14813", "14814", "14815", "14816", "14817", "14819", "14822", "14824", "14825", "14827", "14828", "14830", "14831", "14832", "14834", "14837", "14842", "14844", "14847", "14848", "14850", "14851", "14853", "14854", "14859", "14862", "14864", "14866", "14867", "14869", "14874", "14876", "14878", "14880", "14882", "14883", "14884", "14885", "14886", "14887", "14889", "14891", "14895", "14897", "14898", "14899", "14900", "14905", "14908", "14912", "14914", "14916", "14917", "14920", "14925", "14926", "14928", "14930", "14933", "14936", "14939", "14941", "14942", "14943", "14945", "14947", "14948", "14949", "14954", "14955", "14957", "14960", "14961", "14963", "14965", "14966", "14968", "14971", "14979", "14980", "14984", "14986", "14987", "14988", "14990", "14996", "15001", "15003", "15004", "15009", "15011", "15012", "15014", "15016", "15017", "15021", "15024", "15025", "15027", "15028", "15029", "15030", "15033", "15034", "15036", "15037", "15038", "15040", "15041", "15042", "15044", "15046", "15047", "15049", "15052", "15053", "15054", "15059", "15061", "15062", "15064", "15065", "15066", "15067", "15068", "15069", "15070", "15073", "15075", "15081", "15083", "15088", "15091", "15093", "15095", "15097", "15098", "15100", "15103", "15104", "15105", "15106", "15107", "15110", "15111", "15112", "15113", "15115", "15123", "15124", "15126", "15129", "15130", "15131", "15132", "15133", "15134", "15135", "15136", "15137", "15141", "15143", "15144", "15145", "15147", "15149", "15151", "15152", "15153", "15155", "15156", "15157", "15158", "15159", "15160", "15161", "15162", "15163", "15166", "15167", "15169", "15170", "15173", "15175", "15176", "15177", "15178", "15179", "15181", "15182", "15184", "15186", "15190", "15191", "15195", "15196", "15198", "15200", "15201", "15204", "15206", "15207", "15208", "15209", "15211", "15212", "15213", "15216", "15217", "15218", "15220", "15222", "15223", "15228", "15229", "15230", "15232", "15233", "15236", "15237", "15238", "15242", "15244", "15245", "15249", "15250", "15251", "15253", "15255", "15260", "15261", "15264", "15265", "15267", "15268", "15269", "15270", "15271", "15273", "15276", "15277", "15279", "15281", "15283", "15285", "15286", "15287", "15288", "15289", "15291", "15292", "15294", "15301", "15302", "15305", "15308", "15313", "15314", "15316", "15317", "15318", "15319", "15321", "15322", "15323", "15325", "15326", "15327", "15328", "15329", "15330", "15332", "15334", "15335", "15336", "15338", "15339", "15341", "15343", "15346", "15349", "15354", "15356", "15357", "15358", "15362", "15367", "15370", "15374", "15376", "15379", "15382", "15387", "15388", "15391", "15392", "15393", "15394", "15397", "15399", "15401", "15405", "15407", "15410", "15412", "15413", "15416", "15417", "15419", "15420", "15421", "15422", "15424", "15426", "15427", "15429", "15431", "15433", "15436", "15437", "15442", "15444", "15448", "15451", "15452", "15453", "15454", "15458", "15459", "15460", "15461", "15464", "15466", "15469", "15472", "15474", "15475", "15476", "15479", "15483", "15486", "15487", "15488", "15490", "15491", "15492", "15494", "15495", "15496", "15501", "15503", "15504", "15506", "15507", "15508", "15510", "15511", "15513", "15514", "15515", "15516", "15517", "15518", "15520", "15522", "15525", "15527", "15528", "15529", "15532", "15533", "15534", "15535", "15538", "15541", "15543", "15545", "15547", "15549", "15551", "15552", "15553", "15554", "15555", "15557", "15559", "15562", "15564", "15565", "15566", "15567", "15568", "15571", "15573", "15579", "15580", "15581", "15582", "15585", "15586", "15587", "15589", "15591", "15596", "15597", "15599", "15600", "15601", "15604", "15605", "15607", "15609", "15610", "15613", "15614", "15619", "15620", "15624", "15625", "15630", "15632", "15633", "15636", "15637", "15639", "15642", "15645", "15646", "15647", "15649", "15650", "15652", "15655", "15657", "15658", "15660", "15661", "15664", "15666", "15670", "15671", "15674", "15675", "15676", "15679", "15681", "15682", "15685", "15686", "15688", "15691", "15692", "15693", "15694", "15700", "15703", "15706", "15707", "15708", "15709", "15712", "15713", "15714", "15715", "15718", "15719", "15720", "15724", "15730", "15732", "15735", "15737", "15739", "15740", "15741", "15747", "15748", "15749", "15753", "15754", "15756", "15760", "15761", "15763", "15764", "15766", "15767", "15768", "15771", "15772", "15779", "15781", "15783", "15784", "15785", "15786", "15787", "15788", "15794", "15796", "15797", "15798", "15800", "15802", "15803", "15806", "15807", "15813", "15815", "15817", "15823", "15824", "15826", "15827", "15831", "15832", "15833", "15836", "15837", "15839", "15841", "15844", "15846", "15847", "15849", "15850", "15852", "15854", "15856", "15857", "15858", "15859", "15861", "15862", "15864", "15866", "15867", "15870", "15875", "15876", "15877", "15878", "15880", "15882", "15884", "15887", "15890", "15892", "15893", "15895", "15897", "15898", "15900", "15901", "15902", "15903", "15904", "15906", "15907", "15908", "15909", "15913", "15914", "15915", "15916", "15918", "15922", "15923", "15924", "15925", "15926", "15927", "15928", "15931", "15932", "15934", "15936", "15937", "15938", "15939", "15940", "15941", "15947", "15948", "15949", "15950", "15952", "15953", "15955", "15956", "15959", "15960", "15961", "15963", "15965", "15970", "15973", "15974", "15975", "15976", "15978", "15979", "15980", "15983", "15986", "15989", "15991", "15992", "15993", "15995", "15997", "15998", "16001", "16002", "16003", "16005", "16008", "16009", "16010", "16012", "16013", "16016", "16018", "16020", "16021", "16023", "16024", "16025", "16027", "16030", "16031", "16033", "16034", "16037", "16039", "16040", "16042", "16043", "16044", "16045", "16047", "16048", "16049", "16050", "16052", "16053", "16055", "16056", "16057", "16058", "16061", "16063", "16065", "16066", "16068", "16070", "16071", "16072", "16075", "16078", "16080", "16081", "16082", "16085", "16086", "16089", "16090", "16091", "16096", "16097", "16100", "16101", "16106", "16108", "16110", "16112", "16114", "16115", "16116", "16121", "16123", "16124", "16125", "16127", "16128", "16130", "16134", "16136", "16137", "16139", "16140", "16142", "16143", "16145", "16147", "16148", "16151", "16152", "16154", "16155", "16156", "16157", "16158", "16162", "16163", "16167", "16168", "16169", "16170", "16172", "16175", "16178", "16180", "16181", "16183", "16185", "16186", "16188", "16189", "16191", "16192", "16194", "16197", "16199", "16201", "16204", "16206", "16208", "16209", "16210", "16211", "16215", "16216", "16218", "16219", "16225", "16227", "16228", "16232", "16234", "16235", "16237", "16239", "16240", "16243", "16248", "16249", "16251", "16254", "16256", "16259", "16262", "16263", "16264", "16266", "16269", "16270", "16271", "16273", "16274", "16275", "16276", "16278", "16279", "16282", "16285", "16287", "16289", "16291", "16292", "16293", "16294", "16299", "16300", "16303", "16304", "16306", "16308", "16309", "16310", "16311", "16312", "16313", "16314", "16315", "16316", "16318", "16320", "16321", "16322", "16323", "16325", "16326", "16329", "16333", "16334", "16335", "16339", "16340", "16341", "16344", "16346", "16347", "16348", "16349", "16350", "16351", "16352", "16353", "16357", "16359", "16360", "16362", "16363", "16364", "16365", "16367", "16373", "16374", "16375", "16376", "16378", "16382", "16383", "16385", "16386", "16387", "16388", "16397", "16398", "16401", "16402", "16403", "16406", "16408", "16412", "16413", "16415", "16416", "16417", "16419", "16420", "16421", "16423", "16424", "16429", "16431", "16433", "16439", "16440", "16441", "16443", "16448", "16452", "16453", "16454", "16455", "16457", "16459", "16460", "16462", "16463", "16465", "16467", "16468", "16469", "16470", "16471", "16472", "16474", "16475", "16476", "16477", "16478", "16479", "16485", "16488", "16493", "16496", "16499", "16500", "16503", "16505", "16506", "16510", "16512", "16515", "16517", "16522", "16523", "16524", "16526", "16527", "16528", "16530", "16531", "16532", "16534", "16535", "16536", "16537", "16538", "16541", "16544", "16545", "16546", "16548", "16550", "16552", "16553", "16555", "16556", "16558", "16559", "16563", "16565", "16567", "16569", "16574", "16575", "16576", "16577", "16579", "16580", "16581", "16584", "16585", "16588", "16591", "16592", "16594", "16596", "16597", "16599", "16600", "16601", "16604", "16605", "16606", "16610", "16611", "16612", "16613", "16615", "16616", "16617", "16618", "16624", "16626", "16627", "16631", "16633", "16634", "16635", "16636", "16640", "16642", "16648", "16651", "16653", "16655", "16656", "16657", "16658", "16659", "16660", "16663", "16664", "16666", "16667", "16668", "16670", "16674", "16675", "16676", "16677", "16681", "16683", "16687", "16689", "16691", "16692", "16693", "16694", "16696", "16699", "16700", "16701", "16702", "16704", "16706", "16710", "16711", "16712", "16713", "16714", "16715", "16716", "16720", "16724", "16725", "16727", "16729", "16730", "16734", "16735", "16736", "16745", "16749", "16755", "16760", "16761", "16764", "16767", "16768", "16769", "16772", "16773", "16775", "16777", "16778", "16780", "16781", "16782", "16784", "16785", "16786", "16787", "16789", "16795", "16799", "16801", "16802", "16803", "16806", "16807", "16810", "16816", "16819", "16820", "16821", "16822", "16824", "16825", "16827", "16828", "16835", "16836", "16837", "16839", "16840", "16841", "16845", "16846", "16847", "16848", "16849", "16851", "16852", "16853", "16854", "16856", "16859", "16860", "16861", "16862", "16863", "16864", "16866", "16869", "16871", "16875", "16878", "16879", "16880", "16881", "16882", "16883", "16887", "16888", "16892", "16893", "16894", "16898", "16901", "16902", "16906", "16907", "16910", "16911", "16912", "16914", "16920", "16921", "16924", "16926", "16933", "16938", "16939", "16940", "16941", "16942", "16945", "16947", "16948", "16949", "16950", "16952", "16953", "16958", "16961", "16964", "16965", "16966", "16967", "16973", "16974", "16975", "16976", "16977", "16979", "16982", "16985", "16986", "16988", "16991", "16992", "16993", "16994", "16998", "17002", "17003", "17004", "17005", "17006", "17007", "17009", "17012", "17013", "17014", "17015", "17017", "17020", "17022", "17023", "17024", "17028", "17029", "17032", "17033", "17034", "17035", "17036", "17041", "17043", "17044", "17045", "17047", "17051", "17052", "17053", "17054", "17055", "17057", "17059", "17060", "17061", "17063", "17065", "17066", "17068", "17069", "17070", "17071", "17073", "17074", "17075", "17076", "17077", "17079", "17080", "17081", "17086", "17089", "17091", "17092", "17093", "17094", "17096", "17098", "17099", "17101", "17102", "17104", "17105", "17106", "17109", "17111", "17114", "17116", "17117", "17118", "17119", "17122", "17125", "17128", "17133", "17135", "17136", "17138", "17140", "17141", "17144", "17145", "17146", "17147", "17150", "17151", "17152", "17154", "17156", "17157", "17159", "17163", "17166", "17168", "17170", "17172", "17174", "17175", "17178", "17179", "17182", "17183", "17187", "17188", "17190", "17191", "17193", "17196", "17198", "17200", "17201", "17202", "17203", "17205", "17206", "17208", "17210", "17213", "17215", "17216", "17218", "17219", "17220", "17224", "17225", "17231", "17233", "17234", "17235", "17239", "17240", "17242", "17245", "17246", "17247", "17249", "17251", "17256", "17257", "17258", "17259", "17260", "17263", "17265", "17267", "17269", "17271", "17272", "17276", "17279", "17286", "17287", "17288", "17289", "17291", "17292", "17295", "17297", "17299", "17300", "17301", "17302", "17303", "17304", "17305", "17306", "17308", "17309", "17310", "17312", "17313", "17315", "17317", "17319", "17320", "17324", "17327", "17328", "17332", "17335", "17338", "17345", "17346", "17349", "17350", "17352", "17356", "17359", "17361", "17362", "17364", "17365", "17368", "17370", "17372", "17375", "17378", "17381", "17382", "17390", "17391", "17392", "17393", "17397", "17398", "17399", "17401", "17403", "17407", "17412", "17414", "17415", "17416", "17417", "17419", "17420", "17421", "17422", "17423", "17424", "17425", "17426", "17428", "17430", "17431", "17434", "17435", "17436", "17438", "17440", "17442", "17443", "17449", "17454", "17457", "17460", "17463", "17465", "17467", "17469", "17471", "17474", "17475", "17479", "17480", "17482", "17485", "17486", "17488", "17489", "17490", "17492", "17496", "17497", "17498", "17499", "17500", "17501", "17502", "17505", "17506", "17508", "17509", "17510", "17511", "17512", "17517", "17520", "17521", "17525", "17526", "17528", "17529", "17530", "17531", "17532", "17533", "17534", "17536", "17538", "17539", "17545", "17547", "17548", "17549", "17550", "17551", "17554", "17556", "17558", "17559", "17562", "17563", "17564", "17565", "17566", "17567", "17568", "17569", "17570", "17571", "17572", "17573", "17578", "17580", "17581", "17583", "17584", "17587", "17590", "17593", "17595", "17597", "17598", "17599", "17602", "17603", "17604", "17608", "17609", "17613", "17615", "17617", "17620", "17621", "17622", "17626", "17627", "17628", "17632", "17633", "17634", "17635", "17637", "17638", "17640", "17641", "17642", "17643", "17644", "17646", "17648", "17650", "17651", "17653", "17656", "17657", "17658", "17659", "17660", "17661", "17664", "17665", "17667", "17669", "17670", "17672", "17675", "17677", "17678", "17683", "17686", "17690", "17691", "17693", "17694", "17695", "17697", "17700", "17701", "17702", "17707", "17708", "17713", "17714", "17715", "17716", "17719", "17721", "17722", "17723", "17725", "17726", "17727", "17728", "17732", "17733", "17734", "17735", "17736", "17737", "17739", "17742", "17745", "17747", "17748", "17749", "17750", "17751", "17753", "17757", "17759", "17760", "17761", "17762", "17769", "17771", "17773", "17775", "17776", "17777", "17781", "17783", "17784", "17786", "17790", "17791", "17792", "17794", "17797", "17798", "17799", "17800", "17801", "17802", "17803", "17806", "17810", "17811", "17813", "17814", "17817", "17818", "17819", "17820", "17821", "17822", "17823", "17824", "17825", "17827", "17829", "17830", "17833", "17834", "17835", "17837", "17838", "17839", "17840", "17841", "17842", "17845", "17846", "17847", "17848", "17849", "17850", "17852", "17854", "17855", "17858", "17860", "17862", "17864", "17865", "17867", "17868", "17869", "17872", "17874", "17875", "17876", "17880", "17883", "17884", "17885", "17886", "17887", "17888", "17892", "17893", "17895", "17897", "17901", "17902", "17903", "17904", "17906", "17907", "17909", "17912", "17919", "17920", "17924", "17926", "17928", "17929", "17930", "17931", "17936", "17937", "17938", "17939", "17940", "17945", "17947", "17948", "17949", "17950", "17951", "17952", "17954", "17955", "17958", "17960", "17961", "17964", "17966", "17968", "17972", "17976", "17977", "17980", "17983", "17984", "17986", "17989", "17990", "17991", "17994", "17995", "17998", "17999", "18000", "18006", "18009", "18010", "18011", "18012", "18014", "18016", "18017", "18018", "18019", "18020", "18023", "18024", "18032", "18033", "18034", "18035", "18037", "18038", "18041", "18046", "18048", "18051", "18053", "18054", "18056", "18057", "18059", "18060", "18069", "18072", "18074", "18075", "18076", "18079", "18081", "18083", "18084", "18085", "18095", "18101", "18103", "18107", "18108", "18109", "18110", "18115", "18116", "18117", "18118", "18120", "18122", "18123", "18124", "18126", "18127", "18128", "18130", "18134", "18135", "18139", "18141", "18143", "18149", "18150", "18151", "18155", "18156", "18157", "18161", "18163", "18164", "18166", "18168", "18170", "18172", "18173", "18175", "18177", "18178", "18179", "18185", "18186", "18187", "18188", "18190", "18194", "18195", "18197", "18198", "18199", "18200", "18202", "18204", "18206", "18207", "18209", "18210", "18217", "18220", "18221", "18222", "18223", "18224", "18225", "18227", "18228", "18229", "18230", "18231", "18234", "18235", "18239", "18241", "18246", "18249", "18250", "18254", "18258", "18260", "18261", "18263", "18264", "18266", "18267", "18269", "18273", "18274", "18276", "18277", "18278", "18279", "18280", "18284", "18286", "18287", "18289", "18291", "18293", "18294", "18299", "18307", "18309", "18311", "18312", "18315", "18316", "18317", "18319", "18320", "18321", "18322", "18323", "18324", "18326", "18328", "18329", "18331", "18334", "18336", "18342", "18346", "18347", "18348", "18350", "18351", "18353", "18357", "18358", "18360", "18363", "18367", "18368", "18370", "18371", "18374", "18376", "18377", "18378", "18380", "18381", "18382", "18385", "18387", "18388", "18389", "18391", "18394", "18400", "18402", "18403", "18406", "18410", "18411", "18412", "18413", "18414", "18415", "18417", "18419", "18420", "18421", "18422", "18424", "18425", "18426", "18427", "18428", "18431", "18432", "18433", "18434", "18435", "18437", "18440", "18442", "18445", "18446", "18447", "18449", "18456", "18459", "18460", "18462", "18463", "18467", "18469", "18470", "18471", "18472", "18474", "18476", "18477", "18479", "18480", "18481", "18482", "18483", "18486", "18493", "18497", "18498", "18499", "18501", "18502", "18503", "18504", "18507", "18509", "18513", "18515", "18519", "18520", "18528", "18529", "18530", "18531", "18535", "18537", "18538", "18540", "18541", "18542", "18544", "18545", "18547", "18548", "18553", "18554", "18556", "18557", "18561", "18562", "18564", "18568", "18571", "18573", "18576", "18578", "18580", "18581", "18585", "18588", "18589", "18592", "18593", "18594", "18595", "18596", "18597", "18598", "18599", "18601", "18604", "18607", "18609", "18611", "18613", "18617", "18618", "18620", "18622", "18624", "18625", "18626", "18628", "18629", "18630", "18632", "18633", "18638", "18639", "18640", "18642", "18644", "18646", "18649", "18650", "18651", "18655", "18658", "18661", "18664", "18668", "18669", "18670", "18671", "18674", "18675", "18676", "18681", "18683", "18688", "18691", "18692", "18693", "18696", "18697", "18699", "18700", "18701", "18702", "18706", "18707", "18711", "18712", "18713", "18714", "18715", "18720", "18721", "18722", "18724", "18726", "18728", "18730", "18738", "18739", "18744", "18745", "18747", "18748", "18749", "18750", "18751", "18752", "18753", "18755", "18757", "18758", "18759", "18761", "18762", "18764", "18765", "18766", "18767", "18768", "18769", "18770", "18771", "18772", "18775", "18776", "18777", "18780", "18781", "18784", "18787", "18788", "18789", "18791", "18793", "18795", "18797", "18800", "18802", "18804", "18805", "18806", "18808", "18811", "18813", "18816", "18818", "18819", "18821", "18822", "18823", "18824", "18830", "18834", "18835", "18837", "18838", "18839", "18841", "18843", "18845", "18846", "18848", "18849", "18850", "18851", "18858", "18862", "18863", "18864", "18870", "18874", "18875", "18880", "18883", "18884", "18887", "18889", "18890", "18892", "18893", "18894", "18895", "18897", "18898", "18900", "18901", "18902", "18907", "18908", "18909", "18910", "18911", "18917", "18919", "18926", "18929", "18930", "18931", "18934", "18935", "18936", "18937", "18939", "18940", "18943", "18945", "18948", "18950", "18951", "18952", "18955", "18956", "18958", "18959", "18961", "18963", "18964", "18966", "18968", "18969", "18970", "18971", "18973", "18975", "18977", "18979", "18981", "18982", "18983", "18984", "18986", "18987", "18988", "18989", "18990", "18991", "18992", "18994", "18996", "18999", "19000", "19002", "19004", "19005", "19007", "19010", "19012", "19014", "19017", "19024", "19025", "19028", "19029", "19031", "19032", "19035", "19037", "19038", "19039", "19041", "19042", "19043", "19048", "19049", "19050", "19051", "19052", "19053", "19056", "19057", "19058", "19064", "19065", "19068", "19070", "19074", "19076", "19078", "19080", "19081", "19086", "19087", "19088", "19089", "19090", "19091", "19092", "19093", "19094", "19095", "19096", "19098", "19099", "19100", "19103", "19104", "19106", "19109", "19112", "19115", "19117", "19120", "19121", "19123", "19127", "19128", "19129", "19130", "19131", "19134", "19137", "19140", "19143", "19145", "19146", "19147", "19149", "19155", "19156", "19160", "19164", "19166", "19169", "19172", "19176", "19178", "19179", "19183", "19184", "19185", "19186", "19188", "19189", "19192", "19195", "19196", "19197", "19198", "19199", "19200", "19201", "19202", "19207", "19209", "19210", "19213", "19214", "19217", "19218", "19221", "19226", "19227", "19228", "19232", "19235", "19237", "19240", "19242", "19251", "19252", "19254", "19256", "19258", "19260", "19261", "19262", "19264", "19266", "19272", "19273", "19274", "19275", "19276", "19278", "19279", "19281", "19283", "19285", "19288", "19290", "19291", "19296", "19299", "19300", "19301", "19302", "19305", "19306", "19308", "19309", "19319", "19320", "19321", "19323", "19328", "19330", "19331", "19333", "19336", "19337", "19339", "19343", "19344", "19345", "19350", "19351", "19354", "19355", "19357", "19358", "19362", "19363", "19369", "19372", "19373", "19377", "19378", "19381", "19383", "19386", "19388", "19390", "19391", "19392", "19393", "19394", "19397", "19399", "19401", "19402", "19404", "19405", "19406", "19407", "19408", "19410", "19413", "19415", "19417", "19420", "19424", "19426", "19436", "19442", "19447", "19448", "19449", "19451", "19455", "19456", "19457", "19458", "19459", "19460", "19462", "19463", "19464", "19465", "19466", "19469", "19470", "19471", "19472", "19474", "19476", "19478", "19479", "19481", "19482", "19484", "19485", "19486", "19487", "19491", "19493", "19494", "19495", "19500", "19505", "19506", "19507", "19509", "19512", "19513", "19516", "19518", "19519", "19520", "19523", "19525", "19526", "19530", "19532", "19533", "19534", "19535", "19538", "19539", "19541", "19542", "19543", "19546", "19547", "19549", "19550", "19551", "19552", "19559", "19560", "19562", "19564", "19566", "19569", "19570", "19572", "19573", "19574", "19577", "19579", "19580", "19582", "19583", "19584", "19585", "19589", "19590", "19593", "19594", "19595", "19597", "19602", "19605", "19606", "19609", "19610", "19611", "19615", "19616", "19617", "19619", "19620", "19621", "19622", "19625", "19626", "19627", "19628", "19629", "19630", "19632", "19633", "19637", "19641", "19644", "19646", "19647", "19650", "19651", "19655", "19660", "19661", "19663", "19665", "19667", "19668", "19669", "19674", "19677", "19678", "19679", "19684", "19686", "19691", "19692", "19695", "19696", "19697", "19698", "19699", "19700", "19702", "19706", "19708", "19709", "19712", "19714", "19724", "19725", "19727", "19731", "19732", "19735", "19738", "19739", "19743", "19746", "19747", "19749", "19754", "19759", "19761", "19762", "19767", "19778", "19779", "19780", "19783", "19784", "19786", "19787", "19791", "19792", "19793", "19794", "19798", "19799", "19800", "19802", "19804", "19810", "19813", "19814", "19816", "19817", "19819", "19820", "19822", "19823", "19824", "19825", "19826", "19827", "19828", "19829", "19832", "19833", "19834", "19835", "19836", "19837", "19841", "19843", "19844", "19845", "19846", "19853", "19856", "19857", "19861", "19862", "19865", "19866", "19867", "19869", "19870", "19872", "19874", "19876", "19877", "19881", "19883", "19885", "19886", "19887", "19888", "19889", "19891", "19894", "19903", "19904", "19909", "19910", "19912", "19913", "19914", "19920", "19924", "19925", "19927", "19929", "19931", "19932", "19934", "19937", "19938", "19940", "19942", "19943", "19945", "19949", "19953", "19954", "19955", "19958", "19959", "19960", "19962", "19965", "19966", "19968", "19970", "19974", "19980", "19981", "19990", "19992", "19996", "20000", "20002", "20004", "20007", "20008", "20012", "20016", "20020", "20021", "20022", "20028", "20031", "20035", "20038", "20040", "20041", "20043", "20047", "20049", "20051", "20052", "20053", "20054", "20057", "20058", "20060", "20061", "20062", "20067", "20069", "20075", "20078", "20082", "20086", "20087", "20088", "20090", "20092", "20094", "20098", "20099", "20100", "20101", "20103", "20104", "20105", "20106", "20107", "20108", "20110", "20111", "20116", "20117", "20120", "20122", "20129", "20132", "20133", "20134", "20135", "20136", "20138", "20139", "20140", "20144", "20146", "20147", "20148", "20149", "20150", "20151", "20154", "20157", "20162", "20165", "20166", "20170", "20172", "20176", "20177", "20178", "20179", "20180", "20181", "20184", "20187", "20188", "20189", "20190", "20191", "20195", "20197", "20198", "20202", "20203", "20205", "20206", "20207", "20208", "20210", "20211", "20219", "20221", "20225", "20227", "20228", "20229", "20231", "20235", "20236", "20245", "20248", "20249", "20251", "20252", "20255", "20257", "20259", "20260", "20261", "20264", "20265", "20266", "20269", "20270", "20272", "20276", "20277", "20278", "20280", "20283", "20285", "20288", "20289", "20291", "20293", "20295", "20296", "20298", "20300", "20302", "20304", "20306", "20307", "20308", "20311", "20312", "20313", "20314", "20316", "20319", "20320", "20327", "20328", "20329", "20331", "20332", "20335", "20336", "20337", "20339", "20340", "20342", "20344", "20345", "20346", "20348", "20349", "20350", "20351", "20353", "20354", "20355", "20356", "20359", "20362", "20364", "20366", "20368", "20369", "20370", "20371", "20373", "20374", "20375", "20376", "20377", "20378", "20379", "20384", "20386", "20387", "20388", "20390", "20391", "20392", "20393", "20395", "20398", "20400", "20401", "20402", "20403", "20404", "20406", "20408", "20411", "20413", "20414", "20415", "20419", "20420", "20422", "20423", "20425", "20426", "20427", "20430", "20432", "20433", "20435", "20440", "20443", "20445", "20449", "20450", "20454", "20455", "20458", "20459", "20461", "20463", "20464", "20467", "20468", "20470", "20474", "20477", "20478", "20481", "20483", "20484", "20485", "20486", "20487", "20488", "20489", "20490", "20492", "20498", "20502", "20504", "20505", "20506", "20513", "20516", "20518", "20520", "20521", "20522", "20523", "20524", "20525", "20526", "20529", "20530", "20531", "20534", "20537", "20539", "20541", "20542", "20543", "20544", "20550", "20553", "20555", "20557", "20559", "20560", "20561", "20562", "20563", "20564", "20566", "20568", "20569", "20573", "20578", "20579", "20580", "20581", "20583", "20584", "20585", "20589", "20591", "20595", "20596", "20597", "20598", "20600", "20601", "20602", "20604", "20607", "20610", "20612", "20613", "20614", "20615", "20618", "20620", "20624", "20626", "20627", "20628", "20629", "20631", "20633", "20635", "20636", "20640", "20642", "20644", "20645", "20649", "20654", "20656", "20657", "20659", "20660", "20662", "20663", "20664", "20666", "20668", "20671", "20672", "20673", "20675", "20679", "20683", "20684", "20685", "20686", "20688", "20689", "20690", "20691", "20694", "20695", "20696", "20702", "20704", "20706", "20710", "20712", "20713", "20714", "20715", "20719", "20721", "20725", "20726", "20727", "20728", "20729", "20730", "20731", "20732", "20735", "20738", "20739", "20740", "20741", "20742", "20747", "20748", "20749", "20751", "20754", "20760", "20762", "20763", "20768", "20769", "20771", "20777", "20782", "20786", "20787", "20788", "20790", "20795", "20796", "20799", "20801", "20803", "20805", "20806", "20811", "20813", "20814", "20815", "20817", "20821", "20822", "20824", "20830", "20831", "20838", "20839", "20845", "20846", "20847", "20849", "20851", "20852", "20855", "20856", "20857", "20858", "20859", "20860", "20863", "20864", "20867", "20868", "20870", "20873", "20874", "20878", "20879", "20888", "20889", "20890", "20892", "20893", "20894", "20897", "20898", "20899", "20900", "20902", "20907", "20913", "20917", "20919", "20922", "20925", "20927", "20932", "20933", "20935", "20940", "20942", "20943", "20944", "20945", "20946", "20948", "20949", "20951", "20954", "20957", "20959", "20960", "20961", "20965", "20967", "20969", "20972", "20973", "20974", "20975", "20976", "20977", "20978", "20980", "20981", "20983", "20984", "20989", "20992", "20994", "20996", "20998", "20999", "21002", "21003", "21004", "21005", "21006", "21007", "21008", "21009", "21015", "21017", "21018", "21021", "21022", "21023", "21024", "21026", "21027", "21028", "21029", "21030", "21032", "21034", "21038", "21039", "21040", "21042", "21043", "21048", "21049", "21053", "21056", "21057", "21058", "21059", "21060", "21064", "21068", "21069", "21071", "21072", "21073", "21075", "21077", "21078", "21084", "21086", "21088", "21089", "21095", "21098", "21100", "21101", "21104", "21106", "21110", "21111", "21113", "21114", "21116", "21121", "21122", "21123", "21128", "21130", "21133", "21136", "21137", "21139", "21140", "21141", "21142", "21144", "21146", "21148", "21149", "21150", "21151", "21157", "21160", "21161", "21166", "21167", "21168", "21169", "21170", "21171", "21173", "21175", "21178", "21179", "21181", "21184", "21187", "21188", "21189", "21190", "21193", "21194", "21195", "21198", "21200", "21202", "21204", "21205", "21206", "21207", "21208", "21211", "21212", "21216", "21217", "21218", "21221", "21223", "21224", "21227", "21231", "21232", "21234", "21236", "21240", "21241", "21244", "21245", "21246", "21248", "21250", "21253", "21254", "21255", "21256", "21257", "21258", "21260", "21264", "21268", "21269", "21270", "21274", "21279", "21280", "21281", "21283", "21284", "21297", "21299", "21301", "21304", "21305", "21308", "21309", "21310", "21311", "21312", "21313", "21314", "21315", "21316", "21321", "21324", "21325", "21326", "21327", "21329", "21330", "21331", "21336", "21337", "21338", "21339", "21342", "21343", "21345", "21347", "21350", "21351", "21352", "21353", "21354", "21358", "21359", "21360", "21361", "21363", "21364", "21368", "21371", "21373", "21374", "21376", "21382", "21383", "21385", "21386", "21387", "21388", "21391", "21394", "21397", "21398", "21399", "21401", "21404", "21406", "21410", "21413", "21414", "21423", "21425", "21427", "21431", "21435", "21436", "21441", "21443", "21444", "21445", "21446", "21448", "21451", "21454", "21456", "21458", "21461", "21462", "21463", "21465", "21467", "21468", "21469", "21473", "21475", "21476", "21477", "21479", "21480", "21483", "21486", "21487", "21488", "21489", "21493", "21496", "21503", "21504", "21509", "21513", "21518", "21519", "21520", "21521", "21525", "21526", "21528", "21530", "21531", "21533", "21535", "21536", "21540", "21542", "21544", "21546", "21549", "21550", "21553", "21554", "21556", "21561", "21563", "21564", "21565", "21566", "21567", "21570", "21571", "21572", "21575", "21576", "21577", "21578", "21579", "21580", "21582", "21583", "21590", "21592", "21593", "21594", "21597", "21598", "21604", "21606", "21607", "21611", "21612", "21613", "21616", "21618", "21619", "21621", "21622", "21623", "21626", "21629", "21630", "21631", "21632", "21633", "21634", "21636", "21637", "21638", "21639", "21640", "21641", "21642", "21643", "21646", "21649", "21650", "21651", "21652", "21656", "21657", "21658", "21659", "21663", "21664", "21668", "21673", "21682", "21683", "21685", "21686", "21687", "21689", "21693", "21694", "21695", "21696", "21697", "21699", "21700", "21701", "21702", "21703", "21704", "21706", "21709", "21710", "21711", "21715", "21718", "21719", "21720", "21722", "21723", "21727", "21728", "21729", "21730", "21732", "21733", "21734", "21735", "21736", "21740", "21742", "21745", "21747", "21750", "21751", "21752", "21753", "21758", "21759", "21760", "21764", "21765", "21766", "21771", "21773", "21774", "21778", "21781", "21782", "21783", "21788", "21794", "21799", "21800", "21802", "21803", "21805", "21807", "21810", "21811", "21813", "21814", "21815", "21820", "21822", "21828", "21829", "21832", "21834", "21835", "21836", "21838", "21840", "21842", "21844", "21847", "21848", "21849", "21850", "21851", "21852", "21854", "21857", "21859", "21860", "21862", "21864", "21865", "21866", "21868", "21869", "21870", "21873", "21876", "21877", "21879", "21880", "21883", "21884", "21885", "21887", "21888", "21892", "21893", "21895", "21898", "21899", "21902", "21905", "21908", "21909", "21911", "21913", "21914", "21915", "21916", "21919", "21920", "21921", "21922", "21926", "21927", "21928", "21933", "21934", "21938", "21939", "21941", "21942", "21944", "21947", "21948", "21949", "21951", "21952", "21953", "21954", "21956", "21958", "21963", "21964", "21969", "21972", "21977", "21978", "21979", "21985", "21986", "21987", "21991", "21996", "21997", "21999", "22000", "22001", "22006", "22009", "22010", "22013", "22014", "22017", "22018", "22020", "22023", "22024", "22026", "22028", "22029", "22030", "22033", "22036", "22037", "22038", "22041", "22042", "22044", "22046", "22048", "22050", "22052", "22054", "22058", "22060", "22062", "22063", "22067", "22070", "22071", "22073", "22074", "22075", "22077", "22078", "22080", "22081", "22086", "22087", "22090", "22091", "22093", "22098", "22100", "22101", "22102", "22103", "22105", "22106", "22107", "22111", "22112", "22113", "22116", "22117", "22119", "22121", "22122", "22123", "22124", "22125", "22130", "22132", "22134", "22138", "22140", "22141", "22142", "22143", "22144", "22145", "22147", "22149", "22151", "22153", "22158", "22160", "22161", "22163", "22164", "22166", "22169", "22170", "22172", "22174", "22175", "22178", "22179", "22180", "22183", "22184", "22186", "22187", "22192", "22196", "22197", "22199", "22200", "22201", "22202", "22203", "22205", "22206", "22209", "22213", "22215", "22217", "22218", "22219", "22220", "22222", "22223", "22224", "22225", "22226", "22229", "22230", "22233", "22234", "22235", "22236", "22238", "22239", "22240", "22241", "22243", "22245", "22247", "22248", "22249", "22251", "22255", "22256", "22258", "22261", "22266", "22268", "22271", "22273", "22281", "22284", "22286", "22287", "22288", "22289", "22290", "22294", "22295", "22297", "22299", "22300", "22303", "22304", "22305", "22307", "22310", "22313", "22318", "22320", "22323", "22324", "22326", "22329", "22331", "22332", "22333", "22334", "22336", "22338", "22340", "22342", "22345", "22348", "22349", "22350", "22352", "22354", "22355", "22356", "22357", "22358", "22359", "22360", "22362", "22366", "22370", "22371", "22372", "22373", "22377", "22380", "22381", "22384", "22385", "22388", "22389", "22392", "22396", "22397", "22398", "22399", "22400", "22401", "22402", "22403", "22406", "22408", "22409", "22410", "22411", "22412", "22414", "22416", "22420", "22421", "22422", "22423", "22425", "22427", "22428", "22429", "22430", "22431", "22432", "22433", "22437", "22438", "22446", "22447", "22448", "22450", "22454", "22455", "22457", "22461", "22464", "22468", "22471", "22473", "22476", "22477", "22478", "22481", "22483", "22487", "22490", "22493", "22494", "22496", "22497", "22498", "22504", "22507", "22508", "22510", "22512", "22513", "22515", "22516", "22520", "22521", "22522", "22524", "22527", "22530", "22532", "22533", "22534", "22535", "22539", "22540", "22542", "22543", "22545", "22547", "22548", "22549", "22552", "22553", "22554", "22556", "22557", "22559", "22562", "22563", "22564", "22566", "22567", "22571", "22575", "22576", "22578", "22580", "22583", "22584", "22586", "22590", "22592", "22596", "22600", "22601", "22605", "22606", "22607", "22610", "22613", "22616", "22618", "22619", "22620", "22621", "22622", "22623", "22626", "22630", "22634", "22635", "22636", "22637", "22640", "22642", "22643", "22645", "22646", "22648", "22649", "22652", "22657", "22658", "22659", "22661", "22664", "22671", "22674", "22675", "22676", "22678", "22683", "22684", "22685", "22691", "22692", "22695", "22698", "22700", "22702", "22703", "22705", "22708", "22710", "22711", "22712", "22713", "22715", "22716", "22718", "22719", "22721", "22722", "22723", "22724", "22725", "22727", "22730", "22732", "22734", "22735", "22736", "22737", "22738", "22739", "22740", "22741", "22743", "22744", "22746", "22749", "22750", "22753", "22754", "22755", "22756", "22757", "22760", "22761", "22762", "22763", "22767", "22768", "22769", "22770", "22772", "22776", "22778", "22779", "22781", "22784", "22785", "22786", "22788", "22791", "22793", "22794", "22795", "22796", "22797", "22798", "22799", "22801", "22804", "22806", "22807", "22808", "22811", "22812", "22813", "22814", "22816", "22817", "22819", "22822", "22823", "22829", "22834", "22836", "22837", "22839", "22841", "22845", "22846", "22849", "22850", "22851", "22852", "22853", "22859", "22860", "22861", "22862", "22864", "22865", "22866", "22868", "22870", "22871", "22881", "22882", "22883", "22884", "22885", "22889", "22893", "22894", "22895", "22899", "22901", "22902", "22903", "22904", "22905", "22906", "22907", "22912", "22914", "22916", "22920", "22921", "22922", "22923", "22927", "22929", "22934", "22935", "22936", "22937", "22938", "22940", "22944", "22946", "22948", "22950", "22951", "22955", "22956", "22959", "22961", "22963", "22965", "22966", "22970", "22971", "22972", "22974", "22977", "22978", "22979", "22981", "22982", "22985", "22986", "22988", "22991", "22995", "22996", "23000", "23002", "23003", "23004", "23008", "23009", "23010", "23012", "23013", "23014", "23016", "23019", "23020", "23021", "23022", "23023", "23024", "23025", "23027", "23028", "23030", "23031", "23032", "23033", "23034", "23035", "23036", "23040", "23041", "23043", "23046", "23049", "23050", "23051", "23055", "23056", "23060", "23061", "23063", "23066", "23067", "23068", "23069", "23071", "23073", "23076", "23077", "23081", "23083", "23084", "23085", "23086", "23087", "23090", "23091", "23093", "23096", "23097", "23099", "23104", "23109", "23112", "23114", "23115", "23116", "23118", "23119", "23121", "23123", "23124", "23125", "23126", "23128", "23129", "23130", "23133", "23135", "23136", "23137", "23138", "23139", "23140", "23143", "23144", "23145", "23148", "23152", "23153", "23156", "23158", "23159", "23160", "23161", "23162", "23163", "23170", "23175", "23176", "23177", "23178", "23180", "23182", "23184", "23187", "23189", "23190", "23191", "23199", "23205", "23206", "23209", "23212", "23213", "23214", "23215", "23219", "23221", "23222", "23223", "23224", "23225", "23229", "23230", "23234", "23235", "23236", "23238", "23240", "23241", "23243", "23245", "23246", "23248", "23250", "23254", "23256", "23258", "23259", "23260", "23262", "23263", "23265", "23270", "23271", "23275", "23276", "23277", "23278", "23281", "23282", "23285", "23286", "23287", "23288", "23289", "23290", "23292", "23293", "23294", "23297", "23298", "23302", "23303", "23304", "23305", "23307", "23309", "23310", "23312", "23313", "23314", "23315", "23325", "23328", "23331", "23334", "23335", "23337", "23338", "23339", "23341", "23342", "23346", "23349", "23353", "23356", "23357", "23360", "23361", "23364", "23365", "23366", "23367", "23368", "23370", "23376", "23377", "23378", "23379", "23380", "23381", "23386", "23388", "23390", "23392", "23395", "23398", "23399", "23401", "23402", "23404", "23406", "23407", "23414", "23415", "23416", "23420", "23421", "23422", "23423", "23425", "23427", "23429", "23430", "23433", "23434", "23436", "23437", "23442", "23444", "23445", "23448", "23451", "23454", "23456", "23459", "23460", "23462", "23464", "23467", "23469", "23472", "23473", "23482", "23483", "23484", "23485", "23486", "23488", "23491", "23492", "23494", "23495", "23496", "23497", "23498", "23501", "23502", "23504", "23507", "23508", "23509", "23513", "23517", "23520", "23522", "23524", "23525", "23528", "23530", "23533", "23535", "23537", "23538", "23539", "23541", "23543", "23545", "23546", "23547", "23548", "23549", "23550", "23552", "23554", "23556", "23558", "23559", "23560", "23561", "23563", "23564", "23565", "23566", "23567", "23570", "23571", "23572", "23577", "23579", "23580", "23582", "23583", "23584", "23585", "23589", "23591", "23592", "23593", "23594", "23595", "23596", "23603", "23605", "23607", "23609", "23610", "23612", "23614", "23615", "23616", "23617", "23618", "23619", "23621", "23623", "23626", "23627", "23628", "23629", "23630", "23631", "23633", "23635", "23636", "23637", "23639", "23640", "23641", "23642", "23643", "23645", "23646", "23648", "23650", "23652", "23653", "23654", "23655", "23657", "23658", "23661", "23662", "23663", "23665", "23666", "23670", "23673", "23674", "23677", "23678", "23679", "23680", "23681", "23682", "23683", "23686", "23688", "23689", "23693", "23696", "23697", "23699", "23700", "23704", "23705", "23709", "23710", "23713", "23717", "23718", "23720", "23721", "23729", "23733", "23738", "23739", "23740", "23742", "23743", "23744", "23745", "23746", "23747", "23749", "23754", "23755", "23758", "23759", "23761", "23765", "23770", "23771", "23772", "23773", "23774", "23777", "23779", "23782", "23784", "23786", "23790", "23793", "23794", "23799", "23801", "23805", "23808", "23809", "23812", "23813", "23815", "23817", "23818", "23819", "23820", "23821", "23825", "23828", "23830", "23833", "23834", "23836", "23837", "23838", "23842", "23846", "23848", "23855", "23856", "23858", "23859", "23861", "23862", "23863", "23864", "23867", "23870", "23873", "23878", "23881", "23883", "23884", "23885", "23887", "23893", "23895", "23897", "23898", "23899", "23905", "23906", "23907", "23908", "23909", "23910", "23911", "23913", "23914", "23922", "23925", "23927", "23928", "23932", "23934", "23935", "23941", "23942", "23944", "23945", "23946", "23949", "23950", "23952", "23954", "23959", "23961", "23963", "23964", "23966", "23967", "23968", "23973", "23976", "23978", "23983", "23984", "23985", "23987", "23988", "23989", "23990", "23993", "23994", "23996", "23997", "23998", "23999", "24001", "24002", "24005", "24007", "24008", "24009", "24010", "24012", "24013", "24014", "24015", "24017", "24018", "24019", "24020", "24023", "24025", "24029", "24031", "24033", "24034", "24036", "24039", "24040", "24041", "24042", "24043", "24045", "24047", "24048", "24052", "24056", "24057", "24058", "24062", "24065", "24066", "24068", "24070", "24071", "24073", "24074", "24076", "24080", "24081", "24083", "24085", "24088", "24089", "24090", "24092", "24093", "24094", "24095", "24096", "24097", "24098", "24103", "24109", "24115", "24120", "24123", "24124", "24126", "24129", "24130", "24131", "24133", "24136", "24138", "24140", "24141", "24142", "24143", "24144", "24146", "24149", "24151", "24155", "24157", "24161", "24162", "24163", "24165", "24167", "24168", "24169", "24170", "24175", "24177", "24181", "24184", "24186", "24187", "24189", "24194", "24195", "24197", "24200", "24201", "24202", "24203", "24207", "24209", "24210", "24212", "24213", "24215", "24217", "24218", "24220", "24222", "24223", "24224", "24225", "24226", "24227", "24228", "24229", "24232", "24233", "24236", "24237", "24238", "24239", "24241", "24244", "24245", "24247", "24250", "24251", "24253", "24257", "24259", "24261", "24262", "24263", "24265", "24266", "24269", "24272", "24273", "24274", "24279", "24280", "24284", "24285", "24292", "24294", "24296", "24297", "24299", "24302", "24303", "24304", "24308", "24311", "24315", "24316", "24317", "24319", "24323", "24324", "24325", "24326", "24328", "24329", "24332", "24336", "24337", "24338", "24339", "24340", "24347", "24348", "24351", "24356", "24358", "24359", "24360", "24361", "24364", "24370", "24379", "24381", "24382", "24384", "24385", "24388", "24389", "24393", "24394", "24395", "24396", "24397", "24399", "24403", "24405", "24406", "24410", "24412", "24414", "24415", "24419", "24420", "24421", "24423", "24424", "24426", "24427", "24429", "24431", "24435", "24439", "24440", "24442", "24444", "24445", "24450", "24452", "24454", "24455", "24457", "24458", "24459", "24461", "24467", "24471", "24472", "24474", "24475", "24476", "24479", "24481", "24482", "24484", "24487", "24494", "24497", "24498", "24503", "24504", "24505", "24507", "24508", "24509", "24511", "24512", "24518", "24520", "24521", "24522", "24523", "24524", "24525", "24526", "24527", "24530", "24532", "24536", "24538", "24539", "24540", "24541", "24542", "24543", "24544", "24545", "24547", "24548", "24549", "24550", "24551", "24556", "24557", "24559", "24560", "24563", "24564", "24565", "24566", "24567", "24568", "24570", "24573", "24577", "24578", "24579", "24580", "24581", "24584", "24586", "24588", "24590", "24595", "24598", "24600", "24602", "24603", "24604", "24607", "24609", "24610", "24612", "24620", "24621", "24623", "24624", "24625", "24627", "24629", "24630", "24632", "24633", "24634", "24636", "24639", "24641", "24642", "24644", "24646", "24647", "24649", "24656", "24657", "24660", "24663", "24664", "24667", "24671", "24672", "24673", "24675", "24676", "24677", "24678", "24679", "24680", "24682", "24684", "24685", "24686", "24688", "24690", "24694", "24696", "24698", "24699", "24700", "24702", "24703", "24706", "24707", "24708", "24709", "24712", "24716", "24717", "24719", "24720", "24721", "24723", "24724", "24726", "24729", "24731", "24733", "24734", "24735", "24737", "24738", "24742", "24743", "24752", "24754", "24755", "24757", "24758", "24759", "24760", "24761", "24765", "24767", "24771", "24772", "24773", "24774", "24775", "24776", "24777", "24782", "24786", "24788", "24789", "24790", "24791", "24792", "24793", "24794", "24795", "24796", "24797", "24798", "24800", "24801", "24802", "24803", "24804", "24807", "24811", "24813", "24815", "24816", "24818", "24822", "24823", "24825", "24826", "24831", "24833", "24834", "24836", "24837", "24839", "24841", "24842", "24845", "24846", "24848", "24849", "24852", "24857", "24858", "24859", "24861", "24864", "24868", "24869", "24873", "24876", "24877", "24881", "24883", "24884", "24887", "24893", "24894", "24902", "24908", "24910", "24913", "24914", "24915", "24916", "24921", "24922", "24925", "24926", "24927", "24928", "24929", "24931", "24935", "24936", "24937", "24940", "24945", "24947", "24949", "24951", "24952", "24954", "24958", "24959", "24963", "24964", "24966", "24967", "24968", "24972", "24973", "24977", "24978", "24981", "24985", "24988", "24992", "24993", "24994", "24995", "24996", "24997", "24998", "25000", "25001", "25002", "25003", "25006", "25007", "25009", "25011", "25013", "25014", "25015", "25018", "25019", "25020", "25021", "25022", "25023", "25025", "25026", "25029", "25030", "25032", "25035", "25036", "25038", "25039", "25041", "25043", "25045", "25049", "25050", "25051", "25052", "25053", "25056", "25060", "25061", "25062", "25063", "25064", "25065", "25068", "25072", "25073", "25074", "25075", "25076", "25077", "25083", "25084", "25085", "25087", "25088", "25091", "25092", "25095", "25097", "25098", "25099", "25100", "25101", "25103", "25106", "25107", "25109", "25110", "25115", "25117", "25119", "25120", "25123", "25125", "25127", "25132", "25134", "25135", "25136", "25137", "25140", "25141", "25145", "25146", "25147", "25149", "25150", "25155", "25156", "25157", "25161", "25165", "25167", "25169", "25174", "25175", "25177", "25180", "25182", "25184", "25185", "25186", "25189", "25191", "25192", "25193", "25196", "25200", "25202", "25204", "25206", "25213", "25214", "25215", "25217", "25218", "25219", "25220", "25221", "25222", "25225", "25226", "25228", "25229", "25230", "25232", "25233", "25234", "25235", "25236", "25238", "25245", "25246", "25247", "25250", "25251", "25252", "25253", "25254", "25255", "25257", "25260", "25261", "25263", "25264", "25266", "25267", "25269", "25271", "25272", "25273", "25275", "25279", "25280", "25281", "25283", "25285", "25286", "25287", "25289", "25291", "25294", "25295", "25296", "25297", "25298", "25300", "25301", "25304", "25308", "25309", "25311", "25312", "25313", "25314", "25315", "25316", "25320", "25321", "25322", "25324", "25325", "25326", "25327", "25328", "25329", "25330", "25331", "25333", "25334", "25335", "25336", "25341", "25343", "25344", "25345", "25346", "25347", "25348", "25349", "25350", "25351", "25352", "25353", "25355", "25356", "25357", "25361", "25362", "25363", "25366", "25372", "25373", "25374", "25375", "25379", "25381", "25383", "25384", "25385", "25392", "25394", "25395", "25397", "25398", "25399", "25400", "25404", "25405", "25406", "25407", "25408", "25409", "25410", "25412", "25414", "25416", "25418", "25420", "25426", "25427", "25430", "25431", "25434", "25436", "25440", "25441", "25442", "25443", "25445", "25446", "25447", "25449", "25450", "25453", "25454", "25455", "25458", "25459", "25461", "25462", "25464", "25465", "25467", "25468", "25471", "25472", "25473", "25474", "25475", "25476", "25477", "25479", "25480", "25486", "25490", "25491", "25492", "25493", "25494", "25495", "25496", "25497", "25499", "25503", "25507", "25512", "25513", "25514", "25515", "25520", "25522", "25524", "25529", "25530", "25534", "25539", "25544", "25545", "25546", "25548", "25554", "25555", "25556", "25557", "25563", "25564", "25566", "25567", "25568", "25569", "25570", "25571", "25572", "25574", "25575", "25576", "25579", "25582", "25584", "25585", "25586", "25593", "25594", "25597", "25599", "25601", "25602", "25604", "25605", "25606", "25608", "25611", "25613", "25614", "25618", "25619", "25620", "25621", "25622", "25623", "25624", "25625", "25627", "25629", "25630", "25631", "25632", "25635", "25638", "25642", "25643", "25644", "25652", "25656", "25657", "25659", "25661", "25663", "25664", "25665", "25668", "25670", "25672", "25677", "25678", "25680", "25681", "25684", "25687", "25688", "25691", "25693", "25694", "25696", "25697", "25702", "25704", "25705", "25707", "25712", "25714", "25715", "25717", "25719", "25722", "25723", "25726", "25728", "25729", "25731", "25733", "25735", "25737", "25740", "25741", "25742", "25743", "25744", "25745", "25747", "25750", "25751", "25753", "25755", "25756", "25757", "25758", "25759", "25761", "25764", "25769", "25770", "25771", "25772", "25773", "25775", "25776", "25777", "25779", "25783", "25786", "25789", "25790", "25794", "25798", "25799", "25801", "25804", "25807", "25809", "25811", "25816", "25817", "25818", "25819", "25823", "25824", "25826", "25827", "25828", "25829", "25830", "25831", "25832", "25834", "25835", "25836", "25838", "25842", "25844", "25845", "25846", "25847", "25848", "25849", "25850", "25851", "25852", "25853", "25855", "25857", "25858", "25859", "25861", "25863", "25864", "25869", "25870", "25872", "25874", "25876", "25877", "25879", "25880", "25882", "25885", "25888", "25889", "25890", "25894", "25895", "25896", "25897", "25898", "25899", "25903", "25904", "25905", "25906", "25907", "25910", "25911", "25916", "25917", "25923", "25924", "25926", "25928", "25929", "25930", "25931", "25932", "25938", "25939", "25941", "25942", "25943", "25944", "25945", "25946", "25947", "25948", "25949", "25952", "25954", "25955", "25957", "25958", "25961", "25963", "25967", "25970", "25974", "25975", "25977", "25978", "25980", "25982", "25983", "25984", "25986", "25987", "25989", "25992", "25996", "25998", "25999", "26001", "26002", "26004", "26005", "26006", "26008", "26009", "26010", "26011", "26012", "26015", "26016", "26017", "26018", "26020", "26022", "26025", "26026", "26031", "26033", "26035", "26036", "26041", "26042", "26044", "26046", "26047", "26048", "26049", "26050", "26051", "26053", "26054", "26055", "26056", "26057", "26060", "26061", "26062", "26063", "26066", "26072", "26073", "26078", "26081", "26088", "26093", "26095", "26096", "26097", "26098", "26099", "26103", "26104", "26106", "26108", "26110", "26112", "26113", "26114", "26116", "26118", "26119", "26124", "26125", "26128", "26129", "26130", "26131", "26132", "26133", "26134", "26135", "26137", "26138", "26139", "26140", "26141", "26144", "26145", "26147", "26149", "26153", "26154", "26156", "26158", "26159", "26161", "26163", "26166", "26167", "26171", "26175", "26176", "26178", "26179", "26180", "26182", "26184", "26185", "26187", "26188", "26189", "26190", "26193", "26195", "26198", "26199", "26200", "26203", "26210", "26213", "26214", "26215", "26220", "26222", "26226", "26228", "26229", "26231", "26233", "26234", "26237", "26238", "26239", "26240", "26248", "26249", "26250", "26251", "26252", "26254", "26265", "26267", "26268", "26269", "26270", "26273", "26276", "26277", "26281", "26282", "26283", "26286", "26287", "26289", "26290", "26292", "26293", "26294", "26300", "26301", "26305", "26308", "26309", "26310", "26311", "26314", "26317", "26318", "26321", "26323", "26324", "26325", "26327", "26328", "26329", "26330", "26334", "26337", "26338", "26343", "26347", "26349", "26350", "26351", "26354", "26356", "26358", "26361", "26362", "26363", "26364", "26368", "26370", "26372", "26373", "26374", "26377", "26379", "26386", "26392", "26393", "26394", "26395", "26396", "26398", "26399", "26401", "26403", "26405", "26406", "26407", "26408", "26409", "26412", "26413", "26415", "26416", "26417", "26418", "26419", "26424", "26426", "26427", "26429", "26430", "26431", "26432", "26433", "26434", "26435", "26437", "26440", "26441", "26442", "26443", "26444", "26447", "26450", "26451", "26452", "26453", "26456", "26458", "26460", "26462", "26463", "26464", "26470", "26472", "26473", "26475", "26476", "26477", "26479", "26480", "26483", "26484", "26487", "26488", "26489", "26495", "26497", "26498", "26499", "26500", "26502", "26503", "26504", "26505", "26506", "26508", "26509", "26510", "26512", "26514", "26515", "26516", "26520", "26521", "26522", "26523", "26524", "26525", "26526", "26530", "26531", "26533", "26537", "26538", "26540", "26541", "26543", "26546", "26549", "26550", "26552", "26560", "26561", "26564", "26565", "26567", "26569", "26571", "26573", "26576", "26577", "26578", "26580", "26582", "26590", "26591", "26593", "26594", "26595", "26596", "26597", "26599", "26600", "26604", "26605", "26607", "26608", "26609", "26610", "26612", "26613", "26614", "26617", "26618", "26620", "26621", "26623", "26625", "26626", "26628", "26633", "26634", "26635", "26639", "26640", "26642", "26644", "26645", "26646", "26649", "26653", "26654", "26657", "26659", "26661", "26662", "26664", "26668", "26670", "26672", "26673", "26676", "26677", "26678", "26681", "26682", "26684", "26685", "26686", "26687", "26688", "26690", "26698", "26701", "26702", "26703", "26705", "26707", "26708", "26709", "26712", "26718", "26719", "26720", "26723", "26724", "26726", "26729", "26732", "26733", "26737", "26739", "26742", "26744", "26745", "26747", "26748", "26751", "26753", "26755", "26756", "26757", "26766", "26769", "26775", "26777", "26780", "26786", "26787", "26794", "26796", "26797", "26798", "26799", "26800", "26803", "26806", "26808", "26809", "26811", "26812", "26821", "26822", "26824", "26826", "26830", "26831", "26832", "26835", "26839", "26840", "26841", "26843", "26844", "26846", "26856", "26858", "26859", "26861", "26866", "26867", "26868", "26871", "26874", "26875", "26879", "26880", "26883", "26884", "26888", "26890", "26893", "26896", "26898", "26899", "26901", "26903", "26904", "26905", "26906", "26907", "26908", "26909", "26910", "26911", "26912", "26913", "26916", "26917", "26920", "26921", "26922", "26923", "26924", "26928", "26931", "26932", "26935", "26936", "26938", "26939", "26940", "26941", "26942", "26943", "26944", "26953", "26956", "26960", "26962", "26965", "26966", "26967", "26969", "26973", "26974", "26975", "26979", "26986", "26987", "26988", "26995", "26997", "26998", "27006", "27007", "27010", "27011", "27012", "27015", "27020", "27021", "27022", "27026", "27027", "27030", "27031", "27033", "27034", "27041", "27043", "27044", "27045", "27046", "27053", "27059", "27060", "27061", "27062", "27067", "27070", "27072", "27073", "27075", "27076", "27078", "27081", "27083", "27086", "27091", "27093", "27095", "27096", "27099", "27104", "27105", "27106", "27107", "27109", "27110", "27114", "27116", "27119", "27121", "27123", "27127", "27129", "27130", "27131", "27135", "27136", "27137", "27138", "27140", "27142", "27143", "27144", "27145", "27148", "27149", "27151", "27153", "27155", "27157", "27160", "27161", "27162", "27166", "27167", "27169", "27170", "27174", "27175", "27177", "27178", "27179", "27180", "27182", "27183", "27184", "27185", "27186", "27189", "27193", "27200", "27201", "27203", "27205", "27211", "27212", "27214", "27216", "27219", "27220", "27224", "27225", "27227", "27228", "27229", "27232", "27234", "27235", "27238", "27244", "27248", "27251", "27252", "27255", "27256", "27260", "27261", "27262", "27264", "27266", "27267", "27268", "27271", "27272", "27273", "27276", "27277", "27280", "27283", "27284", "27285", "27286", "27287", "27288", "27291", "27295", "27297", "27300", "27301", "27305", "27307", "27309", "27311", "27312", "27313", "27316", "27318", "27320", "27322", "27324", "27326", "27327", "27328", "27329", "27331", "27332", "27333", "27334", "27336", "27337", "27338", "27339", "27341", "27346", "27348", "27352", "27353", "27354", "27355", "27356", "27359", "27361", "27363", "27364", "27365", "27366", "27367", "27368", "27370", "27372", "27373", "27374", "27379", "27383", "27384", "27385", "27388", "27392", "27393", "27394", "27399", "27401", "27403", "27404", "27406", "27407", "27408", "27412", "27413", "27414", "27415", "27417", "27418", "27420", "27422", "27423", "27424", "27433", "27435", "27437", "27438", "27439", "27441", "27442", "27446", "27448", "27449", "27450", "27451", "27455", "27456", "27458", "27462", "27464", "27465", "27466", "27467", "27468", "27469", "27471", "27475", "27477", "27479", "27480", "27484", "27485", "27490", "27493", "27494", "27498", "27499", "27500", "27504", "27505", "27509", "27513", "27516", "27522", "27523", "27524", "27525", "27527", "27531", "27532", "27533", "27535", "27538", "27541", "27546", "27548", "27550", "27552", "27555", "27558", "27559", "27564", "27567", "27573", "27577", "27580", "27582", "27583", "27585", "27586", "27587", "27589", "27591", "27592", "27594", "27595", "27599", "27603", "27604", "27606", "27610", "27611", "27612", "27613", "27614", "27616", "27617", "27620", "27621", "27622", "27625", "27629", "27631", "27632", "27633", "27638", "27639", "27641", "27642", "27645", "27647", "27649", "27654", "27655", "27656", "27658", "27660", "27662", "27665", "27668", "27669", "27672", "27673", "27675", "27677", "27679", "27681", "27682", "27683", "27689", "27691", "27694", "27695", "27696", "27699", "27700", "27702", "27704", "27706", "27707", "27708", "27709", "27712", "27713", "27715", "27719", "27726", "27728", "27732", "27733", "27735", "27737", "27738", "27739", "27740", "27744", "27747", "27748", "27750", "27752", "27753", "27754", "27758", "27759", "27761", "27763", "27765", "27766", "27767", "27768", "27769", "27770", "27772", "27778", "27781", "27784", "27788", "27790", "27792", "27793", "27795", "27797", "27799", "27801", "27804", "27805", "27806", "27807", "27811", "27812", "27813", "27814", "27815", "27817", "27819", "27820", "27824", "27827", "27829", "27830", "27832", "27833", "27836", "27837", "27840", "27843", "27845", "27848", "27850", "27853", "27856", "27858", "27859", "27860", "27861", "27862", "27865", "27871", "27874", "27875", "27877", "27880", "27883", "27884", "27888", "27889", "27890", "27891", "27892", "27893", "27895", "27896", "27898", "27902", "27904", "27908", "27910", "27912", "27914", "27915", "27917", "27919", "27922", "27924", "27925", "27926", "27928", "27932", "27933", "27935", "27937", "27938", "27939", "27940", "27941", "27942", "27945", "27949", "27952", "27953", "27954", "27955", "27956", "27958", "27963", "27964", "27966", "27967", "27968", "27970", "27971", "27972", "27977", "27978", "27980", "27982", "27983", "27984", "27986", "27987", "27988", "27989", "27990", "27991", "27992", "27993", "27996", "27997", "27998", "28000", "28001", "28003", "28014", "28015", "28019", "28021", "28022", "28023", "28027", "28033", "28034", "28036", "28037", "28038", "28040", "28042", "28045", "28046", "28047", "28049", "28052", "28054", "28056", "28059", "28060", "28061", "28062", "28064", "28065", "28066", "28068", "28069", "28070", "28071", "28073", "28077", "28079", "28081", "28084", "28085", "28088", "28089", "28090", "28091", "28092", "28093", "28095", "28098", "28099", "28102", "28103", "28104", "28105", "28108", "28113", "28114", "28116", "28118", "28120", "28121", "28122", "28123", "28125", "28128", "28131", "28135", "28136", "28138", "28139", "28142", "28143", "28145", "28146", "28150", "28152", "28153", "28160", "28161", "28162", "28163", "28164", "28165", "28169", "28171", "28174", "28177", "28179", "28181", "28185", "28187", "28188", "28191", "28193", "28195", "28196", "28198", "28199", "28201", "28203", "28207", "28208", "28209", "28211", "28212", "28214", "28216", "28218", "28220", "28224", "28227", "28230", "28234", "28236", "28237", "28240", "28243", "28245", "28246", "28248", "28251", "28252", "28254", "28256", "28258", "28259", "28260", "28263", "28264", "28265", "28267", "28272", "28276", "28279", "28280", "28284", "28286", "28287", "28288", "28289", "28295", "28296", "28297", "28298", "28300", "28303", "28307", "28308", "28309", "28310", "28312", "28313", "28314", "28315", "28316", "28317", "28318", "28320", "28325", "28327", "28328", "28330", "28331", "28333", "28335", "28336", "28337", "28338", "28339", "28341", "28343", "28344", "28345", "28349", "28352", "28354", "28355", "28359", "28362", "28364", "28367", "28369", "28370", "28372", "28373", "28375", "28376", "28379", "28380", "28382", "28383", "28384", "28387", "28388", "28389", "28394", "28395", "28396", "28399", "28400", "28403", "28405", "28406", "28412", "28413", "28420", "28421", "28423", "28424", "28427", "28429", "28430", "28431", "28438", "28440", "28441", "28442", "28443", "28445", "28447", "28452", "28453", "28455", "28456", "28460", "28465", "28467", "28468", "28471", "28474", "28475", "28478", "28482", "28484", "28486", "28488", "28490", "28491", "28494", "28495", "28496", "28499", "28503", "28504", "28506", "28507", "28511", "28516", "28517", "28519", "28520", "28521", "28522", "28523", "28524", "28525", "28526", "28527", "28530", "28531", "28532", "28535", "28538", "28540", "28543", "28545", "28546", "28551", "28553", "28555", "28556", "28559", "28563", "28565", "28566", "28567", "28570", "28571", "28572", "28574", "28576", "28578", "28579", "28580", "28581", "28583", "28585", "28586", "28587", "28589", "28590", "28591", "28592", "28593", "28594", "28595", "28596", "28597", "28598", "28599", "28605", "28606", "28609", "28610", "28611", "28614", "28615", "28616", "28618", "28619", "28620", "28622", "28624", "28626", "28628", "28629", "28633", "28634", "28635", "28639", "28640", "28642", "28644", "28645", "28648", "28649", "28652", "28653", "28654", "28655", "28657", "28658", "28664", "28667", "28670", "28671", "28672", "28674", "28676", "28677", "28678", "28679", "28680", "28682", "28686", "28687", "28688", "28691", "28694", "28695", "28696", "28697", "28699", "28701", "28703", "28706", "28712", "28717", "28718", "28719", "28722", "28723", "28725", "28729", "28730", "28735", "28737", "28738", "28740", "28741", "28743", "28745", "28747", "28748", "28749", "28751", "28752", "28753", "28754", "28756", "28757", "28761", "28763", "28765", "28766", "28767", "28769", "28772", "28773", "28774", "28776", "28779", "28780", "28781", "28783", "28785", "28789", "28790", "28792", "28794", "28795", "28797", "28803", "28804", "28806", "28808", "28812", "28813", "28814", "28815", "28817", "28818", "28820", "28823", "28824", "28825", "28826", "28827", "28828", "28829", "28830", "28831", "28832", "28836", "28837", "28838", "28840", "28841", "28842", "28844", "28847", "28851", "28852", "28853", "28854", "28855", "28857", "28859", "28861", "28862", "28863", "28864", "28865", "28869", "28870", "28871", "28872", "28873", "28874", "28876", "28880", "28886", "28887", "28889", "28890", "28891", "28893", "28896", "28899", "28902", "28903", "28905", "28906", "28907", "28908", "28913", "28914", "28916", "28917", "28920", "28921", "28922", "28924", "28925", "28926", "28928", "28929", "28931", "28932", "28938", "28941", "28942", "28943", "28944", "28945", "28946", "28947", "28949", "28951", "28952", "28953", "28954", "28955", "28956", "28957", "28958", "28962", "28964", "28965", "28966", "28967", "28968", "28969", "28971", "28973", "28975", "28976", "28977", "28978", "28981", "28984", "28985", "28986", "28987", "28989", "28990", "28991", "28994", "28995", "28996", "28997", "28998", "29000", "29001", "29002", "29003", "29005", "29008", "29012", "29014", "29015", "29017", "29019", "29021", "29022", "29023", "29024", "29025", "29031", "29032", "29034", "29040", "29041", "29042", "29045", "29047", "29048", "29050", "29051", "29057", "29058", "29059", "29060", "29062", "29063", "29065", "29066", "29067", "29069", "29070", "29072", "29073", "29075", "29076", "29078", "29079", "29080", "29089", "29092", "29093", "29094", "29095", "29099", "29101", "29103", "29105", "29106", "29108", "29110", "29112", "29113", "29121", "29122", "29123", "29124", "29125", "29128", "29129", "29130", "29131", "29132", "29133", "29134", "29136", "29138", "29140", "29143", "29144", "29145", "29146", "29147", "29148", "29149", "29150", "29153", "29156", "29157", "29160", "29163", "29164", "29165", "29167", "29170", "29171", "29173", "29174", "29176", "29177", "29178", "29180", "29181", "29183", "29184", "29186", "29188", "29193", "29194", "29197", "29202", "29203", "29205", "29206", "29208", "29209", "29211", "29212", "29214", "29217", "29218", "29219", "29220", "29221", "29225", "29233", "29235", "29236", "29237", "29238", "29240", "29241", "29242", "29244", "29246", "29248", "29250", "29251", "29252", "29253", "29254", "29255", "29257", "29260", "29261", "29263", "29264", "29267", "29271", "29274", "29278", "29279", "29281", "29282", "29286", "29287", "29292", "29293", "29294", "29295", "29296", "29305", "29306", "29307", "29308", "29310", "29311", "29312", "29313", "29314", "29315", "29316", "29317", "29319", "29323", "29324", "29326", "29327", "29330", "29331", "29335", "29340", "29341", "29343", "29344", "29346", "29347", "29348", "29349", "29352", "29353", "29355", "29357", "29359", "29361", "29362", "29363", "29364", "29365", "29367", "29368", "29371", "29372", "29373", "29374", "29377", "29380", "29381", "29382", "29386", "29387", "29389", "29390", "29391", "29395", "29396", "29398", "29399", "29403", "29405", "29406", "29407", "29409", "29411", "29417", "29418", "29419", "29420", "29421", "29422", "29424", "29426", "29429", "29434", "29436", "29437", "29438", "29439", "29444", "29447", "29448", "29449", "29450", "29451", "29453", "29456", "29457", "29458", "29461", "29464", "29468", "29469", "29471", "29476", "29481", "29483", "29484", "29486", "29487", "29488", "29489", "29492", "29494", "29496", "29499", "29500", "29502", "29503", "29504", "29508", "29510", "29514", "29518", "29523", "29524", "29527", "29528", "29530", "29533", "29534", "29535", "29536", "29539", "29540", "29541", "29544", "29545", "29546", "29547", "29552", "29554", "29556", "29557", "29560", "29561", "29563", "29568", "29569", "29571", "29572", "29576", "29578", "29583", "29585", "29588", "29590", "29593", "29595", "29596", "29598", "29600", "29602", "29607", "29609", "29610", "29614", "29617", "29622", "29623", "29624", "29625", "29627", "29629", "29630", "29631", "29633", "29634", "29635", "29638", "29644", "29645", "29646", "29647", "29651", "29652", "29656", "29658", "29659", "29665", "29666", "29667", "29668", "29669", "29671", "29672", "29674", "29675", "29676", "29679", "29682", "29683", "29688", "29690", "29691", "29693", "29694", "29698", "29701", "29704", "29708", "29709", "29710", "29712", "29713", "29714", "29716", "29718", "29720", "29721", "29723", "29724", "29729", "29734", "29736", "29738", "29739", "29740", "29742", "29744", "29750", "29751", "29755", "29756", "29759", "29761", "29763", "29764", "29765", "29767", "29769", "29771", "29772", "29774", "29776", "29777", "29780", "29783", "29784", "29785", "29786", "29788", "29789", "29790", "29791", "29794", "29797", "29805", "29806", "29808", "29809", "29811", "29812", "29814", "29815", "29825", "29826", "29827", "29831", "29833", "29837", "29839", "29845", "29846", "29847", "29848", "29849", "29850", "29852", "29854", "29855", "29856", "29863", "29864", "29867", "29869", "29870", "29875", "29877", "29878", "29879", "29880", "29881", "29883", "29885", "29886", "29887", "29890", "29893", "29897", "29898", "29899", "29903", "29906", "29911", "29912", "29914", "29919", "29921", "29922", "29923", "29925", "29928", "29929", "29930", "29931", "29934", "29938", "29940", "29941", "29942", "29944", "29946", "29947", "29949", "29956", "29958", "29959", "29962", "29963", "29969", "29970", "29971", "29973", "29975", "29978", "29982", "29983", "29984", "29986", "29990", "29991", "29992", "29996", "29999", "30001", "30002", "30006", "30008", "30010", "30011", "30016", "30017", "30022", "30024", "30027", "30035", "30040", "30043", "30044", "30045", "30047", "30049", "30053", "30056", "30057", "30059", "30062", "30063", "30065", "30067", "30069", "30070", "30071", "30072", "30073", "30074", "30076", "30077", "30078", "30079", "30080", "30081", "30083", "30085", "30086", "30093", "30098", "30099", "30102", "30103", "30104", "30106", "30107", "30108", "30110", "30116", "30117", "30118", "30120", "30122", "30124", "30125", "30128", "30129", "30130", "30131", "30132", "30134", "30136", "30140", "30142", "30144", "30145", "30148", "30149", "30150", "30152", "30153", "30154", "30155", "30156", "30158", "30159", "30160", "30162", "30163", "30165", "30166", "30167", "30168", "30169", "30170", "30171", "30172", "30173", "30175", "30177", "30179", "30180", "30182", "30184", "30185", "30187", "30189", "30194", "30195", "30196", "30198", "30199", "30201", "30203", "30204", "30206", "30208", "30209", "30210", "30211", "30213", "30214", "30215", "30218", "30219", "30220", "30221", "30232", "30233", "30234", "30235", "30236", "30238", "30239", "30242", "30244", "30246", "30247", "30249", "30253", "30258", "30259", "30260", "30261", "30263", "30266", "30267", "30269", "30270", "30271", "30272", "30274", "30275", "30277", "30280", "30281", "30285", "30287", "30289", "30294", "30295", "30299", "30303", "30307", "30310", "30311", "30313", "30314", "30316", "30318", "30321", "30324", "30325", "30326", "30327", "30328", "30329", "30331", "30334", "30335", "30336", "30338", "30340", "30341", "30343", "30345", "30346", "30347", "30351", "30352", "30353", "30356", "30360", "30362", "30364", "30365", "30366", "30367", "30368", "30369", "30370", "30372", "30373", "30374", "30376", "30378", "30381", "30382", "30386", "30388", "30390", "30397", "30398", "30399", "30400", "30401", "30402", "30403", "30406", "30410", "30414", "30417", "30419", "30422", "30425", "30430", "30434", "30435", "30437", "30439", "30440", "30441", "30442", "30443", "30445", "30446", "30447", "30448", "30449", "30451", "30452", "30453", "30455", "30456", "30457", "30458", "30460", "30461", "30462", "30463", "30464", "30465", "30470", "30473", "30475", "30476", "30478", "30479", "30480", "30484", "30485", "30488", "30492", "30493", "30496", "30497", "30501", "30504", "30505", "30507", "30511", "30512", "30513", "30514", "30516", "30518", "30519", "30521", "30523", "30527", "30530", "30531", "30533", "30534", "30537", "30538", "30541", "30543", "30544", "30547", "30548", "30549", "30550", "30551", "30554", "30555", "30557", "30561", "30562", "30563", "30566", "30569", "30571", "30575", "30576", "30577", "30581", "30583", "30586", "30588", "30589", "30590", "30591", "30592", "30593", "30594", "30599", "30602", "30603", "30604", "30606", "30608", "30609", "30610", "30612", "30614", "30616", "30619", "30621", "30624", "30625", "30626", "30628", "30630", "30634", "30636", "30637", "30639", "30642", "30643", "30644", "30645", "30648", "30649", "30654", "30655", "30658", "30659", "30660", "30661", "30667", "30669", "30670", "30672", "30675", "30676", "30677", "30678", "30679", "30680", "30682", "30683", "30685", "30687", "30688", "30690", "30694", "30697", "30701", "30704", "30708", "30709", "30710", "30711", "30716", "30717", "30719", "30720", "30723", "30724", "30730", "30734", "30737", "30739", "30740", "30741", "30742", "30745", "30747", "30749", "30750", "30752", "30753", "30755", "30756", "30758", "30759", "30760", "30765", "30766", "30771", "30772", "30774", "30775", "30776", "30778", "30781", "30782", "30784", "30785", "30786", "30787", "30789", "30791", "30792", "30793", "30795", "30799", "30800", "30804", "30805", "30806", "30807", "30808", "30809", "30813", "30818", "30820", "30821", "30825", "30827", "30828", "30829", "30830", "30837", "30838", "30839", "30844", "30845", "30847", "30848", "30851", "30857", "30860", "30861", "30862", "30870", "30873", "30875", "30876", "30878", "30879", "30880", "30885", "30886", "30887", "30888", "30889", "30890", "30891", "30892", "30893", "30894", "30895", "30904", "30905", "30906", "30908", "30910", "30913", "30916", "30917", "30920", "30923", "30924", "30925", "30926", "30929", "30931", "30932", "30933", "30934", "30935", "30936", "30937", "30939", "30940", "30941", "30944", "30945", "30952", "30953", "30956", "30961", "30962", "30967", "30968", "30970", "30971", "30972", "30973", "30975", "30977", "30978", "30980", "30984", "30987", "30992", "30993", "30994", "31000", "31001", "31002", "31004", "31006", "31007", "31010", "31012", "31014", "31016", "31020", "31026", "31028", "31029", "31031", "31032", "31036", "31038", "31045", "31047", "31049", "31051", "31052", "31053", "31058", "31059", "31062", "31063", "31064", "31066", "31073", "31074", "31079", "31080", "31081", "31083", "31086", "31089", "31091", "31092", "31093", "31094", "31095", "31096", "31098", "31099", "31101", "31102", "31103", "31105", "31106", "31108", "31109", "31114", "31115", "31119", "31121", "31122", "31126", "31127", "31129", "31131", "31133", "31135", "31137", "31139", "31141", "31142", "31144", "31145", "31149", "31151", "31153", "31157", "31159", "31160", "31161", "31164", "31166", "31167", "31170", "31172", "31175", "31177", "31181", "31182", "31184", "31187", "31188", "31189", "31190", "31192", "31194", "31197", "31198", "31199", "31200", "31201", "31202", "31203", "31204", "31205", "31206", "31210", "31211", "31212", "31213", "31214", "31215", "31218", "31219", "31222", "31223", "31226", "31230", "31231", "31232", "31235", "31236", "31239", "31241", "31242", "31243", "31249", "31250", "31253", "31258", "31259", "31262", "31266", "31269", "31270", "31273", "31276", "31279", "31280", "31282", "31283", "31285", "31286", "31288", "31289", "31294", "31296", "31297", "31299", "31302", "31304", "31306", "31309", "31310", "31311", "31314", "31315", "31318", "31319", "31321", "31324", "31325", "31326", "31328", "31333", "31336", "31337", "31338", "31340", "31343", "31344", "31345", "31346", "31347", "31348", "31349", "31350", "31355", "31359", "31363", "31367", "31368", "31369", "31370", "31372", "31373", "31374", "31376", "31378", "31381", "31382", "31385", "31386", "31388", "31389", "31391", "31392", "31394", "31398", "31399", "31400", "31401", "31403", "31406", "31407", "31409", "31410", "31411", "31413", "31415", "31418", "31422", "31424", "31425", "31426", "31427", "31428", "31429", "31432", "31434", "31436", "31438", "31441", "31443", "31444", "31445", "31446", "31450", "31452", "31453", "31454", "31457", "31458", "31459", "31461", "31463", "31465", "31466", "31468", "31469", "31472", "31474", "31478", "31480", "31482", "31484", "31485", "31487", "31489", "31492", "31493", "31494", "31495", "31497", "31500", "31501", "31505", "31508", "31513", "31515", "31517", "31519", "31521", "31523", "31528", "31531", "31533", "31537", "31538", "31539", "31546", "31548", "31550", "31553", "31555", "31557", "31558", "31561", "31562", "31564", "31566", "31567", "31568", "31580", "31581", "31582", "31585", "31586", "31588", "31589", "31590", "31595", "31596", "31597", "31604", "31606", "31607", "31611", "31612", "31614", "31616", "31619", "31621", "31622", "31626", "31627", "31628", "31629", "31631", "31633", "31637", "31639", "31643", "31646", "31647", "31652", "31654", "31655", "31660", "31661", "31662", "31663", "31665", "31666", "31669", "31671", "31673", "31674", "31675", "31676", "31678", "31681", "31682", "31689", "31690", "31691", "31692", "31698", "31701", "31703", "31705", "31706", "31709", "31713", "31714", "31715", "31716", "31719", "31720", "31721", "31723", "31725", "31726", "31727", "31728", "31730", "31732", "31733", "31734", "31738", "31739", "31740", "31743", "31744", "31745", "31747", "31751", "31753", "31756", "31759", "31760", "31761", "31762", "31766", "31768", "31769", "31770", "31771", "31772", "31773", "31781", "31785", "31787", "31789", "31790", "31792", "31793", "31795", "31797", "31798", "31800", "31808", "31810", "31815", "31819", "31820", "31827", "31830", "31834", "31835", "31836", "31837", "31841", "31844", "31845", "31847", "31848", "31850", "31851", "31852", "31853", "31854", "31856", "31857", "31858", "31859", "31866", "31869", "31872", "31875", "31876", "31877", "31878", "31879", "31880", "31881", "31882", "31889", "31891", "31893", "31896", "31897", "31898", "31901", "31902", "31903", "31904", "31907", "31909", "31911", "31913", "31915", "31919", "31923", "31924", "31925", "31926", "31927", "31928", "31932", "31934", "31938", "31940", "31941", "31942", "31943", "31952", "31953", "31957", "31959", "31961", "31968", "31970", "31972", "31974", "31976", "31977", "31980", "31983", "31984", "31986", "31989", "31994", "31995", "31998", "32005", "32010", "32011", "32016", "32018", "32019", "32023", "32026", "32027", "32028", "32029", "32030", "32033", "32034", "32036", "32038", "32039", "32042", "32045", "32048", "32050", "32053", "32061", "32062", "32063", "32065", "32067", "32068", "32071", "32073", "32074", "32075", "32076", "32077", "32080", "32081", "32082", "32084", "32088", "32090", "32091", "32092", "32095", "32096", "32098", "32099", "32100", "32102", "32103", "32104", "32105", "32106", "32107", "32109", "32110", "32112", "32114", "32120", "32122", "32123", "32124", "32126", "32127", "32128", "32132", "32133", "32134", "32137", "32142", "32147", "32149", "32150", "32153", "32154", "32159", "32162", "32163", "32165", "32168", "32169", "32170", "32171", "32174", "32176", "32179", "32180", "32181", "32185", "32188", "32195", "32197", "32199", "32200", "32201", "32202", "32203", "32204", "32205", "32208", "32209", "32211", "32212", "32213", "32214", "32218", "32219", "32220", "32221", "32223", "32224", "32228", "32233", "32235", "32236", "32238", "32239", "32240", "32243", "32244", "32245", "32246", "32247", "32248", "32249", "32250", "32256", "32258", "32260", "32263", "32266", "32267", "32270", "32272", "32274", "32276", "32278", "32284", "32285", "32287", "32289", "32292", "32295", "32297", "32298", "32301", "32302", "32303", "32304", "32305", "32307", "32310", "32312", "32313", "32314", "32315", "32316", "32317", "32318", "32321", "32326", "32328", "32329", "32330", "32332", "32333", "32334", "32338", "32339", "32340", "32344", "32345", "32351", "32353", "32355", "32356", "32358", "32359", "32360", "32361", "32363", "32364", "32365", "32368", "32372", "32374", "32375", "32376", "32377", "32379", "32384", "32385", "32387", "32388", "32389", "32390", "32393", "32394", "32398", "32402", "32403", "32405", "32406", "32410", "32411", "32412", "32414", "32415", "32418", "32420", "32421", "32422", "32423", "32424", "32428", "32429", "32431", "32432", "32433", "32434", "32435", "32437", "32439", "32440", "32441", "32448", "32449", "32450", "32451", "32455", "32456", "32459", "32463", "32465", "32466", "32467", "32469", "32471", "32472", "32474", "32475", "32476", "32479", "32480", "32481", "32482", "32483", "32484", "32485", "32488", "32490", "32492", "32495", "32496", "32497", "32499", "32501", "32502", "32505", "32508", "32509", "32511", "32514", "32515", "32517", "32519", "32520", "32521", "32522", "32527", "32532", "32534", "32535", "32540", "32542", "32543", "32544", "32545", "32546", "32548", "32549", "32550", "32551", "32552", "32554", "32555", "32562", "32565", "32569", "32570", "32572", "32575", "32576", "32577", "32578", "32584", "32586", "32591", "32592", "32593", "32594", "32596", "32599", "32600", "32601", "32604", "32609", "32612", "32613", "32615", "32616", "32620", "32621", "32623", "32626", "32628", "32630", "32631", "32632", "32635", "32636", "32637", "32639", "32640", "32641", "32642", "32643", "32647", "32648", "32649", "32650", "32653", "32654", "32656", "32657", "32658", "32660", "32661", "32662", "32666", "32667", "32668", "32676", "32677", "32679", "32682", "32687", "32688", "32690", "32692", "32693", "32694", "32695", "32697", "32701", "32704", "32705", "32706", "32709", "32712", "32715", "32717", "32721", "32722", "32725", "32726", "32727", "32728", "32729", "32731", "32733", "32734", "32738", "32740", "32741", "32743", "32745", "32746", "32747", "32749", "32750", "32759", "32760", "32762", "32764", "32765", "32766", "32767", "32773", "32775", "32779", "32780", "32781", "32782", "32783", "32784", "32787", "32788", "32792", "32793", "32794", "32797", "32799", "32802", "32803", "32804", "32805", "32806", "32807", "32808", "32813", "32814", "32815", "32818", "32819", "32820", "32821", "32827", "32828", "32829", "32831", "32832", "32833", "32834", "32839", "32841", "32842", "32844", "32850", "32852", "32854", "32855", "32857", "32859", "32860", "32861", "32862", "32863", "32865", "32866", "32870", "32871", "32873", "32874", "32876", "32878", "32881", "32882", "32885", "32886", "32893", "32894", "32895", "32900", "32901", "32902", "32904", "32906", "32909", "32911", "32912", "32916", "32917", "32918", "32921", "32924", "32925", "32926", "32928", "32929", "32932", "32933", "32936", "32937", "32938", "32940", "32945", "32947", "32948", "32949", "32950", "32951", "32955", "32956", "32958", "32960", "32961", "32963", "32965", "32966", "32967", "32969", "32970", "32973", "32975", "32976", "32977", "32979", "32980", "32982", "32983", "32986", "32988", "32989", "32990", "32992", "32994", "32996", "32998", "33000", "33004", "33005", "33007", "33009", "33011", "33013", "33014", "33015", "33019", "33020", "33021", "33022", "33025", "33027", "33028", "33030", "33031", "33033", "33034", "33036", "33037", "33039", "33041", "33042", "33043", "33045", "33046", "33047", "33049", "33050", "33051", "33052", "33054", "33055", "33056", "33057", "33058", "33060", "33061", "33064", "33066", "33067", "33068", "33069", "33077", "33078", "33079", "33081", "33082", "33083", "33086", "33087", "33092", "33094", "33096", "33097", "33098", "33100", "33102", "33103", "33105", "33106", "33107", "33110", "33111", "33116", "33118", "33119", "33120", "33121", "33122", "33123", "33125", "33128", "33129", "33130", "33133", "33134", "33135", "33138", "33139", "33141", "33142", "33146", "33147", "33148", "33153", "33154", "33160", "33166", "33167", "33168", "33169", "33170", "33171", "33173", "33174", "33175", "33177", "33178", "33179", "33181", "33186", "33187", "33189", "33192", "33193", "33199", "33200", "33201", "33203", "33206", "33207", "33209", "33210", "33212", "33214", "33215", "33216", "33217", "33221", "33224", "33225", "33227", "33230", "33236", "33237", "33238", "33240", "33242", "33244", "33245", "33247", "33248", "33251", "33252", "33259", "33261", "33262", "33263", "33265", "33267", "33268", "33270", "33271", "33272", "33273", "33275", "33277", "33280", "33281", "33282", "33285", "33286", "33287", "33288", "33290", "33291", "33294", "33295", "33296", "33297", "33298", "33300", "33301", "33303", "33304", "33307", "33311", "33314", "33315", "33317", "33318", "33319", "33320", "33321", "33323", "33324", "33326", "33327", "33328", "33329", "33331", "33332", "33333", "33336", "33338", "33340", "33344", "33345", "33346", "33348", "33351", "33355", "33358", "33361", "33364", "33366", "33367", "33371", "33373", "33375", "33376", "33377", "33378", "33382", "33383", "33385", "33388", "33390", "33391", "33393", "33402", "33403", "33404", "33405", "33407", "33409", "33410", "33414", "33416", "33418", "33420", "33421", "33423", "33424", "33425", "33428", "33430", "33431", "33432", "33436", "33438", "33439", "33440", "33441", "33443", "33445", "33447", "33449", "33452", "33454", "33465", "33467", "33469", "33473", "33479", "33481", "33483", "33484", "33485", "33487", "33491", "33494", "33497", "33498", "33499", "33500", "33501", "33504", "33505", "33509", "33511", "33515", "33517", "33518", "33519", "33522", "33523", "33524", "33527", "33528", "33529", "33530", "33531", "33532", "33533", "33534", "33539", "33542", "33543", "33544", "33546", "33547", "33550", "33552", "33553", "33554", "33556", "33558", "33559", "33561", "33564", "33565", "33567", "33568", "33571", "33572", "33573", "33578", "33584", "33586", "33588", "33589", "33593", "33594", "33597", "33599", "33600", "33601", "33602", "33605", "33606", "33607", "33609", "33612", "33613", "33617", "33619", "33620", "33621", "33622", "33624", "33626", "33628", "33630", "33631", "33633", "33641", "33642", "33644", "33648", "33649", "33651", "33653", "33654", "33656", "33657", "33659", "33661", "33662", "33665", "33668", "33670", "33671", "33673", "33675", "33676", "33677", "33678", "33679", "33680", "33682", "33683", "33684", "33687", "33689", "33690", "33692", "33693", "33694", "33695", "33696", "33699", "33701", "33702", "33703", "33704", "33706", "33707", "33710", "33711", "33712", "33713", "33718", "33720", "33721", "33722", "33723", "33725", "33726", "33727", "33729", "33731", "33733", "33735", "33740", "33741", "33742", "33751", "33752", "33755", "33759", "33760", "33761", "33765", "33766", "33768", "33770", "33773", "33776", "33779", "33780", "33785", "33793", "33797", "33798", "33799", "33800", "33801", "33805", "33807", "33814", "33818", "33823", "33826", "33829", "33830", "33831", "33833", "33834", "33836", "33837", "33840", "33843", "33846", "33849", "33850", "33851", "33854", "33855", "33859", "33862", "33863", "33866", "33867", "33869", "33870", "33871", "33872", "33873", "33875", "33877", "33883", "33884", "33888", "33890", "33891", "33893", "33894", "33898", "33899", "33905", "33906", "33907", "33908", "33909", "33910", "33913", "33914", "33917", "33923", "33924", "33930", "33931", "33933", "33936", "33938", "33941", "33945", "33946", "33951", "33954", "33956", "33958", "33959", "33961", "33963", "33965", "33966", "33968", "33970", "33971", "33973", "33974", "33978", "33984", "33987", "33988", "33990", "33992", "33993", "33994", "33995", "33997", "33999", "34000", "34002", "34003", "34004", "34010", "34011", "34012", "34013", "34014", "34017", "34019", "34022", "34023", "34024", "34025", "34026", "34029", "34030", "34034", "34039", "34041", "34043", "34044", "34046", "34047", "34049", "34055", "34056", "34057", "34059", "34065", "34072", "34081", "34084", "34085", "34086", "34088", "34089", "34094", "34096", "34097", "34098", "34099", "34102", "34104", "34106", "34107", "34108", "34109", "34110", "34111", "34113", "34118", "34119", "34120", "34121", "34122", "34125", "34126", "34128", "34129", "34133", "34134", "34136", "34140", "34141", "34142", "34143", "34144", "34145", "34151", "34152", "34154", "34155", "34157", "34159", "34161", "34162", "34165", "34166", "34167", "34168", "34171", "34172", "34173", "34175", "34177", "34178", "34179", "34185", "34190", "34191", "34192", "34194", "34195", "34196", "34197", "34205", "34206", "34208", "34209", "34210", "34211", "34212", "34213", "34214", "34215", "34217", "34218", "34219", "34221", "34224", "34225", "34227", "34228", "34232", "34233", "34234", "34235", "34237", "34238", "34239", "34240", "34241", "34242", "34243", "34247", "34248", "34249", "34250", "34255", "34258", "34260", "34264", "34267", "34268", "34272", "34276", "34280", "34283", "34285", "34287", "34290", "34291", "34292", "34293", "34294", "34297", "34299", "34300", "34301", "34302", "34304", "34307", "34308", "34309", "34311", "34312", "34313", "34315", "34317", "34318", "34319", "34322", "34323", "34325", "34326", "34327", "34329", "34330", "34331", "34337", "34341", "34342", "34345", "34346", "34348", "34349", "34350", "34355", "34356", "34357", "34362", "34366", "34367", "34368", "34369", "34370", "34374", "34375", "34377", "34378", "34379", "34380", "34381", "34382", "34386", "34389", "34390", "34392", "34395", "34397", "34400", "34402", "34406", "34408", "34409", "34410", "34411", "34413", "34414", "34415", "34416", "34418", "34420", "34421", "34423", "34424", "34426", "34429", "34431", "34434", "34435", "34437", "34439", "34440", "34443", "34445", "34446", "34449", "34450", "34451", "34452", "34453", "34455", "34456", "34458", "34459", "34460", "34463", "34468", "34470", "34471", "34474", "34478", "34479", "34480", "34481", "34482", "34483", "34484", "34486", "34487", "34490", "34493", "34494", "34495", "34496", "34498", "34499", "34503", "34504", "34506", "34507", "34509", "34510", "34515", "34517", "34518", "34520", "34522", "34523", "34525", "34527", "34532", "34533", "34535", "34537", "34542", "34543", "34546", "34547", "34550", "34553", "34554", "34556", "34557", "34558", "34559", "34561", "34565", "34568", "34569", "34571", "34573", "34574", "34575", "34576", "34578", "34580", "34581", "34584", "34588", "34590", "34591", "34592", "34593", "34594", "34595", "34597", "34601", "34603", "34604", "34605", "34606", "34607", "34608", "34610", "34611", "34613", "34615", "34616", "34617", "34618", "34620", "34621", "34622", "34626", "34627", "34629", "34630", "34631", "34634", "34635", "34640", "34643", "34644", "34645", "34648", "34649", "34651", "34652", "34653", "34654", "34666", "34668", "34670", "34671", "34672", "34676", "34677", "34681", "34682", "34683", "34685", "34686", "34688", "34689", "34690", "34691", "34692", "34693", "34694", "34695", "34699", "34700", "34701", "34703", "34705", "34707", "34708", "34710", "34712", "34713", "34715", "34716", "34718", "34720", "34721", "34724", "34727", "34728", "34732", "34734", "34735", "34737", "34738", "34739", "34746", "34747", "34748", "34750", "34755", "34757", "34758", "34759", "34761", "34762", "34769", "34771", "34772", "34775", "34777", "34778", "34779", "34780", "34783", "34785", "34786", "34788", "34790", "34791", "34793", "34795", "34796", "34798", "34799", "34803", "34805", "34808", "34809", "34810", "34814", "34817", "34820", "34825", "34827", "34830", "34832", "34833", "34836", "34837", "34838", "34839", "34840", "34842", "34845", "34846", "34849", "34854", "34857", "34860", "34861", "34864", "34865", "34866", "34871", "34872", "34875", "34879", "34880", "34881", "34883", "34885", "34886", "34888", "34892", "34894", "34895", "34896", "34897", "34899", "34905", "34906", "34907", "34911", "34912", "34913", "34914", "34917", "34918", "34921", "34922", "34923", "34925", "34926", "34928", "34929", "34931", "34932", "34934", "34935", "34936", "34943", "34946", "34947", "34948", "34950", "34952", "34954", "34955", "34958", "34961", "34962", "34966", "34967", "34968", "34969", "34971", "34976", "34977", "34979", "34981", "34982", "34983", "34984", "34985", "34986", "34988", "34989", "34992", "34994", "34995", "34996", "34997", "34998", "35001", "35002", "35007", "35010", "35011", "35013", "35015", "35016", "35018", "35022", "35024", "35025", "35026", "35028", "35034", "35036", "35040", "35041", "35042", "35047", "35052", "35055", "35056", "35058", "35059", "35060", "35062", "35065", "35068", "35073", "35074", "35075", "35077", "35078", "35080", "35082", "35083", "35087", "35088", "35096", "35097", "35100", "35101", "35102", "35104", "35106", "35107", "35110", "35111", "35112", "35114", "35115", "35116", "35117", "35118", "35119", "35120", "35121", "35126", "35127", "35128", "35133", "35134", "35137", "35138", "35141", "35142", "35145", "35147", "35149", "35150", "35151", "35153", "35155", "35157", "35158", "35160", "35165", "35174", "35175", "35176", "35177", "35180", "35182", "35183", "35184", "35185", "35187", "35189", "35191", "35192", "35193", "35194", "35197", "35202", "35203", "35206", "35207", "35208", "35209", "35210", "35211", "35213", "35214", "35215", "35216", "35217", "35218", "35221", "35222", "35223", "35226", "35227", "35228", "35232", "35236", "35238", "35239", "35240", "35241", "35243", "35245", "35248", "35249", "35253", "35255", "35257", "35259", "35260", "35261", "35262", "35265", "35267", "35268", "35269", "35270", "35271", "35273", "35274", "35278", "35280", "35281", "35284", "35285", "35289", "35290", "35291", "35292", "35293", "35294", "35297", "35301", "35302", "35303", "35305", "35306", "35308", "35310", "35312", "35315", "35317", "35326", "35327", "35331", "35332", "35333", "35335", "35336", "35337", "35340", "35342", "35345", "35346", "35347", "35351", "35352", "35353", "35354", "35355", "35356", "35357", "35359", "35360", "35363", "35365", "35366", "35367", "35368", "35370", "35372", "35376", "35377", "35378", "35381", "35383", "35385", "35389", "35390", "35393", "35396", "35397", "35400", "35401", "35404", "35406", "35407", "35408", "35410", "35411", "35412", "35413", "35415", "35417", "35423", "35424", "35425", "35426", "35428", "35429", "35430", "35435", "35437", "35438", "35441", "35448", "35449", "35450", "35452", "35453", "35454", "35456", "35460", "35461", "35462", "35464", "35466", "35467", "35470", "35471", "35474", "35475", "35476", "35477", "35478", "35479", "35483", "35485", "35486", "35487", "35489", "35492", "35493", "35497", "35498", "35499", "35500", "35501", "35504", "35506", "35509", "35511", "35512", "35514", "35518", "35525", "35527", "35532", "35533", "35535", "35536", "35538", "35539", "35540", "35541", "35545", "35546", "35547", "35551", "35552", "35553", "35554", "35559", "35563", "35564", "35565", "35567", "35568", "35569", "35570", "35575", "35576", "35577", "35579", "35580", "35582", "35584", "35585", "35587", "35589", "35590", "35591", "35592", "35593", "35596", "35601", "35602", "35603", "35604", "35606", "35608", "35610", "35612", "35615", "35616", "35618", "35619", "35622", "35623", "35624", "35625", "35627", "35629", "35631", "35633", "35634", "35639", "35640", "35641", "35642", "35643", "35644", "35645", "35647", "35650", "35651", "35652", "35653", "35658", "35660", "35661", "35662", "35665", "35666", "35667", "35670", "35674", "35675", "35676", "35679", "35680", "35686", "35690", "35693", "35694", "35695", "35701", "35704", "35705", "35707", "35708", "35709", "35710", "35711", "35713", "35715", "35717", "35719", "35721", "35722", "35723", "35730", "35731", "35732", "35733", "35734", "35735", "35737", "35738", "35739", "35740", "35741", "35742", "35744", "35745", "35748", "35749", "35750", "35752", "35755", "35756", "35758", "35759", "35760", "35761", "35769", "35770", "35771", "35773", "35774", "35776", "35777", "35780", "35783", "35784", "35786", "35787", "35788", "35789", "35790", "35791", "35793", "35795", "35796", "35797", "35800", "35801", "35806", "35808", "35809", "35810", "35811", "35812", "35813", "35819", "35820", "35821", "35822", "35823", "35824", "35827", "35828", "35830", "35831", "35833", "35834", "35837", "35840", "35844", "35845", "35857", "35858", "35860", "35862", "35867", "35869", "35871", "35873", "35874", "35875", "35877", "35878", "35886", "35888", "35890", "35894", "35896", "35897", "35899", "35901", "35903", "35904", "35905", "35906", "35907", "35909", "35913", "35914", "35915", "35919", "35920", "35922", "35923", "35924", "35925", "35926", "35928", "35931", "35932", "35933", "35934", "35936", "35937", "35938", "35939", "35942", "35945", "35946", "35947", "35949", "35950", "35951", "35955", "35956", "35957", "35958", "35960", "35961", "35962", "35963", "35964", "35965", "35966", "35967", "35968", "35972", "35973", "35974", "35980", "35981", "35987", "35991", "35993", "35994", "35995", "35996", "35997", "35998", "36000", "36006", "36010", "36011", "36014", "36015", "36018", "36020", "36022", "36025", "36026", "36027", "36028", "36029", "36030", "36032", "36034", "36035", "36036", "36037", "36038", "36039", "36040", "36043", "36044", "36045", "36046", "36049", "36052", "36053", "36054", "36055", "36056", "36058", "36061", "36062", "36066", "36067", "36069", "36073", "36076", "36080", "36082", "36083", "36084", "36086", "36087", "36089", "36091", "36092", "36093", "36095", "36097", "36099", "36100", "36101", "36103", "36104", "36105", "36109", "36110", "36113", "36114", "36117", "36118", "36120", "36121", "36122", "36123", "36124", "36125", "36131", "36132", "36133", "36135", "36136", "36137", "36138", "36139", "36140", "36141", "36143", "36144", "36146", "36149", "36152", "36154", "36155", "36160", "36163", "36164", "36165", "36166", "36167", "36168", "36169", "36171", "36173", "36175", "36177", "36178", "36179", "36181", "36184", "36185", "36187", "36188", "36190", "36191", "36195", "36196", "36197", "36198", "36199", "36200", "36201", "36204", "36206", "36207", "36208", "36211", "36212", "36213", "36215", "36216", "36218", "36219", "36220", "36221", "36225", "36227", "36229", "36230", "36237", "36238", "36243", "36244", "36247", "36249", "36254", "36255", "36259", "36260", "36261", "36264", "36268", "36269", "36271", "36277", "36278", "36281", "36283", "36286", "36293", "36294", "36299", "36301", "36302", "36303", "36304", "36306", "36310", "36312", "36313", "36315", "36316", "36317", "36318", "36320", "36323", "36324", "36325", "36326", "36332", "36333", "36334", "36339", "36340", "36341", "36342", "36344", "36345", "36346", "36347", "36350", "36351", "36352", "36353", "36356", "36357", "36358", "36362", "36363", "36364", "36366", "36367", "36374", "36375", "36376", "36378", "36379", "36380", "36381", "36390", "36391", "36392", "36395", "36396", "36397", "36398", "36399", "36400", "36401", "36402", "36405", "36406", "36408", "36409", "36410", "36412", "36416", "36417", "36419", "36420", "36421", "36424", "36426", "36427", "36430", "36432", "36434", "36436", "36439", "36441", "36445", "36450", "36451", "36452", "36455", "36462", "36464", "36465", "36467", "36468", "36469", "36470", "36471", "36472", "36473", "36474", "36475", "36478", "36481", "36482", "36486", "36488", "36489", "36491", "36492", "36493", "36494", "36495", "36496", "36498", "36503", "36504", "36505", "36507", "36510", "36516", "36519", "36521", "36523", "36524", "36527", "36529", "36531", "36532", "36533", "36534", "36535", "36537", "36540", "36541", "36546", "36547", "36548", "36550", "36552", "36555", "36560", "36561", "36562", "36563", "36564", "36565", "36566", "36567", "36568", "36573", "36578", "36582", "36583", "36584", "36585", "36586", "36587", "36588", "36590", "36595", "36596", "36597", "36598", "36601", "36602", "36603", "36606", "36607", "36608", "36610", "36611", "36613", "36615", "36616", "36617", "36621", "36622", "36623", "36624", "36625", "36627", "36628", "36629", "36631", "36632", "36638", "36642", "36644", "36645", "36647", "36648", "36649", "36650", "36651", "36656", "36657", "36658", "36659", "36660", "36669", "36670", "36672", "36675", "36676", "36677", "36678", "36680", "36684", "36685", "36687", "36688", "36689", "36690", "36691", "36695", "36700", "36702", "36703", "36706", "36707", "36708", "36710", "36712", "36714", "36715", "36718", "36719", "36720", "36721", "36723", "36724", "36726", "36733", "36737", "36739", "36741", "36743", "36745", "36747", "36748", "36752", "36757", "36760", "36761", "36763", "36764", "36767", "36768", "36775", "36776", "36778", "36779", "36781", "36786", "36789", "36794", "36795", "36799", "36800", "36802", "36804", "36809", "36810", "36812", "36814", "36821", "36823", "36826", "36828", "36831", "36832", "36833", "36840", "36841", "36843", "36844", "36846", "36847", "36848", "36849", "36851", "36854", "36855", "36856", "36857", "36858", "36859", "36860", "36861", "36864", "36865", "36866", "36867", "36871", "36872", "36873", "36874", "36875", "36876", "36878", "36881", "36882", "36883", "36884", "36885", "36889", "36890", "36893", "36894", "36898", "36899", "36900", "36903", "36906", "36907", "36908", "36909", "36910", "36916", "36923", "36931", "36932", "36934", "36935", "36936", "36941", "36946", "36947", "36948", "36950", "36951", "36952", "36955", "36956", "36958", "36959", "36962", "36964", "36965", "36966", "36967", "36968", "36971", "36973", "36974", "36975", "36976", "36978", "36979", "36981", "36982", "36985", "36986", "36987", "36988", "36991", "36994", "36997", "37000", "37005", "37007", "37010", "37016", "37019", "37020", "37021", "37023", "37028", "37032", "37033", "37035", "37039", "37040", "37042", "37048", "37051", "37052", "37055", "37056", "37057", "37058", "37060", "37064", "37066", "37067", "37073", "37075", "37076", "37079", "37080", "37082", "37083", "37085", "37087", "37088", "37089", "37091", "37092", "37093", "37094", "37095", "37096", "37097", "37102", "37103", "37104", "37105", "37107", "37109", "37110", "37111", "37113", "37115", "37116", "37118", "37120", "37122", "37123", "37124", "37127", "37128", "37129", "37130", "37132", "37134", "37136", "37138", "37139", "37141", "37142", "37147", "37148", "37153", "37155", "37156", "37162", "37163", "37165", "37166", "37167", "37168", "37173", "37174", "37176", "37179", "37180", "37181", "37182", "37183", "37186", "37187", "37189", "37195", "37199", "37201", "37203", "37204", "37206", "37209", "37214", "37217", "37220", "37224", "37225", "37230", "37231", "37232", "37234", "37235", "37236", "37241", "37242", "37243", "37244", "37246", "37248", "37249", "37251", "37253", "37254", "37255", "37257", "37258", "37259", "37260", "37266", "37267", "37271", "37277", "37278", "37279", "37280", "37282", "37283", "37286", "37287", "37289", "37292", "37293", "37297", "37298", "37299", "37301", "37305", "37306", "37307", "37308", "37310", "37312", "37313", "37314", "37317", "37320", "37321", "37325", "37327", "37328", "37329", "37332", "37335", "37337", "37338", "37340", "37341", "37347", "37350", "37351", "37352", "37353", "37354", "37356", "37358", "37359", "37361", "37364", "37366", "37367", "37375", "37376", "37377", "37378", "37379", "37380", "37383", "37385", "37386", "37388", "37389", "37390", "37391", "37396", "37398", "37400", "37401", "37402", "37403", "37404", "37405", "37408", "37409", "37411", "37412", "37413", "37414", "37416", "37417", "37419", "37420", "37423", "37425", "37428", "37431", "37433", "37437", "37438", "37439", "37441", "37443", "37445", "37448", "37451", "37452", "37454", "37455", "37462", "37463", "37464", "37465", "37466", "37467", "37469", "37470", "37471", "37473", "37474", "37476", "37477", "37479", "37481", "37483", "37484", "37486", "37490", "37493", "37494", "37497", "37499", "37500", "37501", "37502", "37503", "37504", "37506", "37510", "37511", "37513", "37518", "37523", "37524", "37527", "37529", "37535", "37536", "37540", "37542", "37543", "37546", "37547", "37548", "37549", "37551", "37556", "37558", "37561", "37565", "37566", "37567", "37568", "37572", "37573", "37579", "37582", "37584", "37585", "37586", "37587", "37593", "37595", "37596", "37597", "37598", "37601", "37603", "37604", "37606", "37610", "37611", "37613", "37614", "37615", "37620", "37621", "37623", "37624", "37625", "37626", "37627", "37628", "37632", "37635", "37636", "37638", "37639", "37641", "37646", "37647", "37648", "37651", "37652", "37654", "37655", "37656", "37658", "37660", "37664", "37665", "37666", "37668", "37671", "37672", "37673", "37674", "37676", "37679", "37680", "37681", "37683", "37696", "37698", "37699", "37703", "37705", "37707", "37709", "37711", "37713", "37714", "37716", "37717", "37720", "37722", "37724", "37727", "37728", "37729", "37730", "37731", "37734", "37735", "37737", "37738", "37739", "37740", "37742", "37743", "37747", "37749", "37750", "37752", "37753", "37755", "37756", "37758", "37759", "37760", "37761", "37764", "37765", "37766", "37768", "37770", "37771", "37776", "37785", "37787", "37788", "37791", "37792", "37795", "37797", "37798", "37801", "37802", "37806", "37808", "37810", "37811", "37813", "37815", "37817", "37818", "37824", "37826", "37827", "37831", "37832", "37834", "37837", "37838", "37840", "37841", "37842", "37845", "37847", "37852", "37856", "37857", "37859", "37861", "37865", "37866", "37868", "37869", "37871", "37873", "37874", "37875", "37879", "37883", "37886", "37887", "37890", "37894", "37895", "37896", "37898", "37899", "37903", "37904", "37905", "37906", "37907", "37909", "37915", "37916", "37917", "37918", "37919", "37920", "37923", "37925", "37927", "37930", "37932", "37935", "37936", "37937", "37940", "37941", "37942", "37947", "37950", "37952", "37953", "37955", "37956", "37957", "37959", "37961", "37963", "37964", "37965", "37967", "37968", "37971", "37973", "37974", "37975", "37976", "37979", "37980", "37982", "37985", "37986", "37987", "37989", "37990", "37992", "37994", "37995", "38000", "38001", "38004", "38005", "38014", "38015", "38017", "38018", "38021", "38023", "38024", "38026", "38027", "38031", "38032", "38034", "38035", "38038", "38039", "38040", "38041", "38042", "38045", "38046", "38049", "38050", "38051", "38052", "38053", "38059", "38060", "38061", "38071", "38072", "38073", "38074", "38075", "38076", "38077", "38080", "38081", "38084", "38088", "38096", "38098", "38099", "38100", "38101", "38102", "38104", "38105", "38106", "38109", "38110", "38113", "38114", "38116", "38117", "38118", "38122", "38124", "38125", "38128", "38129", "38130", "38133", "38135", "38137", "38138", "38141", "38143", "38145", "38150", "38151", "38152", "38156", "38157", "38159", "38162", "38164", "38167", "38168", "38170", "38171", "38172", "38174", "38175", "38177", "38178", "38179", "38180", "38181", "38182", "38183", "38184", "38185", "38186", "38188", "38189", "38195", "38198", "38200", "38201", "38202", "38204", "38208", "38209", "38211", "38213", "38215", "38217", "38219", "38221", "38223", "38224", "38228", "38229", "38232", "38234", "38235", "38238", "38242", "38247", "38248", "38249", "38251", "38256", "38258", "38259", "38262", "38264", "38266", "38271", "38272", "38273", "38275", "38279", "38284", "38286", "38290", "38291", "38293", "38294", "38296", "38297", "38298", "38299", "38302", "38303", "38305", "38306", "38307", "38311", "38313", "38319", "38321", "38322", "38324", "38325", "38332", "38333", "38339", "38340", "38341", "38342", "38346", "38347", "38348", "38350", "38352", "38353", "38355", "38356", "38357", "38358", "38359", "38360", "38362", "38364", "38366", "38368", "38371", "38372", "38373", "38377", "38378", "38379", "38383", "38384", "38385", "38390", "38391", "38392", "38395", "38396", "38399", "38402", "38403", "38404", "38406", "38407", "38414", "38415", "38416", "38417", "38418", "38420", "38421", "38424", "38426", "38430", "38433", "38436", "38439", "38440", "38442", "38445", "38448", "38451", "38454", "38459", "38460", "38461", "38462", "38465", "38467", "38471", "38473", "38474", "38476", "38477", "38480", "38481", "38484", "38486", "38489", "38491", "38495", "38499", "38502", "38503", "38504", "38507", "38508", "38512", "38513", "38514", "38515", "38516", "38518", "38519", "38520", "38522", "38525", "38528", "38532", "38533", "38534", "38535", "38536", "38537", "38538", "38543", "38547", "38550", "38551", "38553", "38554", "38555", "38556", "38557", "38558", "38559", "38563", "38565", "38567", "38568", "38569", "38571", "38572", "38573", "38577", "38579", "38586", "38588", "38593", "38594", "38595", "38598", "38599", "38604", "38605", "38606", "38607", "38609", "38611", "38612", "38613", "38615", "38617", "38619", "38620", "38623", "38624", "38626", "38627", "38630", "38633", "38634", "38636", "38637", "38641", "38642", "38643", "38644", "38646", "38651", "38656", "38658", "38660", "38661", "38662", "38663", "38664", "38665", "38666", "38667", "38675", "38676", "38678", "38679", "38681", "38685", "38686", "38689", "38692", "38696", "38697", "38700", "38703", "38704", "38705", "38711", "38713", "38716", "38717", "38720", "38724", "38727", "38728", "38731", "38732", "38734", "38738", "38739", "38741", "38742", "38743", "38744", "38745", "38749", "38751", "38752", "38756", "38758", "38761", "38762", "38764", "38765", "38766", "38768", "38770", "38778", "38779", "38781", "38787", "38790", "38792", "38797", "38798", "38799", "38800", "38801", "38802", "38808", "38810", "38811", "38812", "38815", "38817", "38820", "38821", "38822", "38824", "38826", "38827", "38829", "38831", "38833", "38836", "38837", "38838", "38841", "38843", "38845", "38846", "38849", "38852", "38853", "38854", "38856", "38858", "38860", "38861", "38862", "38865", "38870", "38871", "38872", "38875", "38876", "38878", "38879", "38880", "38883", "38885", "38887", "38888", "38889", "38891", "38894", "38895", "38897", "38898", "38901", "38903", "38904", "38905", "38906", "38907", "38909", "38910", "38912", "38917", "38921", "38926", "38929", "38930", "38932", "38935", "38937", "38941", "38942", "38945", "38946", "38947", "38955", "38958", "38960", "38967", "38968", "38969", "38970", "38972", "38975", "38976", "38977", "38978", "38979", "38980", "38981", "38983", "38984", "38986", "38988", "38989", "38990", "38991", "38993", "38994", "38995", "38996", "38997", "39002", "39004", "39005", "39006", "39007", "39009", "39011", "39012", "39013", "39019", "39020", "39022", "39023", "39028", "39033", "39035", "39040", "39041", "39044", "39047", "39048", "39051", "39053", "39054", "39055", "39057", "39058", "39059", "39063", "39064", "39067", "39068", "39070", "39071", "39075", "39076", "39078", "39080", "39084", "39085", "39086", "39087", "39089", "39090", "39092", "39094", "39096", "39098", "39099", "39100", "39101", "39102", "39104", "39105", "39106", "39108", "39109", "39111", "39112", "39118", "39120", "39121", "39122", "39123", "39124", "39125", "39126", "39127", "39128", "39132", "39134", "39136", "39140", "39141", "39142", "39144", "39148", "39150", "39151", "39152", "39153", "39156", "39158", "39159", "39161", "39162", "39163", "39164", "39166", "39167", "39170", "39171", "39172", "39173", "39178", "39180", "39181", "39182", "39184", "39188", "39192", "39195", "39197", "39199", "39202", "39203", "39205", "39208", "39211", "39213", "39216", "39219", "39220", "39221", "39228", "39230", "39231", "39233", "39235", "39236", "39237", "39241", "39243", "39244", "39248", "39249", "39252", "39254", "39255", "39256", "39257", "39258", "39259", "39263", "39265", "39266", "39267", "39268", "39271", "39272", "39274", "39275", "39276", "39277", "39278", "39279", "39280", "39281", "39283", "39284", "39286", "39290", "39291", "39292", "39295", "39296", "39299", "39300", "39303", "39305", "39309", "39311", "39315", "39316", "39318", "39319", "39322", "39324", "39325", "39326", "39327", "39328", "39330", "39332", "39334", "39336", "39337", "39338", "39340", "39343", "39345", "39346", "39348", "39349", "39351", "39354", "39355", "39356", "39358", "39359", "39361", "39362", "39363", "39365", "39366", "39367", "39368", "39372", "39373", "39376", "39377", "39378", "39379", "39381", "39382", "39383", "39385", "39389", "39394", "39395", "39397", "39402", "39403", "39406", "39408", "39410", "39411", "39412", "39413", "39414", "39415", "39416", "39417", "39418", "39419", "39420", "39421", "39422", "39423", "39424", "39425", "39427", "39428", "39429", "39430", "39431", "39434", "39439", "39441", "39442", "39443", "39444", "39446", "39447", "39449", "39450", "39454", "39456", "39457", "39461", "39462", "39463", "39464", "39465", "39467", "39471", "39473", "39474", "39476", "39478", "39479", "39481", "39482", "39483", "39486", "39488", "39489", "39493", "39497", "39501", "39502", "39503", "39504", "39508", "39514", "39515", "39516", "39517", "39520", "39521", "39528", "39529", "39531", "39532", "39534", "39536", "39538", "39540", "39542", "39544", "39547", "39549", "39550", "39551", "39559", "39561", "39562", "39565", "39566", "39568", "39569", "39572", "39573", "39574", "39575", "39577", "39578", "39580", "39581", "39583", "39584", "39585", "39588", "39592", "39593", "39594", "39596", "39598", "39600", "39602", "39603", "39604", "39606", "39607", "39611", "39616", "39617", "39619", "39625", "39628", "39631", "39634", "39637", "39638", "39641", "39643", "39644", "39645", "39647", "39648", "39649", "39660", "39665", "39666", "39667", "39670", "39672", "39679", "39680", "39681", "39682", "39683", "39687", "39691", "39692", "39693", "39695", "39696", "39697", "39698", "39700", "39701", "39706", "39709", "39710", "39711", "39715", "39716", "39717", "39718", "39721", "39724", "39730", "39731", "39733", "39742", "39743", "39745", "39748", "39749", "39750", "39751", "39752", "39756", "39757", "39759", "39764", "39767", "39770", "39772", "39779", "39780", "39781", "39782", "39783", "39789", "39790", "39791", "39793", "39795", "39796", "39798", "39799", "39800", "39803", "39804", "39807", "39813", "39814", "39815", "39817", "39823", "39824", "39826", "39827", "39832", "39835", "39837", "39838", "39839", "39840", "39844", "39845", "39846", "39847", "39848", "39849", "39850", "39851", "39852", "39853", "39854", "39855", "39856", "39857", "39859", "39862", "39864", "39865", "39866", "39870", "39874", "39877", "39878", "39881", "39882", "39884", "39886", "39888", "39890", "39891", "39892", "39894", "39895", "39899", "39901", "39902", "39904", "39907", "39909", "39911", "39912", "39915", "39917", "39919", "39921", "39922", "39924", "39925", "39927", "39929", "39931", "39932", "39933", "39936", "39937", "39938", "39939", "39940", "39943", "39944", "39945", "39946", "39949", "39950", "39951", "39956", "39959", "39960", "39962", "39963", "39964", "39965", "39966", "39968", "39970", "39974", "39975", "39976", "39978", "39979", "39980", "39981", "39982", "39984", "39990", "39994", "39996", "39997", "40000", "40002", "40003", "40004", "40012", "40017", "40018", "40019", "40020", "40022", "40023", "40025", "40026", "40028", "40029", "40036", "40038", "40039", "40041", "40042", "40043", "40044", "40047", "40049", "40055", "40056", "40057", "40059", "40062", "40063", "40069", "40070", "40074", "40076", "40077", "40078", "40079", "40080", "40082", "40084", "40085", "40087", "40088", "40089", "40091", "40092", "40094", "40097", "40100", "40101", "40102", "40104", "40105", "40108", "40109", "40111", "40114", "40117", "40120", "40121", "40125", "40127", "40128", "40130", "40131", "40132", "40133", "40134", "40140", "40141", "40142", "40144", "40145", "40148", "40149", "40155", "40156", "40160", "40161", "40163", "40171", "40172", "40173", "40174", "40178", "40182", "40186", "40188", "40194", "40195", "40196", "40197", "40198", "40200", "40202", "40203", "40205", "40206", "40208", "40209", "40210", "40212", "40213", "40214", "40216", "40217", "40218", "40219", "40221", "40222", "40225", "40229", "40233", "40236", "40238", "40240", "40241", "40246", "40249", "40250", "40251", "40257", "40260", "40261", "40264", "40266", "40267", "40270", "40271", "40272", "40274", "40279", "40280", "40282", "40285", "40286", "40289", "40293", "40295", "40297", "40300", "40301", "40302", "40303", "40305", "40308", "40311", "40314", "40315", "40316", "40317", "40322", "40323", "40325", "40326", "40327", "40328", "40329", "40330", "40332", "40333", "40334", "40335", "40336", "40337", "40338", "40340", "40343", "40345", "40346", "40347", "40349", "40353", "40354", "40355", "40358", "40360", "40361", "40365", "40367", "40369", "40370", "40377", "40380", "40382", "40385", "40386", "40387", "40388", "40389", "40391", "40393", "40395", "40398", "40403", "40405", "40406", "40410", "40411", "40413", "40415", "40416", "40417", "40420", "40425", "40427", "40428", "40429", "40430", "40432", "40436", "40437", "40439", "40441", "40443", "40445", "40446", "40447", "40448", "40456", "40457", "40461", "40462", "40463", "40464", "40465", "40468", "40469", "40470", "40471", "40472", "40473", "40476", "40477", "40479", "40481", "40482", "40483", "40484", "40487", "40488", "40491", "40492", "40498", "40501", "40502", "40504", "40505", "40514", "40517", "40520", "40522", "40525", "40526", "40534", "40535", "40539", "40540", "40541", "40543", "40544", "40545", "40547", "40548", "40551", "40552", "40554", "40557", "40559", "40561", "40562", "40563", "40564", "40565", "40569", "40570", "40571", "40572", "40573", "40574", "40575", "40577", "40579", "40580", "40584", "40585", "40588", "40589", "40593", "40594", "40601", "40603", "40604", "40606", "40607", "40608", "40614", "40618", "40620", "40621", "40625", "40626", "40627", "40628", "40629", "40631", "40632", "40633", "40634", "40635", "40636", "40638", "40639", "40640", "40641", "40645", "40647", "40649", "40650", "40653", "40654", "40657", "40658", "40666", "40667", "40668", "40669", "40670", "40674", "40677", "40679", "40683", "40686", "40690", "40691", "40692", "40696", "40697", "40699", "40700", "40701", "40702", "40703", "40706", "40707", "40708", "40710", "40712", "40714", "40715", "40716", "40717", "40719", "40720", "40726", "40728", "40729", "40730", "40737", "40740", "40743", "40744", "40747", "40749", "40750", "40754", "40755", "40756", "40757", "40758", "40759", "40761", "40762", "40765", "40767", "40770", "40771", "40772", "40773", "40778", "40781", "40783", "40785", "40789", "40791", "40794", "40795", "40796", "40799", "40805", "40808", "40809", "40811", "40812", "40815", "40817", "40819", "40822", "40823", "40825", "40828", "40830", "40831", "40832", "40833", "40834", "40835", "40837", "40838", "40840", "40842", "40843", "40844", "40846", "40847", "40848", "40849", "40855", "40856", "40857", "40860", "40865", "40868", "40871", "40874", "40875", "40885", "40887", "40890", "40891", "40892", "40893", "40894", "40898", "40899", "40900", "40902", "40904", "40905", "40907", "40909", "40911", "40912", "40915", "40916", "40917", "40918", "40919", "40920", "40921", "40922", "40923", "40927", "40929", "40930", "40931", "40934", "40936", "40940", "40942", "40943", "40944", "40946", "40947", "40948", "40954", "40955", "40956", "40960", "40961", "40962", "40965", "40967", "40968", "40975", "40976", "40977", "40978", "40980", "40981", "40982", "40983", "40985", "40991", "40992", "40994", "41000", "41001", "41002", "41004", "41008", "41009", "41010", "41011", "41013", "41014", "41019", "41021", "41023", "41024", "41025", "41026", "41027", "41028", "41030", "41031", "41038", "41039", "41041", "41042", "41043", "41045", "41048", "41049", "41051", "41052", "41053", "41054", "41059", "41062", "41064", "41065", "41066", "41068", "41070", "41071", "41073", "41075", "41076", "41078", "41080", "41081", "41082", "41084", "41086", "41089", "41090", "41092", "41096", "41097", "41098", "41099", "41101", "41102", "41103", "41106", "41110", "41112", "41113", "41115", "41120", "41121", "41123", "41127", "41128", "41132", "41136", "41138", "41139", "41144", "41146", "41150", "41154", "41155", "41157", "41158", "41160", "41161", "41163", "41168", "41169", "41172", "41174", "41175", "41176", "41182", "41183", "41185", "41186", "41187", "41188", "41189", "41192", "41196", "41197", "41199", "41200", "41202", "41204", "41205", "41207", "41208", "41209", "41210", "41212", "41213", "41214", "41216", "41219", "41221", "41222", "41223", "41227", "41228", "41229", "41235", "41237", "41238", "41242", "41243", "41244", "41245", "41246", "41247", "41248", "41249", "41251", "41252", "41254", "41257", "41261", "41262", "41264", "41265", "41268", "41269", "41273", "41276", "41277", "41278", "41282", "41286", "41287", "41290", "41291", "41292", "41296", "41297", "41298", "41299", "41301", "41302", "41303", "41304", "41309", "41310", "41312", "41321", "41322", "41323", "41326", "41327", "41328", "41330", "41331", "41332", "41333", "41336", "41337", "41339", "41341", "41344", "41346", "41348", "41351", "41354", "41360", "41361", "41366", "41373", "41374", "41378", "41379", "41380", "41382", "41385", "41387", "41390", "41391", "41392", "41399", "41403", "41404", "41406", "41407", "41408", "41411", "41413", "41414", "41415", "41416", "41417", "41420", "41422", "41424", "41427", "41429", "41430", "41431", "41432", "41433", "41435", "41436", "41438", "41439", "41441", "41443", "41446", "41448", "41450", "41453", "41455", "41457", "41458", "41460", "41462", "41463", "41465", "41466", "41467", "41468", "41469", "41471", "41472", "41473", "41477", "41479", "41482", "41485", "41486", "41488", "41489", "41503", "41504", "41507", "41508", "41512", "41514", "41516", "41517", "41520", "41522", "41523", "41525", "41527", "41529", "41530", "41531", "41533", "41536", "41538", "41540", "41542", "41543", "41546", "41550", "41552", "41559", "41560", "41561", "41563", "41564", "41569", "41572", "41576", "41579", "41582", "41584", "41585", "41589", "41593", "41595", "41596", "41597", "41599", "41601", "41603", "41607", "41608", "41609", "41612", "41614", "41615", "41616", "41617", "41619", "41621", "41623", "41625", "41626", "41627", "41628", "41629", "41631", "41633", "41634", "41636", "41637", "41639", "41641", "41644", "41645", "41646", "41647", "41649", "41652", "41653", "41654", "41655", "41659", "41661", "41662", "41664", "41668", "41669", "41670", "41671", "41673", "41675", "41677", "41679", "41680", "41682", "41685", "41688", "41690", "41692", "41693", "41694", "41697", "41698", "41700", "41702", "41704", "41705", "41707", "41708", "41709", "41710", "41715", "41717", "41718", "41719", "41720", "41721", "41722", "41724", "41725", "41730", "41731", "41732", "41735", "41737", "41738", "41740", "41742", "41747", "41749", "41750", "41751", "41752", "41753", "41754", "41758", "41759", "41760", "41762", "41764", "41766", "41768", "41769", "41771", "41772", "41775", "41776", "41781", "41782", "41783", "41784", "41789", "41790", "41793", "41795", "41796", "41798", "41799", "41801", "41802", "41805", "41806", "41808", "41809", "41811", "41821", "41823", "41824", "41825", "41827", "41829", "41831", "41832", "41836", "41837", "41840", "41841", "41842", "41843", "41845", "41848", "41850", "41851", "41852", "41853", "41858", "41860", "41864", "41866", "41867", "41872", "41873", "41875", "41876", "41877", "41879", "41885", "41889", "41891", "41893", "41894", "41895", "41898", "41900", "41901", "41902", "41903", "41904", "41905", "41906", "41908", "41910", "41911", "41912", "41915", "41917", "41923", "41924", "41925", "41926", "41929", "41930", "41933", "41935", "41939", "41941", "41942", "41945", "41946", "41950", "41951", "41952", "41953", "41958", "41959", "41960", "41965", "41966", "41971", "41974", "41976", "41988", "41990", "41991", "41992", "41997", "42000", "42001", "42002", "42007", "42008", "42009", "42012", "42014", "42015", "42018", "42022", "42023", "42024", "42026", "42029", "42030", "42033", "42035", "42036", "42037", "42039", "42040", "42042", "42046", "42047", "42048", "42049", "42052", "42058", "42060", "42062", "42065", "42066", "42071", "42073", "42076", "42079", "42080", "42082", "42084", "42087", "42088", "42090", "42091", "42094", "42095", "42097", "42100", "42102", "42103", "42104", "42106", "42108", "42110", "42112", "42113", "42119", "42120", "42121", "42122", "42123", "42125", "42130", "42133", "42134", "42135", "42136", "42138", "42142", "42143", "42146", "42147", "42148", "42149", "42150", "42151", "42156", "42157", "42158", "42160", "42162", "42165", "42168", "42170", "42174", "42176", "42177", "42179", "42182", "42183", "42184", "42185", "42186", "42187", "42188", "42189", "42190", "42192", "42194", "42195", "42199", "42200", "42201", "42203", "42205", "42206", "42208", "42212", "42214", "42215", "42216", "42217", "42218", "42221", "42222", "42223", "42224", "42228", "42230", "42231", "42233", "42234", "42236", "42238", "42239", "42240", "42241", "42242", "42244", "42245", "42247", "42249", "42250", "42251", "42252", "42253", "42255", "42257", "42261", "42264", "42269", "42271", "42272", "42273", "42277", "42279", "42281", "42282", "42287", "42288", "42289", "42290", "42291", "42294", "42295", "42298", "42299", "42300", "42302", "42303", "42304", "42305", "42306", "42307", "42308", "42309", "42311", "42312", "42317", "42319", "42320", "42321", "42327", "42329", "42332", "42333", "42336", "42338", "42350", "42351", "42353", "42356", "42359", "42363", "42365", "42369", "42370", "42371", "42374", "42379", "42385", "42386", "42387", "42388", "42389", "42390", "42392", "42393", "42395", "42396", "42397", "42400", "42402", "42404", "42405", "42406", "42408", "42412", "42419", "42423", "42425", "42426", "42427", "42429", "42431", "42433", "42439", "42440", "42442", "42443", "42445", "42448", "42449", "42450", "42451", "42452", "42455", "42457", "42458", "42462", "42463", "42464", "42467", "42468", "42469", "42471", "42473", "42474", "42477", "42478", "42479", "42480", "42482", "42485", "42488", "42492", "42493", "42494", "42496", "42498", "42502", "42503", "42506", "42507", "42508", "42511", "42512", "42513", "42514", "42515", "42518", "42521", "42529", "42530", "42531", "42532", "42537", "42539", "42540", "42541", "42543", "42544", "42546", "42549", "42552", "42553", "42556", "42559", "42562", "42563", "42566", "42568", "42570", "42574", "42575", "42578", "42579", "42581", "42583", "42585", "42586", "42588", "42589", "42591", "42592", "42595", "42597", "42600", "42601", "42603", "42604", "42605", "42607", "42608", "42610", "42611", "42613", "42614", "42616", "42617", "42619", "42620", "42627", "42628", "42629", "42630", "42631", "42632", "42633", "42634", "42636", "42638", "42639", "42640", "42642", "42644", "42646", "42647", "42649", "42650", "42652", "42653", "42654", "42657", "42658", "42661", "42662", "42663", "42664", "42665", "42668", "42677", "42679", "42683", "42684", "42685", "42688", "42689", "42691", "42694", "42695", "42696", "42701", "42702", "42703", "42704", "42708", "42709", "42710", "42715", "42720", "42722", "42725", "42726", "42730", "42732", "42735", "42736", "42737", "42739", "42740", "42742", "42743", "42744", "42746", "42747", "42748", "42751", "42753", "42754", "42755", "42756", "42758", "42761", "42762", "42763", "42766", "42767", "42768", "42770", "42775", "42777", "42778", "42779", "42780", "42785", "42787", "42790", "42795", "42796", "42799", "42800", "42801", "42803", "42804", "42805", "42809", "42812", "42813", "42815", "42816", "42818", "42819", "42820", "42823", "42827", "42837", "42838", "42839", "42843", "42846", "42847", "42848", "42860", "42861", "42864", "42866", "42869", "42871", "42873", "42874", "42879", "42881", "42883", "42886", "42888", "42891", "42893", "42895", "42896", "42898", "42899", "42901", "42902", "42906", "42910", "42911", "42912", "42915", "42917", "42918", "42921", "42923", "42924", "42927", "42928", "42930", "42931", "42932", "42939", "42940", "42941", "42942", "42943", "42944", "42945", "42946", "42949", "42950", "42952", "42953", "42954", "42955", "42958", "42959", "42960", "42964", "42966", "42969", "42970", "42971", "42972", "42976", "42978", "42979", "42981", "42986", "42991", "42992", "42993", "42994", "42997", "42998", "43000", "43004", "43005", "43007", "43008", "43009", "43010", "43011", "43012", "43014", "43015", "43016", "43017", "43018", "43020", "43021", "43024", "43025", "43026", "43028", "43030", "43031", "43033", "43034", "43035", "43036", "43037", "43040", "43043", "43044", "43045", "43046", "43049", "43050", "43052", "43053", "43056", "43057", "43058", "43059", "43063", "43066", "43073", "43074", "43075", "43076", "43078", "43082", "43083", "43084", "43090", "43091", "43092", "43093", "43095", "43096", "43097", "43098", "43099", "43103", "43104", "43105", "43106", "43109", "43110", "43111", "43112", "43115", "43116", "43119", "43120", "43123", "43126", "43128", "43131", "43136", "43137", "43139", "43140", "43143", "43144", "43145", "43148", "43149", "43151", "43153", "43154", "43155", "43158", "43159", "43161", "43162", "43163", "43164", "43165", "43166", "43168", "43169", "43171", "43173", "43174", "43176", "43177", "43186", "43188", "43189", "43191", "43193", "43195", "43197", "43201", "43203", "43204", "43206", "43210", "43212", "43213", "43215", "43217", "43218", "43220", "43221", "43222", "43224", "43225", "43231", "43232", "43236", "43242", "43243", "43248", "43251", "43253", "43255", "43258", "43259", "43264", "43273", "43277", "43278", "43280", "43282", "43283", "43285", "43288", "43290", "43292", "43293", "43294", "43298", "43300", "43301", "43302", "43304", "43305", "43307", "43310", "43311", "43313", "43316", "43317", "43319", "43320", "43322", "43323", "43326", "43327", "43328", "43329", "43333", "43336", "43337", "43342", "43343", "43352", "43353", "43354", "43359", "43361", "43362", "43363", "43364", "43369", "43372", "43375", "43376", "43377", "43380", "43381", "43383", "43384", "43385", "43387", "43388", "43391", "43393", "43394", "43395", "43396", "43398", "43399", "43400", "43403", "43404", "43405", "43406", "43407", "43413", "43414", "43416", "43417", "43418", "43421", "43424", "43425", "43428", "43429", "43434", "43435", "43436", "43438", "43440", "43444", "43445", "43449", "43451", "43452", "43455", "43457", "43463", "43464", "43466", "43468", "43470", "43472", "43475", "43477", "43478", "43479", "43480", "43482", "43487", "43488", "43489", "43491", "43492", "43493", "43494", "43496", "43497", "43499", "43503", "43504", "43505", "43506", "43507", "43511", "43512", "43513", "43514", "43515", "43516", "43517", "43518", "43519", "43522", "43523", "43529", "43530", "43531", "43535", "43536", "43537", "43538", "43539", "43541", "43545", "43546", "43547", "43550", "43551", "43552", "43553", "43554", "43557", "43560", "43561", "43562", "43564", "43565", "43568", "43569", "43572", "43573", "43574", "43577", "43578", "43579", "43582", "43585", "43591", "43593", "43597", "43602", "43603", "43604", "43608", "43609", "43611", "43613", "43615", "43618", "43619", "43620", "43621", "43624", "43628", "43629", "43633", "43634", "43635", "43637", "43639", "43640", "43641", "43646", "43648", "43649", "43652", "43654", "43655", "43656", "43657", "43660", "43661", "43662", "43664", "43668", "43671", "43672", "43673", "43674", "43675", "43676", "43681", "43682", "43684", "43686", "43687", "43688", "43690", "43695", "43696", "43700", "43701", "43702", "43704", "43705", "43706", "43707", "43709", "43710", "43712", "43713", "43714", "43715", "43717", "43719", "43721", "43727", "43728", "43729", "43732", "43733", "43735", "43736", "43737", "43738", "43740", "43743", "43745", "43746", "43750", "43753", "43754", "43755", "43756", "43757", "43758", "43759", "43761", "43762", "43765", "43766", "43767", "43769", "43771", "43772", "43773", "43774", "43775", "43777", "43778", "43779", "43781", "43784", "43785", "43786", "43790", "43792", "43794", "43797", "43800", "43801", "43802", "43803", "43806", "43807", "43810", "43811", "43812", "43813", "43814", "43824", "43827", "43829", "43831", "43832", "43835", "43836", "43837", "43839", "43840", "43841", "43845", "43846", "43849", "43852", "43853", "43854", "43855", "43856", "43858", "43859", "43862", "43864", "43865", "43871", "43876", "43885", "43889", "43890", "43891", "43893", "43894", "43895", "43896", "43897", "43900", "43901", "43902", "43904", "43905", "43906", "43909", "43910", "43911", "43913", "43915", "43919", "43920", "43924", "43926", "43927", "43928", "43929", "43930", "43933", "43935", "43937", "43938", "43940", "43941", "43942", "43943", "43945", "43947", "43949", "43950", "43953", "43954", "43955", "43958", "43961", "43962", "43964", "43965", "43967", "43973", "43974", "43977", "43980", "43981", "43987", "43988", "43991", "43992", "43995", "43996", "43999", "44000", "44002", "44004", "44006", "44011", "44014", "44015", "44017", "44020", "44021", "44022", "44024", "44028", "44033", "44037", "44039", "44043", "44045", "44047", "44049", "44052", "44056", "44058", "44061", "44063", "44064", "44065", "44066", "44067", "44070", "44072", "44077", "44078", "44079", "44082", "44083", "44087", "44088", "44089", "44093", "44095", "44096", "44103", "44105", "44109", "44111", "44113", "44114", "44117", "44122", "44130", "44132", "44134", "44135", "44139", "44140", "44141", "44143", "44151", "44152", "44154", "44155", "44158", "44159", "44160", "44163", "44167", "44168", "44169", "44170", "44172", "44173", "44175", "44176", "44177", "44179", "44186", "44190", "44191", "44194", "44195", "44198", "44199", "44202", "44205", "44206", "44208", "44209", "44211", "44213", "44216", "44217", "44218", "44219", "44220", "44222", "44223", "44224", "44226", "44227", "44229", "44230", "44231", "44234", "44243", "44244", "44245", "44252", "44254", "44255", "44257", "44258", "44259", "44260", "44262", "44264", "44265", "44266", "44267", "44271", "44272", "44276", "44277", "44279", "44280", "44281", "44283", "44285", "44287", "44289", "44290", "44291", "44294", "44299", "44300", "44301", "44302", "44303", "44307", "44310", "44312", "44315", "44316", "44317", "44320", "44322", "44324", "44325", "44327", "44331", "44332", "44333", "44336", "44338", "44339", "44343", "44344", "44349", "44350", "44352", "44354", "44355", "44357", "44363", "44366", "44368", "44370", "44375", "44378", "44381", "44382", "44383", "44384", "44386", "44387", "44388", "44391", "44392", "44393", "44394", "44397", "44399", "44400", "44402", "44405", "44406", "44414", "44417", "44419", "44422", "44423", "44426", "44427", "44431", "44434", "44437", "44438", "44439", "44442", "44445", "44450", "44452", "44453", "44454", "44456", "44461", "44465", "44466", "44468", "44470", "44471", "44473", "44476", "44477", "44479", "44480", "44483", "44487", "44488", "44489", "44492", "44493", "44494", "44495", "44500", "44501", "44506", "44508", "44509", "44510", "44511", "44512", "44513", "44514", "44516", "44518", "44519", "44520", "44521", "44524", "44526", "44527", "44528", "44529", "44530", "44532", "44533", "44535", "44536", "44537", "44538", "44540", "44542", "44543", "44545", "44546", "44549", "44551", "44552", "44553", "44554", "44555", "44557", "44558", "44559", "44562", "44563", "44567", "44568", "44569", "44570", "44573", "44574", "44575", "44577", "44578", "44580", "44581", "44583", "44586", "44590", "44592", "44593", "44596", "44597", "44599", "44600", "44601", "44603", "44605", "44606", "44607", "44610", "44611", "44612", "44613", "44614", "44615", "44617", "44618", "44621", "44622", "44625", "44626", "44629", "44630", "44631", "44632", "44635", "44638", "44640", "44642", "44643", "44644", "44646", "44647", "44648", "44649", "44650", "44652", "44653", "44655", "44656", "44658", "44659", "44663", "44664", "44665", "44666", "44668", "44671", "44673", "44676", "44681", "44682", "44683", "44684", "44686", "44687", "44688", "44691", "44695", "44698", "44701", "44705", "44709", "44714", "44717", "44718", "44722", "44723", "44725", "44728", "44729", "44730", "44732", "44734", "44735", "44737", "44741", "44745", "44747", "44752", "44753", "44754", "44755", "44756", "44757", "44758", "44761", "44765", "44766", "44767", "44769", "44772", "44773", "44774", "44777", "44780", "44783", "44789", "44792", "44793", "44794", "44795", "44797", "44798", "44800", "44801", "44807", "44809", "44811", "44812", "44814", "44815", "44819", "44820", "44821", "44822", "44824", "44825", "44826", "44827", "44828", "44829", "44830", "44833", "44836", "44837", "44838", "44842", "44843", "44845", "44846", "44847", "44848", "44856", "44858", "44859", "44861", "44862", "44865", "44866", "44869", "44870", "44871", "44872", "44873", "44875", "44878", "44879", "44880", "44881", "44882", "44883", "44889", "44892", "44895", "44896", "44897", "44898", "44901", "44902", "44903", "44906", "44910", "44911", "44912", "44913", "44914", "44920", "44922", "44927", "44928", "44929", "44931", "44935", "44938", "44939", "44942", "44946", "44947", "44948", "44950", "44951", "44953", "44954", "44955", "44956", "44958", "44960", "44961", "44962", "44964", "44972", "44973", "44974", "44975", "44976", "44977", "44978", "44986", "44988", "44991", "44993", "44994", "44995", "44996", "44998", "44999", "45002", "45004", "45005", "45007", "45008", "45009", "45010", "45011", "45013", "45017", "45018", "45019", "45020", "45021", "45023", "45026", "45027", "45028", "45030", "45034", "45036", "45039", "45040", "45041", "45042", "45045", "45047", "45051", "45055", "45056", "45057", "45058", "45059", "45060", "45066", "45069", "45072", "45075", "45076", "45079", "45080", "45081", "45087", "45088", "45090", "45093", "45095", "45097", "45098", "45100", "45104", "45109", "45110", "45111", "45112", "45113", "45114", "45117", "45119", "45122", "45127", "45129", "45130", "45131", "45132", "45133", "45135", "45138", "45141", "45143", "45144", "45148", "45151", "45152", "45153", "45159", "45161", "45163", "45166", "45167", "45170", "45172", "45174", "45175", "45177", "45183", "45184", "45185", "45188", "45191", "45192", "45193", "45194", "45195", "45196", "45199", "45200", "45203", "45204", "45206", "45207", "45208", "45209", "45210", "45212", "45213", "45214", "45215", "45216", "45218", "45219", "45221", "45222", "45225", "45226", "45228", "45232", "45234", "45238", "45242", "45247", "45250", "45253", "45255", "45256", "45257", "45259", "45261", "45262", "45263", "45264", "45265", "45266", "45270", "45271", "45272", "45273", "45277", "45279", "45280", "45281", "45287", "45289", "45292", "45293", "45294", "45297", "45303", "45306", "45307", "45308", "45310", "45314", "45315", "45316", "45317", "45318", "45319", "45321", "45322", "45323", "45325", "45330", "45331", "45332", "45341", "45343", "45344", "45345", "45346", "45348", "45350", "45351", "45356", "45357", "45359", "45360", "45361", "45364", "45365", "45366", "45367", "45369", "45371", "45376", "45377", "45381", "45384", "45385", "45386", "45389", "45390", "45392", "45394", "45395", "45398", "45400", "45401", "45404", "45405", "45410", "45411", "45416", "45417", "45419", "45420", "45424", "45425", "45426", "45428", "45433", "45435", "45436", "45437", "45441", "45443", "45444", "45447", "45448", "45451", "45453", "45454", "45459", "45462", "45465", "45466", "45468", "45473", "45474", "45475", "45476", "45477", "45480", "45481", "45482", "45484", "45485", "45486", "45488", "45489", "45491", "45495", "45497", "45498", "45500", "45502", "45503", "45504", "45507", "45508", "45510", "45511", "45512", "45513", "45516", "45519", "45525", "45527", "45528", "45531", "45534", "45537", "45538", "45540", "45541", "45543", "45545", "45548", "45549", "45550", "45552", "45553", "45554", "45556", "45557", "45558", "45560", "45561", "45563", "45570", "45571", "45573", "45574", "45576", "45577", "45578", "45582", "45583", "45585", "45590", "45591", "45592", "45597", "45600", "45601", "45603", "45605", "45606", "45608", "45610", "45611", "45618", "45619", "45624", "45627", "45628", "45634", "45635", "45636", "45637", "45641", "45650", "45651", "45658", "45659", "45660", "45667", "45668", "45669", "45670", "45671", "45672", "45673", "45678", "45681", "45682", "45683", "45686", "45688", "45693", "45696", "45698", "45702", "45703", "45706", "45708", "45711", "45713", "45716", "45721", "45725", "45729", "45730", "45733", "45734", "45737", "45738", "45739", "45740", "45742", "45745", "45746", "45747", "45748", "45750", "45751", "45755", "45757", "45758", "45759", "45761", "45762", "45763", "45764", "45765", "45766", "45767", "45769", "45773", "45774", "45775", "45780", "45782", "45785", "45786", "45788", "45789", "45790", "45791", "45793", "45794", "45795", "45796", "45797", "45798", "45799", "45800", "45802", "45803", "45804", "45805", "45810", "45811", "45814", "45815", "45817", "45818", "45821", "45822", "45823", "45826", "45827", "45828", "45829", "45832", "45837", "45839", "45840", "45842", "45843", "45844", "45847", "45850", "45851", "45852", "45853", "45854", "45857", "45858", "45859", "45861", "45862", "45864", "45865", "45870", "45873", "45878", "45881", "45882", "45884", "45888", "45891", "45892", "45895", "45896", "45897", "45899", "45902", "45903", "45904", "45905", "45907", "45908", "45910", "45911", "45912", "45914", "45916", "45917", "45918", "45921", "45923", "45927", "45929", "45930", "45931", "45932", "45933", "45936", "45938", "45939", "45941", "45948", "45950", "45953", "45954", "45955", "45956", "45958", "45960", "45962", "45963", "45966", "45967", "45969", "45971", "45972", "45973", "45974", "45975", "45979", "45984", "45987", "45989", "45990", "45991", "45994", "45995", "45996", "45997", "45998", "45999", "46000", "46001", "46002", "46006", "46007", "46008", "46009", "46010", "46011", "46013", "46015", "46016", "46020", "46024", "46025", "46026", "46027", "46028", "46030", "46031", "46034", "46035", "46038", "46039", "46040", "46042", "46044", "46045", "46046", "46049", "46050", "46053", "46054", "46056", "46060", "46061", "46064", "46065", "46066", "46067", "46070", "46073", "46076", "46077", "46078", "46079", "46082", "46083", "46086", "46087", "46088", "46090", "46092", "46093", "46094", "46101", "46102", "46106", "46108", "46110", "46114", "46116", "46117", "46118", "46120", "46125", "46126", "46128", "46132", "46140", "46142", "46143", "46145", "46148", "46151", "46152", "46153", "46156", "46157", "46160", "46161", "46162", "46163", "46166", "46167", "46168", "46169", "46170", "46175", "46176", "46179", "46180", "46181", "46182", "46183", "46184", "46187", "46192", "46193", "46195", "46196", "46197", "46198", "46201", "46202", "46203", "46204", "46205", "46207", "46208", "46210", "46211", "46213", "46217", "46218", "46220", "46221", "46226", "46227", "46228", "46229", "46230", "46232", "46234", "46237", "46238", "46239", "46240", "46241", "46242", "46244", "46245", "46247", "46250", "46251", "46252", "46253", "46254", "46255", "46256", "46258", "46260", "46261", "46262", "46263", "46266", "46270", "46271", "46274", "46275", "46276", "46277", "46285", "46287", "46289", "46291", "46292", "46293", "46294", "46299", "46302", "46304", "46305", "46306", "46309", "46312", "46314", "46315", "46317", "46318", "46319", "46320", "46322", "46323", "46324", "46325", "46326", "46327", "46329", "46330", "46334", "46335", "46340", "46343", "46345", "46346", "46347", "46354", "46357", "46358", "46363", "46365", "46367", "46368", "46369", "46373", "46374", "46375", "46377", "46381", "46382", "46383", "46384", "46387", "46388", "46389", "46392", "46393", "46394", "46396", "46397", "46400", "46405", "46408", "46409", "46410", "46412", "46416", "46417", "46418", "46419", "46420", "46425", "46429", "46430", "46431", "46433", "46434", "46435", "46436", "46445", "46449", "46451", "46453", "46454", "46457", "46458", "46460", "46465", "46466", "46468", "46469", "46470", "46473", "46479", "46481", "46482", "46483", "46487", "46488", "46489", "46492", "46493", "46496", "46497", "46498", "46499", "46500", "46501", "46502", "46504", "46506", "46509", "46513", "46514", "46515", "46516", "46518", "46521", "46523", "46525", "46529", "46530", "46533", "46535", "46536", "46538", "46539", "46540", "46544", "46547", "46548", "46550", "46551", "46552", "46554", "46555", "46556", "46557", "46558", "46559", "46561", "46563", "46565", "46566", "46575", "46576", "46577", "46578", "46579", "46581", "46582", "46583", "46584", "46586", "46590", "46593", "46594", "46595", "46596", "46597", "46598", "46599", "46600", "46602", "46604", "46608", "46612", "46613", "46614", "46615", "46618", "46619", "46620", "46624", "46626", "46628", "46629", "46630", "46631", "46634", "46635", "46636", "46637", "46638", "46643", "46644", "46645", "46647", "46651", "46654", "46656", "46660", "46662", "46663", "46664", "46672", "46673", "46674", "46675", "46676", "46677", "46678", "46682", "46690", "46691", "46692", "46693", "46695", "46696", "46697", "46698", "46700", "46701", "46703", "46706", "46708", "46709", "46712", "46714", "46715", "46717", "46718", "46720", "46724", "46727", "46728", "46730", "46731", "46732", "46733", "46737", "46738", "46739", "46742", "46743", "46745", "46748", "46750", "46752", "46753", "46755", "46756", "46757", "46758", "46760", "46763", "46770", "46771", "46776", "46778", "46779", "46780", "46782", "46783", "46787", "46790", "46792", "46796", "46799", "46800", "46801", "46803", "46804", "46805", "46807", "46808", "46809", "46811", "46813", "46815", "46817", "46818", "46819", "46821", "46822", "46823", "46825", "46826", "46829", "46831", "46832", "46834", "46836", "46839", "46840", "46843", "46844", "46845", "46846", "46847", "46849", "46856", "46860", "46861", "46862", "46864", "46865", "46866", "46867", "46870", "46871", "46878", "46879", "46880", "46882", "46883", "46886", "46887", "46891", "46892", "46893", "46895", "46897", "46900", "46902", "46903", "46904", "46905", "46909", "46911", "46919", "46920", "46921", "46923", "46929", "46931", "46934", "46935", "46936", "46938", "46941", "46942", "46943", "46944", "46945", "46949", "46950", "46953", "46955", "46957", "46958", "46960", "46964", "46967", "46968", "46969", "46970", "46972", "46974", "46976", "46977", "46978", "46979", "46981", "46982", "46984", "46985", "46987", "46988", "46990", "46992", "46996", "46997", "47001", "47002", "47006", "47007", "47008", "47010", "47012", "47014", "47017", "47018", "47020", "47022", "47023", "47024", "47026", "47028", "47031", "47032", "47033", "47037", "47038", "47039", "47040", "47041", "47044", "47045", "47047", "47050", "47051", "47052", "47054", "47055", "47061", "47065", "47068", "47070", "47072", "47073", "47074", "47080", "47082", "47084", "47087", "47091", "47094", "47097", "47100", "47102", "47105", "47107", "47109", "47110", "47111", "47112", "47113", "47114", "47116", "47118", "47120", "47121", "47123", "47124", "47125", "47126", "47127", "47128", "47129", "47134", "47136", "47141", "47143", "47145", "47152", "47153", "47156", "47157", "47158", "47159", "47160", "47161", "47162", "47163", "47164", "47165", "47167", "47168", "47171", "47173", "47175", "47179", "47180", "47181", "47184", "47185", "47193", "47194", "47195", "47196", "47198", "47200", "47201", "47202", "47203", "47207", "47208", "47209", "47210", "47212", "47213", "47219", "47220", "47224", "47226", "47227", "47228", "47230", "47232", "47237", "47241", "47242", "47243", "47246", "47247", "47248", "47250", "47251", "47252", "47253", "47254", "47256", "47258", "47260", "47261", "47269", "47271", "47275", "47276", "47281", "47285", "47286", "47288", "47289", "47290", "47291", "47297", "47298", "47302", "47304", "47308", "47311", "47313", "47314", "47316", "47317", "47319", "47324", "47325", "47328", "47329", "47331", "47333", "47335", "47339", "47340", "47341", "47343", "47346", "47347", "47349", "47350", "47353", "47356", "47357", "47361", "47362", "47364", "47365", "47367", "47368", "47369", "47371", "47372", "47374", "47375", "47377", "47378", "47379", "47380", "47381", "47382", "47383", "47385", "47390", "47394", "47396", "47397", "47398", "47400", "47407", "47410", "47411", "47414", "47416", "47420", "47423", "47426", "47427", "47430", "47431", "47434", "47435", "47437", "47439", "47441", "47442", "47443", "47452", "47453", "47454", "47462", "47463", "47470", "47472", "47473", "47474", "47475", "47476", "47482", "47486", "47488", "47489", "47490", "47494", "47495", "47496", "47500", "47501", "47507", "47508", "47510", "47511", "47512", "47516", "47521", "47524", "47526", "47527", "47529", "47530", "47532", "47535", "47536", "47538", "47541", "47543", "47544", "47545", "47546", "47548", "47549", "47550", "47551", "47552", "47553", "47558", "47559", "47560", "47561", "47562", "47563", "47566", "47568", "47569", "47572", "47576", "47577", "47579", "47581", "47585", "47586", "47587", "47591", "47592", "47593", "47597", "47598", "47602", "47604", "47605", "47608", "47609", "47610", "47611", "47612", "47615", "47616", "47619", "47620", "47621", "47624", "47625", "47626", "47627", "47630", "47631", "47636", "47638", "47640", "47642", "47643", "47644", "47645", "47647", "47648", "47651", "47652", "47656", "47657", "47660", "47670", "47671", "47672", "47676", "47677", "47678", "47682", "47683", "47686", "47687", "47689", "47690", "47692", "47693", "47695", "47703", "47705", "47708", "47710", "47712", "47713", "47715", "47719", "47720", "47721", "47723", "47725", "47729", "47730", "47732", "47734", "47735", "47737", "47738", "47739", "47740", "47744", "47745", "47746", "47748", "47749", "47750", "47751", "47752", "47753", "47755", "47756", "47757", "47758", "47759", "47760", "47761", "47762", "47763", "47765", "47771", "47773", "47775", "47776", "47777", "47779", "47782", "47783", "47786", "47787", "47790", "47791", "47792", "47793", "47794", "47799", "47801", "47802", "47803", "47804", "47806", "47807", "47808", "47810", "47811", "47813", "47815", "47817", "47818", "47819", "47822", "47823", "47824", "47825", "47828", "47832", "47833", "47834", "47835", "47838", "47839", "47842", "47843", "47844", "47848", "47849", "47859", "47860", "47862", "47864", "47867", "47868", "47869", "47871", "47872", "47873", "47874", "47875", "47877", "47882", "47884", "47885", "47887", "47888", "47893", "47894", "47895", "47900", "47902", "47904", "47909", "47911", "47913", "47915", "47919", "47920", "47922", "47925", "47926", "47928", "47929", "47934", "47943", "47944", "47947", "47949", "47950", "47953", "47955", "47956", "47959", "47960", "47963", "47964", "47968", "47972", "47973", "47977", "47978", "47981", "47982", "47983", "47984", "47994", "47999", "48000", "48001", "48004", "48005", "48009", "48012", "48013", "48015", "48016", "48022", "48023", "48024", "48025", "48026", "48028", "48031", "48034", "48039", "48040", "48041", "48044", "48045", "48046", "48048", "48051", "48052", "48054", "48058", "48060", "48061", "48063", "48069", "48071", "48072", "48073", "48074", "48075", "48077", "48078", "48081", "48082", "48083", "48087", "48091", "48092", "48094", "48095", "48096", "48097", "48099", "48101", "48102", "48103", "48104", "48107", "48108", "48109", "48111", "48115", "48118", "48120", "48121", "48126", "48129", "48130", "48131", "48133", "48134", "48143", "48147", "48149", "48150", "48154", "48155", "48156", "48157", "48161", "48163", "48165", "48166", "48167", "48171", "48173", "48175", "48177", "48180", "48181", "48182", "48183", "48184", "48185", "48187", "48189", "48192", "48193", "48196", "48198", "48200", "48202", "48205", "48206", "48209", "48210", "48213", "48214", "48215", "48218", "48219", "48222", "48223", "48224", "48227", "48228", "48231", "48234", "48236", "48237", "48238", "48240", "48241", "48245", "48247", "48248", "48253", "48254", "48255", "48256", "48260", "48262", "48263", "48265", "48266", "48268", "48271", "48272", "48275", "48276", "48277", "48278", "48279", "48281", "48282", "48283", "48285", "48286", "48288", "48291", "48292", "48293", "48294", "48295", "48297", "48299", "48301", "48304", "48305", "48308", "48310", "48314", "48317", "48318", "48320", "48322", "48323", "48325", "48327", "48328", "48329", "48333", "48334", "48335", "48337", "48338", "48340", "48342", "48343", "48350", "48352", "48354", "48355", "48356", "48357", "48358", "48359", "48361", "48366", "48367", "48368", "48372", "48374", "48376", "48377", "48379", "48382", "48384", "48385", "48387", "48390", "48391", "48394", "48395", "48399", "48400", "48403", "48406", "48408", "48411", "48413", "48420", "48421", "48423", "48426", "48428", "48429", "48432", "48433", "48435", "48437", "48441", "48447", "48451", "48452", "48454", "48459", "48460", "48461", "48463", "48464", "48472", "48473", "48474", "48475", "48478", "48481", "48483", "48490", "48491", "48493", "48499", "48501", "48502", "48503", "48504", "48507", "48510", "48513", "48514", "48516", "48518", "48520", "48524", "48529", "48530", "48531", "48535", "48538", "48539", "48541", "48543", "48544", "48545", "48546", "48547", "48548", "48550", "48553", "48554", "48559", "48560", "48564", "48569", "48571", "48572", "48573", "48575", "48576", "48580", "48581", "48582", "48585", "48586", "48588", "48589", "48594", "48595", "48598", "48599", "48601", "48602", "48604", "48605", "48606", "48609", "48612", "48613", "48616", "48619", "48622", "48623", "48626", "48627", "48629", "48630", "48633", "48635", "48639", "48642", "48643", "48646", "48652", "48653", "48654", "48655", "48660", "48663", "48664", "48667", "48669", "48671", "48673", "48674", "48680", "48681", "48682", "48684", "48685", "48695", "48698", "48702", "48704", "48705", "48707", "48709", "48710", "48715", "48716", "48717", "48720", "48722", "48725", "48727", "48730", "48732", "48733", "48736", "48739", "48742", "48743", "48744", "48745", "48747", "48749", "48754", "48755", "48758", "48760", "48761", "48762", "48763", "48767", "48768", "48769", "48770", "48774", "48777", "48780", "48786", "48788", "48794", "48797", "48798", "48799", "48801", "48802", "48803", "48804", "48805", "48806", "48807", "48808", "48812", "48813", "48814", "48815", "48816", "48820", "48821", "48825", "48827", "48829", "48830", "48833", "48834", "48835", "48836", "48839", "48840", "48845", "48846", "48847", "48848", "48849", "48850", "48851", "48854", "48856", "48857", "48859", "48860", "48864", "48866", "48867", "48868", "48870", "48872", "48873", "48874", "48875", "48879", "48881", "48882", "48883", "48885", "48886", "48887", "48888", "48889", "48894", "48895", "48896", "48897", "48898", "48903", "48904", "48909", "48911", "48912", "48913", "48914", "48916", "48917", "48918", "48919", "48922", "48924", "48925", "48930", "48931", "48932", "48936", "48937", "48938", "48940", "48941", "48944", "48945", "48948", "48949", "48951", "48956", "48958", "48959", "48961", "48964", "48966", "48967", "48969", "48970", "48972", "48973", "48974", "48975", "48976", "48978", "48979", "48980", "48981", "48984", "48986", "48987", "48990", "48991", "48992", "48994", "48997", "48999", "49002", "49004", "49006", "49007", "49008", "49009", "49011", "49013", "49014", "49015", "49016", "49019", "49024", "49025", "49026", "49027", "49031", "49033", "49038", "49039", "49040", "49042", "49043", "49045", "49046", "49047", "49048", "49049", "49050", "49051", "49053", "49055", "49056", "49057", "49058", "49059", "49061", "49062", "49064", "49067", "49072", "49074", "49079", "49081", "49083", "49084", "49085", "49090", "49091", "49096", "49097", "49098", "49099", "49100", "49102", "49105", "49109", "49111", "49112", "49113", "49114", "49115", "49116", "49117", "49119", "49122", "49128", "49129", "49130", "49131", "49132", "49133", "49136", "49139", "49140", "49141", "49142", "49143", "49144", "49148", "49149", "49150", "49151", "49152", "49156", "49157", "49158", "49159", "49162", "49163", "49164", "49166", "49167", "49169", "49170", "49171", "49174", "49177", "49178", "49182", "49183", "49185", "49189", "49190", "49192", "49193", "49194", "49195", "49196", "49197", "49198", "49199", "49200", "49201", "49206", "49208", "49210", "49211", "49212", "49215", "49216", "49217", "49219", "49223", "49224", "49225", "49226", "49229", "49231", "49232", "49237", "49238", "49239", "49241", "49242", "49245", "49246", "49250", "49252", "49258", "49260", "49262", "49265", "49267", "49268", "49271", "49274", "49275", "49277", "49279", "49281", "49282", "49283", "49284", "49285", "49287", "49289", "49290", "49294", "49298", "49303", "49304", "49306", "49307", "49308", "49312", "49313", "49316", "49318", "49319", "49320", "49322", "49323", "49324", "49325", "49328", "49335", "49338", "49340", "49341", "49348", "49349", "49350", "49352", "49354", "49356", "49358", "49359", "49361", "49362", "49363", "49364", "49366", "49368", "49369", "49370", "49375", "49379", "49382", "49383", "49384", "49385", "49387", "49388", "49395", "49396", "49399", "49405", "49407", "49408", "49409", "49412", "49413", "49416", "49419", "49428", "49430", "49431", "49432", "49435", "49436", "49438", "49441", "49442", "49444", "49446", "49447", "49448", "49452", "49453", "49454", "49455", "49462", "49464", "49468", "49472", "49474", "49477", "49479", "49480", "49481", "49484", "49485", "49486", "49487", "49489", "49491", "49493", "49494", "49496", "49498", "49499", "49500", "49503", "49504", "49505", "49509", "49510", "49511", "49512", "49513", "49514", "49517", "49518", "49519", "49520", "49522", "49523", "49524", "49525", "49527", "49529", "49530", "49531", "49533", "49535", "49537", "49538", "49539", "49540", "49541", "49542", "49543", "49544", "49547", "49550", "49551", "49553", "49556", "49558", "49559", "49563", "49566", "49567", "49568", "49570", "49571", "49573", "49575", "49577", "49578", "49579", "49580", "49582", "49584", "49585", "49587", "49589", "49591", "49593", "49594", "49595", "49597", "49598", "49599", "49600", "49601", "49602", "49603", "49605", "49606", "49607", "49608", "49609", "49610", "49611", "49614", "49617", "49618", "49619", "49621", "49624", "49625", "49626", "49628", "49631", "49633", "49634", "49635", "49636", "49638", "49639", "49642", "49646", "49648", "49654", "49655", "49656", "49658", "49660", "49661", "49662", "49663", "49666", "49667", "49668", "49671", "49677", "49679", "49682", "49683", "49689", "49690", "49691", "49692", "49696", "49697", "49698", "49699", "49700", "49704", "49708", "49709", "49714", "49719", "49721", "49726", "49727", "49730", "49731", "49732", "49735", "49736", "49739", "49740", "49741", "49742", "49743", "49747", "49748", "49749", "49750", "49752", "49755", "49757", "49758", "49760", "49761", "49762", "49764", "49766", "49768", "49771", "49772", "49776", "49777", "49779", "49780", "49782", "49784", "49785", "49786", "49787", "49788", "49793", "49794", "49799", "49800", "49807", "49809", "49810", "49811", "49812", "49815", "49816", "49818", "49821", "49824", "49825", "49827", "49830", "49832", "49833", "49838", "49839", "49840", "49845", "49847", "49848", "49851", "49855", "49858", "49861", "49862", "49863", "49864", "49867", "49876", "49877", "49882", "49883", "49885", "49887", "49888", "49889", "49890", "49891", "49893", "49897", "49898", "49900", "49901", "49902", "49903", "49906", "49913", "49918", "49921", "49922", "49924", "49925", "49926", "49928", "49929", "49932", "49933", "49935", "49936", "49944", "49946", "49949", "49952", "49953", "49956", "49957", "49959", "49964", "49965", "49966", "49967", "49969", "49971", "49972", "49974", "49977", "49980", "49981", "49983", "49984", "49987", "49988", "49989", "49990", "49992", "49994"]],
+ "valid" : ["int" , ["1", "2", "3", "4", "6", "8", "9", "10", "12", "14", "18", "19", "21", "22", "23", "25", "27", "29", "33", "35", "38", "41", "42", "44", "45", "47", "51", "54", "57", "59", "61", "62", "63", "64", "65", "67", "70", "71", "72", "73", "76", "80", "82", "83", "84", "85", "87", "89", "91", "92", "95", "98", "99", "102", "105", "108", "110", "116", "119", "121", "127", "130", "133", "138", "143", "145", "146", "149", "150", "153", "154", "157", "159", "160", "163", "176", "177", "180", "181", "182", "183", "184", "186", "187", "190", "191", "194", "198", "199", "200", "201", "202", "208", "214", "215", "218", "219", "220", "221", "222", "223", "224", "230", "232", "234", "235", "236", "237", "238", "239", "240", "242", "244", "246", "248", "249", "253", "258", "260", "261", "264", "265", "266", "267", "270", "274", "277", "279", "281", "283", "285", "286", "289", "290", "292", "293", "294", "298", "299", "304", "306", "307", "308", "309", "310", "311", "313", "314", "316", "320", "321", "324", "325", "326", "330", "331", "334", "337", "339", "342", "344", "345", "346", "348", "349", "350", "352", "353", "354", "356", "357", "358", "359", "360", "362", "363", "365", "366", "368", "373", "374", "377", "378", "379", "382", "383", "384", "385", "390", "391", "392", "393", "394", "395", "396", "401", "404", "407", "409", "410", "411", "413", "416", "417", "418", "419", "420", "421", "423", "426", "427", "428", "429", "436", "437", "441", "442", "446", "447", "448", "449", "450", "455", "458", "459", "460", "462", "463", "464", "467", "468", "470", "472", "473", "474", "475", "477", "479", "480", "481", "482", "485", "486", "488", "489", "490", "491", "492", "494", "495", "496", "499", "501", "502", "505", "509", "511", "512", "515", "517", "518", "519", "520", "521", "523", "524", "526", "528", "530", "534", "536", "537", "538", "540", "541", "542", "543", "550", "552", "555", "556", "558", "559", "560", "561", "562", "563", "566", "569", "570", "571", "574", "575", "576", "577", "580", "581", "583", "586", "587", "588", "592", "593", "594", "599", "603", "606", "607", "609", "610", "611", "613", "614", "616", "617", "618", "622", "623", "628", "630", "632", "633", "635", "636", "638", "640", "642", "644", "646", "647", "648", "651", "654", "656", "657", "658", "659", "660", "661", "662", "663", "664", "665", "667", "669", "672", "675", "678", "681", "682", "684", "685", "689", "690", "692", "693", "697", "698", "699", "701", "702", "703", "704", "706", "708", "709", "711", "712", "713", "714", "715", "718", "719", "720", "723", "725", "726", "728", "730", "733", "736", "740", "743", "744", "745", "746", "747", "749", "750", "753", "754", "755", "757", "758", "759", "762", "763", "764", "766", "767", "769", "770", "772", "773", "776", "778", "779", "780", "782", "786", "788", "792", "795", "796", "801", "802", "804", "805", "806", "808", "810", "813", "814", "818", "824", "826", "829", "830", "834", "835", "836", "839", "840", "843", "844", "845", "847", "848", "849", "850", "851", "852", "856", "858", "860", "862", "863", "865", "866", "867", "874", "875", "877", "878", "879", "880", "882", "883", "884", "886", "888", "890", "891", "892", "893", "894", "895", "898", "904", "908", "915", "916", "917", "920", "921", "924", "926", "928", "929", "930", "931", "932", "933", "936", "938", "939", "940", "941", "942", "943", "947", "949", "950", "952", "955", "956", "962", "963", "969", "971", "974", "976", "977", "982", "983", "984", "985", "989", "998", "999", "1000", "1001", "1002", "1003", "1004", "1007", "1010", "1011", "1013", "1016", "1017", "1019", "1020", "1025", "1026", "1027", "1028", "1031", "1033", "1034", "1036", "1039", "1040", "1041", "1045", "1046", "1048", "1050", "1051", "1054", "1058", "1059", "1060", "1061", "1064", "1069", "1070", "1072", "1073", "1075", "1078", "1082", "1083", "1086", "1088", "1089", "1090", "1092", "1093", "1095", "1097", "1098", "1099", "1104", "1105", "1114", "1120", "1121", "1122", "1124", "1125", "1126", "1127", "1128", "1130", "1131", "1133", "1134", "1136", "1141", "1145", "1146", "1147", "1148", "1149", "1152", "1153", "1159", "1161", "1163", "1164", "1167", "1168", "1169", "1170", "1172", "1173", "1174", "1176", "1178", "1182", "1183", "1188", "1189", "1190", "1191", "1192", "1195", "1196", "1197", "1198", "1200", "1201", "1203", "1204", "1205", "1206", "1207", "1209", "1210", "1211", "1212", "1215", "1216", "1218", "1221", "1222", "1224", "1230", "1232", "1234", "1240", "1241", "1247", "1248", "1250", "1253", "1254", "1255", "1258", "1259", "1261", "1262", "1263", "1265", "1267", "1268", "1270", "1271", "1273", "1275", "1281", "1284", "1290", "1293", "1296", "1299", "1301", "1303", "1307", "1309", "1312", "1314", "1315", "1323", "1326", "1328", "1330", "1332", "1333", "1336", "1337", "1340", "1343", "1344", "1345", "1346", "1347", "1349", "1350", "1353", "1356", "1358", "1359", "1360", "1361", "1362", "1364", "1365", "1366", "1368", "1370", "1371", "1373", "1374", "1377", "1379", "1382", "1384", "1385", "1387", "1394", "1397", "1398", "1399", "1400", "1402", "1404", "1405", "1407", "1408", "1409", "1411", "1412", "1413", "1416", "1417", "1418", "1423", "1424", "1428", "1430", "1431", "1433", "1435", "1436", "1437", "1438", "1440", "1441", "1442", "1443", "1447", "1449", "1451", "1452", "1453", "1455", "1457", "1459", "1462", "1464", "1465", "1466", "1468", "1470", "1471", "1473", "1474", "1476", "1477", "1478", "1480", "1481", "1485", "1488", "1489", "1491", "1494", "1495", "1496", "1498", "1499", "1500", "1501", "1502", "1505", "1508", "1509", "1514", "1515", "1517", "1519", "1521", "1528", "1529", "1530", "1533", "1535", "1537", "1540", "1542", "1543", "1549", "1554", "1557", "1558", "1560", "1562", "1565", "1567", "1568", "1569", "1571", "1572", "1573", "1574", "1575", "1576", "1577", "1578", "1582", "1583", "1584", "1588", "1592", "1596", "1597", "1598", "1599", "1600", "1601", "1602", "1603", "1606", "1607", "1610", "1611", "1613", "1615", "1616", "1617", "1618", "1619", "1621", "1624", "1627", "1629", "1630", "1631", "1633", "1643", "1644", "1645", "1646", "1647", "1648", "1649", "1650", "1653", "1655", "1657", "1658", "1659", "1662", "1666", "1667", "1672", "1675", "1678", "1679", "1680", "1681", "1682", "1683", "1689", "1692", "1693", "1694", "1696", "1698", "1702", "1703", "1706", "1707", "1708", "1714", "1716", "1719", "1725", "1726", "1727", "1728", "1729", "1730", "1731", "1732", "1735", "1736", "1737", "1738", "1743", "1745", "1747", "1751", "1753", "1755", "1758", "1762", "1764", "1773", "1774", "1779", "1780", "1781", "1782", "1783", "1785", "1786", "1787", "1789", "1793", "1794", "1795", "1796", "1797", "1799", "1800", "1801", "1802", "1804", "1807", "1808", "1809", "1811", "1813", "1814", "1816", "1818", "1821", "1822", "1823", "1824", "1825", "1827", "1828", "1830", "1832", "1836", "1838", "1839", "1842", "1843", "1847", "1848", "1854", "1856", "1857", "1858", "1859", "1860", "1861", "1863", "1866", "1867", "1868", "1870", "1873", "1875", "1877", "1878", "1879", "1881", "1884", "1886", "1890", "1894", "1898", "1902", "1903", "1907", "1909", "1910", "1911", "1913", "1917", "1918", "1919", "1921", "1922", "1927", "1928", "1929", "1930", "1931", "1933", "1938", "1940", "1941", "1942", "1944", "1948", "1950", "1952", "1953", "1954", "1957", "1958", "1959", "1960", "1961", "1963", "1964", "1965", "1967", "1968", "1976", "1977", "1978", "1982", "1984", "1987", "1988", "1989", "1993", "1994", "1995", "1996", "1999", "2000", "2004", "2007", "2011", "2012", "2013", "2014", "2017", "2024", "2025", "2026", "2027", "2032", "2034", "2035", "2036", "2038", "2039", "2041", "2043", "2044", "2045", "2046", "2048", "2050", "2052", "2054", "2057", "2058", "2059", "2060", "2063", "2064", "2073", "2075", "2077", "2078", "2080", "2082", "2087", "2089", "2090", "2094", "2095", "2097", "2101", "2108", "2109", "2112", "2115", "2116", "2117", "2118", "2120", "2121", "2123", "2124", "2129", "2130", "2132", "2133", "2134", "2136", "2137", "2139", "2141", "2144", "2146", "2148", "2154", "2155", "2158", "2162", "2164", "2165", "2166", "2167", "2169", "2171", "2172", "2177", "2178", "2184", "2185", "2186", "2190", "2191", "2192", "2195", "2197", "2199", "2202", "2203", "2208", "2209", "2210", "2212", "2216", "2219", "2220", "2221", "2222", "2223", "2224", "2225", "2228", "2231", "2232", "2236", "2237", "2238", "2239", "2243", "2244", "2246", "2247", "2253", "2256", "2261", "2262", "2263", "2264", "2265", "2268", "2270", "2277", "2278", "2279", "2280", "2281", "2282", "2283", "2285", "2287", "2288", "2290", "2292", "2293", "2296", "2297", "2298", "2300", "2305", "2306", "2307", "2308", "2310", "2311", "2314", "2317", "2320", "2326", "2328", "2331", "2332", "2334", "2335", "2336", "2337", "2339", "2341", "2342", "2345", "2348", "2354", "2356", "2357", "2360", "2362", "2364", "2366", "2367", "2369", "2371", "2374", "2375", "2377", "2378", "2379", "2380", "2381", "2384", "2385", "2387", "2388", "2391", "2393", "2394", "2395", "2396", "2397", "2400", "2402", "2403", "2404", "2405", "2406", "2407", "2408", "2409", "2410", "2412", "2415", "2417", "2419", "2420", "2421", "2423", "2425", "2426", "2427", "2428", "2431", "2433", "2435", "2436", "2437", "2438", "2443", "2444", "2446", "2452", "2454", "2455", "2456", "2460", "2462", "2463", "2464", "2467", "2468", "2471", "2475", "2477", "2479", "2480", "2482", "2487", "2490", "2491", "2492", "2494", "2495", "2497", "2500", "2503", "2507", "2509", "2510", "2511", "2512", "2513", "2517", "2519", "2522", "2523", "2526", "2527", "2533", "2534", "2535", "2536", "2538", "2541", "2547", "2550", "2552", "2553", "2555", "2557", "2558", "2559", "2560", "2561", "2562", "2565", "2571", "2572", "2574", "2575", "2576", "2578", "2582", "2583", "2591", "2595", "2598", "2600", "2601", "2606", "2608", "2609", "2613", "2618", "2620", "2623", "2626", "2631", "2632", "2633", "2635", "2638", "2639", "2643", "2644", "2647", "2648", "2650", "2654", "2658", "2660", "2662", "2664", "2667", "2669", "2672", "2673", "2675", "2683", "2689", "2692", "2694", "2695", "2696", "2699", "2701", "2702", "2703", "2704", "2705", "2709", "2712", "2717", "2718", "2722", "2723", "2724", "2725", "2726", "2727", "2728", "2729", "2730", "2732", "2733", "2737", "2738", "2741", "2742", "2745", "2747", "2749", "2750", "2751", "2754", "2755", "2758", "2766", "2767", "2768", "2769", "2772", "2773", "2777", "2778", "2780", "2783", "2784", "2786", "2788", "2789", "2791", "2797", "2799", "2800", "2801", "2804", "2805", "2807", "2812", "2813", "2814", "2816", "2817", "2818", "2819", "2820", "2821", "2823", "2825", "2831", "2832", "2833", "2838", "2840", "2841", "2845", "2846", "2847", "2848", "2852", "2855", "2858", "2859", "2860", "2861", "2862", "2863", "2864", "2865", "2869", "2870", "2871", "2873", "2877", "2878", "2881", "2882", "2883", "2884", "2885", "2888", "2889", "2890", "2891", "2893", "2897", "2899", "2903", "2904", "2907", "2911", "2912", "2918", "2920", "2921", "2922", "2926", "2928", "2931", "2932", "2933", "2936", "2937", "2941", "2944", "2949", "2951", "2953", "2954", "2955", "2956", "2958", "2960", "2961", "2963", "2964", "2966", "2969", "2970", "2972", "2973", "2979", "2980", "2981", "2982", "2983", "2984", "2986", "2987", "2993", "2994", "2995", "2996", "2997", "2999", "3000", "3001", "3010", "3018", "3020", "3023", "3024", "3025", "3026", "3027", "3029", "3030", "3031", "3032", "3034", "3035", "3037", "3038", "3040", "3041", "3042", "3043", "3044", "3048", "3049", "3052", "3053", "3054", "3055", "3056", "3062", "3063", "3064", "3069", "3071", "3073", "3075", "3076", "3077", "3079", "3081", "3082", "3083", "3084", "3086", "3092", "3093", "3094", "3095", "3097", "3098", "3099", "3102", "3104", "3105", "3106", "3107", "3108", "3109", "3113", "3116", "3118", "3120", "3125", "3128", "3129", "3131", "3132", "3134", "3135", "3136", "3138", "3142", "3144", "3147", "3148", "3149", "3152", "3153", "3155", "3156", "3158", "3161", "3162", "3164", "3168", "3170", "3172", "3173", "3177", "3181", "3182", "3183", "3187", "3189", "3191", "3192", "3195", "3196", "3199", "3200", "3201", "3204", "3205", "3207", "3210", "3214", "3216", "3218", "3219", "3221", "3223", "3224", "3226", "3227", "3233", "3235", "3237", "3238", "3239", "3240", "3242", "3244", "3245", "3246", "3247", "3251", "3253", "3254", "3255", "3256", "3257", "3258", "3259", "3260", "3262", "3266", "3268", "3272", "3275", "3277", "3278", "3279", "3286", "3290", "3292", "3296", "3302", "3303", "3304", "3305", "3306", "3307", "3309", "3313", "3314", "3317", "3321", "3322", "3323", "3324", "3325", "3326", "3327", "3328", "3329", "3330", "3334", "3336", "3337", "3346", "3347", "3348", "3350", "3351", "3353", "3354", "3357", "3360", "3361", "3363", "3364", "3369", "3371", "3372", "3374", "3377", "3380", "3381", "3382", "3383", "3385", "3387", "3389", "3393", "3394", "3395", "3397", "3399", "3401", "3403", "3409", "3411", "3413", "3414", "3415", "3417", "3418", "3419", "3424", "3429", "3433", "3437", "3438", "3439", "3441", "3443", "3446", "3450", "3452", "3454", "3456", "3459", "3460", "3461", "3464", "3465", "3467", "3469", "3470", "3471", "3473", "3474", "3477", "3478", "3481", "3486", "3487", "3489", "3495", "3497", "3498", "3499", "3501", "3502", "3503", "3505", "3506", "3507", "3508", "3510", "3511", "3514", "3516", "3519", "3520", "3521", "3523", "3525", "3526", "3531", "3532", "3533", "3535", "3538", "3540", "3542", "3543", "3545", "3548", "3549", "3556", "3557", "3559", "3560", "3561", "3562", "3565", "3566", "3568", "3571", "3573", "3574", "3575", "3576", "3581", "3582", "3584", "3585", "3587", "3588", "3589", "3590", "3591", "3594", "3595", "3599", "3603", "3604", "3607", "3609", "3611", "3612", "3614", "3615", "3619", "3620", "3623", "3625", "3626", "3627", "3628", "3630", "3631", "3633", "3636", "3637", "3638", "3640", "3644", "3646", "3647", "3649", "3651", "3652", "3653", "3654", "3655", "3656", "3657", "3660", "3662", "3663", "3665", "3668", "3669", "3670", "3675", "3680", "3682", "3683", "3684", "3685", "3688", "3691", "3694", "3695", "3698", "3699", "3702", "3704", "3705", "3706", "3707", "3713", "3715", "3716", "3719", "3722", "3725", "3727", "3730", "3733", "3734", "3737", "3739", "3741", "3743", "3746", "3749", "3752", "3753", "3754", "3755", "3757", "3758", "3759", "3762", "3763", "3765", "3766", "3767", "3768", "3770", "3772", "3773", "3775", "3776", "3778", "3781", "3782", "3783", "3785", "3786", "3787", "3789", "3790", "3791", "3792", "3793", "3794", "3796", "3797", "3798", "3800", "3801", "3802", "3805", "3806", "3809", "3812", "3815", "3816", "3818", "3819", "3820", "3821", "3822", "3824", "3825", "3831", "3832", "3833", "3836", "3838", "3840", "3841", "3843", "3847", "3848", "3849", "3850", "3855", "3857", "3858", "3860", "3861", "3863", "3864", "3871", "3873", "3878", "3879", "3880", "3884", "3886", "3887", "3889", "3897", "3899", "3904", "3906", "3907", "3909", "3910", "3912", "3913", "3914", "3915", "3920", "3921", "3923", "3928", "3933", "3935", "3938", "3939", "3940", "3941", "3942", "3948", "3949", "3951", "3953", "3958", "3962", "3965", "3966", "3967", "3969", "3970", "3972", "3974", "3975", "3976", "3977", "3979", "3988", "3989", "3990", "3995", "3996", "3998", "4001", "4004", "4005", "4011", "4012", "4013", "4014", "4017", "4019", "4022", "4023", "4024", "4025", "4026", "4028", "4029", "4030", "4031", "4034", "4037", "4039", "4042", "4043", "4044", "4046", "4048", "4049", "4050", "4051", "4055", "4056", "4060", "4063", "4064", "4066", "4067", "4068", "4070", "4075", "4077", "4078", "4081", "4082", "4083", "4084", "4087", "4090", "4092", "4094", "4099", "4105", "4106", "4107", "4108", "4110", "4111", "4113", "4115", "4116", "4118", "4120", "4121", "4123", "4124", "4126", "4130", "4131", "4132", "4134", "4136", "4140", "4143", "4144", "4145", "4146", "4149", "4150", "4153", "4154", "4155", "4161", "4163", "4164", "4165", "4167", "4168", "4172", "4173", "4174", "4175", "4177", "4178", "4183", "4184", "4185", "4186", "4187", "4189", "4190", "4192", "4193", "4196", "4197", "4198", "4204", "4206", "4208", "4209", "4210", "4211", "4212", "4213", "4214", "4217", "4218", "4220", "4221", "4222", "4223", "4224", "4227", "4231", "4232", "4234", "4235", "4237", "4238", "4239", "4240", "4241", "4242", "4243", "4251", "4252", "4253", "4254", "4255", "4259", "4261", "4262", "4263", "4264", "4266", "4268", "4269", "4271", "4272", "4273", "4274", "4276", "4278", "4280", "4285", "4286", "4287", "4288", "4290", "4292", "4294", "4296", "4300", "4301", "4308", "4311", "4313", "4317", "4320", "4321", "4322", "4324", "4325", "4327", "4329", "4330", "4332", "4334", "4337", "4339", "4342", "4343", "4345", "4346", "4347", "4351", "4354", "4355", "4359", "4363", "4364", "4366", "4367", "4368", "4371", "4373", "4379", "4380", "4381", "4383", "4384", "4385", "4386", "4387", "4390", "4394", "4395", "4396", "4397", "4398", "4400", "4401", "4402", "4403", "4404", "4407", "4414", "4415", "4416", "4418", "4419", "4420", "4421", "4424", "4425", "4427", "4429", "4430", "4431", "4436", "4440", "4442", "4443", "4447", "4448", "4449", "4458", "4460", "4462", "4463", "4465", "4468", "4469", "4470", "4472", "4479", "4480", "4482", "4483", "4486", "4487", "4489", "4491", "4492", "4493", "4494", "4495", "4498", "4499", "4500", "4501", "4504", "4505", "4507", "4508", "4515", "4516", "4518", "4519", "4520", "4522", "4523", "4525", "4529", "4530", "4531", "4533", "4535", "4539", "4542", "4543", "4544", "4545", "4550", "4553", "4556", "4559", "4566", "4569", "4570", "4571", "4572", "4574", "4576", "4577", "4579", "4582", "4583", "4585", "4586", "4587", "4588", "4591", "4592", "4593", "4594", "4595", "4598", "4599", "4601", "4604", "4605", "4610", "4612", "4614", "4615", "4616", "4617", "4622", "4625", "4626", "4630", "4631", "4632", "4633", "4635", "4636", "4637", "4638", "4639", "4640", "4641", "4642", "4645", "4646", "4647", "4648", "4650", "4651", "4655", "4657", "4658", "4659", "4660", "4662", "4664", "4665", "4671", "4672", "4674", "4676", "4677", "4678", "4679", "4681", "4682", "4683", "4684", "4685", "4686", "4688", "4689", "4690", "4696", "4698", "4699", "4706", "4709", "4712", "4720", "4721", "4723", "4725", "4730", "4731", "4733", "4734", "4735", "4737", "4738", "4746", "4747", "4751", "4752", "4754", "4755", "4758", "4759", "4761", "4762", "4764", "4765", "4768", "4772", "4773", "4774", "4775", "4778", "4779", "4780", "4782", "4783", "4784", "4785", "4787", "4789", "4790", "4792", "4795", "4796", "4797", "4804", "4805", "4806", "4807", "4808", "4813", "4815", "4817", "4821", "4822", "4825", "4829", "4831", "4832", "4834", "4836", "4837", "4838", "4840", "4842", "4843", "4846", "4850", "4851", "4852", "4853", "4855", "4856", "4857", "4858", "4860", "4861", "4864", "4865", "4867", "4868", "4869", "4870", "4872", "4874", "4878", "4881", "4882", "4883", "4884", "4887", "4888", "4890", "4893", "4896", "4901", "4904", "4905", "4911", "4913", "4914", "4916", "4918", "4920", "4924", "4925", "4927", "4928", "4929", "4930", "4931", "4933", "4934", "4935", "4936", "4937", "4938", "4940", "4943", "4945", "4947", "4949", "4951", "4953", "4954", "4957", "4958", "4959", "4962", "4963", "4964", "4965", "4966", "4967", "4971", "4973", "4974", "4979", "4981", "4985", "4988", "4992", "4993", "4994", "4995", "5000", "5004", "5006", "5008", "5009", "5011", "5012", "5017", "5019", "5020", "5021", "5022", "5023", "5025", "5026", "5028", "5029", "5033", "5034", "5035", "5037", "5041", "5043", "5044", "5045", "5057", "5061", "5064", "5066", "5068", "5069", "5070", "5071", "5072", "5073", "5076", "5079", "5081", "5083", "5088", "5089", "5090", "5091", "5092", "5096", "5098", "5100", "5105", "5109", "5111", "5114", "5116", "5120", "5121", "5122", "5125", "5127", "5129", "5137", "5138", "5139", "5141", "5144", "5146", "5149", "5151", "5152", "5153", "5155", "5156", "5157", "5159", "5160", "5161", "5166", "5171", "5173", "5178", "5181", "5183", "5185", "5188", "5189", "5191", "5196", "5197", "5199", "5200", "5203", "5206", "5211", "5214", "5216", "5218", "5219", "5221", "5222", "5223", "5224", "5225", "5233", "5234", "5237", "5238", "5240", "5242", "5244", "5250", "5252", "5254", "5258", "5263", "5264", "5272", "5276", "5277", "5278", "5284", "5286", "5288", "5289", "5291", "5292", "5294", "5297", "5298", "5302", "5304", "5305", "5307", "5308", "5314", "5316", "5318", "5320", "5321", "5324", "5328", "5329", "5333", "5336", "5340", "5341", "5342", "5343", "5344", "5345", "5348", "5349", "5353", "5354", "5356", "5357", "5358", "5361", "5362", "5363", "5367", "5369", "5372", "5374", "5375", "5379", "5380", "5381", "5382", "5383", "5384", "5386", "5387", "5388", "5392", "5393", "5394", "5395", "5398", "5399", "5401", "5403", "5408", "5410", "5411", "5412", "5413", "5414", "5416", "5417", "5418", "5420", "5422", "5423", "5426", "5427", "5428", "5430", "5431", "5432", "5433", "5436", "5438", "5443", "5449", "5452", "5454", "5455", "5457", "5458", "5459", "5460", "5461", "5462", "5463", "5464", "5465", "5466", "5468", "5469", "5470", "5472", "5473", "5480", "5481", "5483", "5484", "5485", "5488", "5490", "5491", "5492", "5495", "5496", "5498", "5499", "5504", "5508", "5509", "5510", "5511", "5517", "5523", "5524", "5526", "5530", "5531", "5535", "5538", "5540", "5541", "5542", "5543", "5544", "5548", "5550", "5552", "5555", "5556", "5557", "5560", "5562", "5563", "5564", "5570", "5571", "5573", "5574", "5576", "5577", "5579", "5580", "5581", "5583", "5584", "5585", "5587", "5591", "5592", "5593", "5594", "5595", "5597", "5598", "5599", "5600", "5602", "5603", "5604", "5605", "5608", "5610", "5612", "5613", "5619", "5621", "5622", "5629", "5630", "5631", "5632", "5633", "5636", "5637", "5641", "5642", "5643", "5646", "5650", "5651", "5652", "5654", "5655", "5656", "5658", "5660", "5661", "5662", "5664", "5665", "5666", "5668", "5669", "5670", "5671", "5672", "5673", "5674", "5675", "5677", "5680", "5681", "5682", "5684", "5685", "5687", "5689", "5690", "5692", "5693", "5694", "5696", "5702", "5707", "5708", "5710", "5712", "5714", "5715", "5718", "5720", "5724", "5725", "5727", "5728", "5729", "5730", "5735", "5736", "5737", "5738", "5740", "5748", "5749", "5750", "5753", "5756", "5757", "5758", "5759", "5760", "5762", "5765", "5767", "5774", "5777", "5778", "5779", "5783", "5786", "5787", "5790", "5791", "5793", "5797", "5800", "5801", "5802", "5803", "5805", "5806", "5807", "5808", "5809", "5810", "5811", "5817", "5820", "5823", "5825", "5828", "5829", "5831", "5832", "5833", "5836", "5837", "5838", "5839", "5841", "5843", "5845", "5848", "5851", "5857", "5858", "5859", "5860", "5861", "5862", "5863", "5867", "5868", "5869", "5870", "5871", "5873", "5875", "5878", "5879", "5883", "5884", "5885", "5886", "5887", "5890", "5892", "5897", "5899", "5900", "5903", "5908", "5910", "5911", "5912", "5913", "5916", "5919", "5922", "5923", "5927", "5928", "5932", "5936", "5938", "5939", "5940", "5942", "5945", "5948", "5949", "5951", "5952", "5953", "5954", "5956", "5959", "5961", "5964", "5965", "5968", "5969", "5970", "5972", "5974", "5975", "5977", "5978", "5979", "5983", "5984", "5986", "5991", "5992", "5993", "5994", "5995", "5996", "5997", "6000", "6001", "6003", "6004", "6005", "6006", "6007", "6010", "6012", "6014", "6015", "6017", "6018", "6020", "6021", "6022", "6024", "6026", "6027", "6029", "6031", "6032", "6034", "6036", "6042", "6044", "6045", "6048", "6049", "6051", "6053", "6054", "6055", "6056", "6057", "6060", "6061", "6068", "6069", "6070", "6072", "6073", "6075", "6077", "6080", "6081", "6084", "6086", "6090", "6095", "6096", "6098", "6100", "6101", "6102", "6103", "6104", "6108", "6109", "6110", "6113", "6114", "6115", "6116", "6117", "6119", "6125", "6127", "6128", "6129", "6133", "6134", "6136", "6143", "6144", "6148", "6150", "6151", "6156", "6157", "6158", "6159", "6160", "6162", "6164", "6168", "6169", "6170", "6171", "6172", "6173", "6174", "6175", "6176", "6177", "6179", "6180", "6182", "6183", "6185", "6187", "6189", "6191", "6193", "6194", "6197", "6198", "6199", "6201", "6202", "6204", "6205", "6206", "6207", "6209", "6211", "6213", "6215", "6218", "6219", "6220", "6221", "6222", "6223", "6224", "6226", "6229", "6230", "6233", "6234", "6236", "6237", "6238", "6239", "6242", "6243", "6245", "6247", "6248", "6252", "6259", "6260", "6261", "6263", "6265", "6266", "6269", "6270", "6273", "6277", "6280", "6285", "6286", "6287", "6288", "6289", "6290", "6295", "6296", "6297", "6299", "6302", "6303", "6308", "6310", "6313", "6317", "6318", "6320", "6322", "6323", "6324", "6325", "6327", "6328", "6329", "6330", "6331", "6333", "6336", "6337", "6338", "6342", "6343", "6344", "6345", "6347", "6349", "6351", "6352", "6353", "6358", "6359", "6361", "6362", "6365", "6368", "6371", "6372", "6373", "6375", "6377", "6378", "6379", "6380", "6382", "6383", "6384", "6387", "6389", "6391", "6393", "6394", "6395", "6398", "6399", "6402", "6404", "6409", "6410", "6411", "6412", "6415", "6417", "6418", "6420", "6421", "6423", "6425", "6426", "6430", "6433", "6434", "6435", "6437", "6438", "6439", "6440", "6442", "6444", "6447", "6448", "6449", "6450", "6453", "6455", "6457", "6458", "6459", "6461", "6463", "6465", "6467", "6474", "6476", "6479", "6480", "6481", "6482", "6484", "6486", "6489", "6490", "6493", "6495", "6496", "6498", "6501", "6503", "6505", "6506", "6508", "6510", "6511", "6514", "6515", "6517", "6518", "6519", "6520", "6522", "6524", "6525", "6526", "6531", "6532", "6536", "6538", "6548", "6549", "6551", "6553", "6554", "6556", "6559", "6561", "6562", "6564", "6566", "6571", "6572", "6575", "6577", "6579", "6581", "6584", "6590", "6591", "6592", "6594", "6595", "6598", "6599", "6600", "6601", "6602", "6603", "6604", "6606", "6607", "6610", "6614", "6616", "6620", "6621", "6625", "6627", "6628", "6631", "6632", "6633", "6634", "6640", "6645", "6646", "6647", "6648", "6649", "6651", "6655", "6656", "6657", "6658", "6659", "6660", "6661", "6662", "6663", "6664", "6666", "6671", "6673", "6675", "6676", "6677", "6681", "6683", "6685", "6689", "6690", "6692", "6693", "6694", "6701", "6702", "6703", "6704", "6705", "6706", "6707", "6708", "6710", "6714", "6715", "6716", "6720", "6726", "6728", "6729", "6733", "6734", "6737", "6738", "6739", "6741", "6743", "6744", "6746", "6747", "6748", "6749", "6752", "6753", "6757", "6761", "6762", "6763", "6764", "6765", "6766", "6769", "6770", "6771", "6772", "6773", "6776", "6778", "6783", "6789", "6791", "6792", "6793", "6798", "6799", "6800", "6801", "6802", "6804", "6806", "6807", "6808", "6811", "6818", "6821", "6822", "6823", "6827", "6828", "6830", "6832", "6833", "6834", "6835", "6837", "6838", "6841", "6844", "6848", "6850", "6851", "6852", "6854", "6855", "6856", "6859", "6865", "6866", "6867", "6868", "6871", "6872", "6873", "6875", "6877", "6878", "6879", "6881", "6882", "6883", "6886", "6887", "6889", "6891", "6894", "6895", "6896", "6897", "6900", "6901", "6903", "6905", "6906", "6907", "6908", "6909", "6914", "6916", "6917", "6922", "6923", "6926", "6929", "6930", "6931", "6932", "6936", "6937", "6939", "6940", "6943", "6945", "6946", "6947", "6948", "6949", "6950", "6953", "6954", "6958", "6961", "6962", "6963", "6964", "6965", "6967", "6968", "6969", "6971", "6973", "6974", "6975", "6978", "6983", "6985", "6986", "6990", "6991", "6993", "6996", "6997", "7000", "7001", "7002", "7003", "7005", "7008", "7013", "7014", "7015", "7016", "7017", "7018", "7019", "7021", "7023", "7024", "7027", "7029", "7030", "7031", "7032", "7033", "7036", "7038", "7039", "7040", "7043", "7044", "7045", "7047", "7049", "7051", "7052", "7055", "7060", "7061", "7063", "7068", "7072", "7077", "7080", "7081", "7082", "7083", "7084", "7085", "7088", "7090", "7091", "7093", "7094", "7095", "7098", "7099", "7100", "7103", "7104", "7106", "7109", "7110", "7112", "7117", "7120", "7121", "7122", "7123", "7124", "7125", "7126", "7129", "7131", "7132", "7134", "7135", "7136", "7139", "7142", "7148", "7152", "7153", "7154", "7157", "7158", "7159", "7160", "7161", "7163", "7165", "7166", "7168", "7169", "7173", "7176", "7178", "7179", "7180", "7183", "7184", "7186", "7187", "7188", "7189", "7190", "7192", "7197", "7200", "7202", "7203", "7204", "7205", "7206", "7207", "7212", "7213", "7214", "7216", "7217", "7218", "7221", "7222", "7223", "7224", "7225", "7226", "7227", "7228", "7229", "7231", "7234", "7236", "7237", "7240", "7241", "7243", "7244", "7245", "7250", "7251", "7252", "7253", "7256", "7257", "7259", "7260", "7267", "7270", "7271", "7273", "7274", "7275", "7276", "7278", "7279", "7280", "7281", "7286", "7291", "7292", "7293", "7294", "7298", "7299", "7301", "7304", "7305", "7306", "7307", "7308", "7309", "7312", "7314", "7315", "7316", "7318", "7319", "7320", "7323", "7325", "7327", "7329", "7332", "7334", "7335", "7336", "7338", "7339", "7342", "7343", "7344", "7345", "7346", "7348", "7350", "7351", "7354", "7355", "7356", "7359", "7361", "7363", "7364", "7365", "7366", "7368", "7369", "7371", "7373", "7375", "7376", "7377", "7378", "7382", "7384", "7387", "7389", "7390", "7393", "7394", "7397", "7400", "7403", "7404", "7406", "7411", "7414", "7415", "7416", "7418", "7421", "7424", "7427", "7429", "7431", "7433", "7434", "7435", "7438", "7439", "7441", "7447", "7450", "7457", "7458", "7465", "7467", "7474", "7475", "7476", "7477", "7480", "7481", "7485", "7486", "7488", "7489", "7492", "7497", "7500", "7502", "7503", "7505", "7509", "7511", "7512", "7516", "7517", "7519", "7520", "7521", "7523", "7524", "7531", "7534", "7535", "7537", "7541", "7542", "7544", "7548", "7553", "7554", "7557", "7558", "7559", "7561", "7562", "7565", "7568", "7572", "7574", "7575", "7576", "7577", "7579", "7584", "7585", "7587", "7589", "7592", "7595", "7596", "7597", "7599", "7600", "7601", "7602", "7603", "7605", "7608", "7612", "7613", "7617", "7618", "7620", "7624", "7629", "7632", "7633", "7634", "7638", "7642", "7643", "7647", "7648", "7649", "7651", "7653", "7655", "7657", "7659", "7664", "7665", "7666", "7670", "7671", "7672", "7674", "7675", "7677", "7679", "7680", "7683", "7685", "7686", "7692", "7694", "7695", "7696", "7698", "7700", "7701", "7702", "7705", "7708", "7711", "7713", "7714", "7715", "7718", "7725", "7726", "7727", "7730", "7731", "7733", "7734", "7736", "7739", "7741", "7742", "7743", "7746", "7750", "7753", "7755", "7760", "7761", "7762", "7767", "7769", "7771", "7772", "7773", "7774", "7775", "7776", "7779", "7783", "7784", "7785", "7786", "7788", "7789", "7790", "7793", "7799", "7800", "7801", "7802", "7804", "7806", "7807", "7810", "7811", "7812", "7816", "7819", "7820", "7821", "7824", "7825", "7829", "7832", "7833", "7834", "7841", "7843", "7844", "7846", "7849", "7850", "7852", "7854", "7856", "7857", "7860", "7864", "7866", "7867", "7868", "7869", "7871", "7873", "7875", "7876", "7877", "7879", "7881", "7882", "7883", "7884", "7885", "7886", "7887", "7892", "7895", "7899", "7902", "7904", "7906", "7907", "7908", "7910", "7912", "7921", "7922", "7924", "7928", "7930", "7938", "7942", "7943", "7944", "7945", "7948", "7951", "7952", "7956", "7957", "7958", "7960", "7962", "7963", "7969", "7970", "7971", "7972", "7977", "7978", "7979", "7980", "7981", "7982", "7985", "7986", "7988", "7989", "7990", "7995", "7996", "7997", "8000", "8001", "8003", "8004", "8006", "8009", "8011", "8014", "8015", "8016", "8017", "8018", "8019", "8020", "8022", "8024", "8027", "8030", "8033", "8038", "8039", "8044", "8047", "8050", "8052", "8054", "8055", "8056", "8059", "8060", "8062", "8067", "8069", "8070", "8072", "8075", "8076", "8077", "8082", "8085", "8086", "8089", "8090", "8091", "8092", "8094", "8095", "8096", "8098", "8099", "8100", "8103", "8105", "8106", "8111", "8116", "8118", "8120", "8122", "8125", "8126", "8131", "8132", "8141", "8142", "8143", "8146", "8147", "8148", "8149", "8150", "8152", "8153", "8156", "8157", "8159", "8161", "8163", "8164", "8165", "8167", "8168", "8169", "8170", "8174", "8175", "8180", "8182", "8183", "8188", "8189", "8190", "8191", "8193", "8196", "8202", "8203", "8204", "8205", "8208", "8217", "8218", "8219", "8220", "8221", "8222", "8225", "8226", "8227", "8228", "8231", "8232", "8233", "8234", "8236", "8237", "8238", "8242", "8243", "8244", "8245", "8248", "8249", "8250", "8251", "8254", "8256", "8260", "8261", "8262", "8265", "8267", "8269", "8272", "8273", "8274", "8281", "8282", "8283", "8284", "8289", "8290", "8291", "8292", "8295", "8300", "8301", "8302", "8307", "8308", "8310", "8311", "8313", "8314", "8317", "8318", "8321", "8322", "8323", "8326", "8327", "8329", "8330", "8331", "8335", "8337", "8342", "8343", "8344", "8346", "8347", "8348", "8349", "8351", "8352", "8353", "8354", "8357", "8358", "8361", "8362", "8365", "8366", "8367", "8370", "8371", "8374", "8376", "8377", "8378", "8380", "8381", "8383", "8385", "8387", "8388", "8389", "8390", "8393", "8399", "8400", "8401", "8403", "8406", "8409", "8410", "8411", "8412", "8413", "8418", "8421", "8425", "8427", "8431", "8432", "8433", "8438", "8440", "8441", "8442", "8443", "8444", "8446", "8448", "8450", "8453", "8455", "8456", "8457", "8458", "8459", "8461", "8462", "8463", "8464", "8468", "8469", "8470", "8472", "8474", "8475", "8476", "8477", "8479", "8480", "8481", "8482", "8489", "8491", "8492", "8493", "8494", "8497", "8498", "8499", "8501", "8502", "8504", "8506", "8507", "8508", "8510", "8513", "8515", "8517", "8519", "8520", "8526", "8528", "8529", "8530", "8532", "8533", "8534", "8536", "8539", "8540", "8543", "8545", "8546", "8547", "8549", "8551", "8552", "8555", "8557", "8560", "8563", "8565", "8566", "8569", "8570", "8571", "8575", "8577", "8578", "8579", "8581", "8582", "8584", "8585", "8588", "8589", "8592", "8599", "8601", "8603", "8604", "8606", "8607", "8609", "8611", "8620", "8621", "8623", "8624", "8628", "8633", "8634", "8637", "8638", "8640", "8641", "8642", "8643", "8644", "8647", "8648", "8651", "8653", "8655", "8656", "8657", "8659", "8663", "8664", "8665", "8666", "8667", "8668", "8669", "8672", "8674", "8675", "8680", "8681", "8683", "8684", "8686", "8687", "8688", "8690", "8691", "8692", "8693", "8696", "8697", "8699", "8700", "8703", "8705", "8707", "8709", "8711", "8716", "8718", "8719", "8721", "8724", "8725", "8726", "8727", "8728", "8732", "8734", "8735", "8737", "8739", "8742", "8745", "8747", "8748", "8751", "8753", "8754", "8755", "8757", "8760", "8761", "8762", "8764", "8765", "8766", "8767", "8768", "8769", "8771", "8774", "8775", "8776", "8777", "8780", "8781", "8785", "8787", "8789", "8791", "8792", "8794", "8795", "8796", "8798", "8800", "8801", "8804", "8805", "8807", "8808", "8810", "8811", "8817", "8819", "8821", "8823", "8824", "8825", "8827", "8830", "8834", "8835", "8837", "8838", "8840", "8842", "8845", "8848", "8850", "8851", "8853", "8855", "8856", "8860", "8861", "8862", "8864", "8867", "8870", "8872", "8874", "8875", "8878", "8881", "8883", "8885", "8887", "8888", "8889", "8891", "8892", "8893", "8896", "8898", "8899", "8900", "8902", "8903", "8904", "8905", "8906", "8907", "8914", "8916", "8918", "8921", "8922", "8923", "8924", "8926", "8931", "8934", "8935", "8937", "8938", "8941", "8942", "8943", "8947", "8949", "8952", "8953", "8954", "8955", "8957", "8958", "8959", "8961", "8962", "8963", "8965", "8966", "8970", "8972", "8973", "8975", "8976", "8977", "8978", "8979", "8980", "8981", "8985", "8986", "8987", "8988", "8989", "8990", "8991", "8993", "8998", "8999", "9001", "9002", "9003", "9009", "9010", "9011", "9015", "9016", "9019", "9022", "9024", "9025", "9026", "9027", "9030", "9032", "9033", "9035", "9036", "9037", "9039", "9043", "9046", "9049", "9050", "9052", "9057", "9058", "9063", "9064", "9065", "9066", "9067", "9068", "9069", "9071", "9073", "9075", "9078", "9079", "9080", "9081", "9082", "9086", "9088", "9090", "9092", "9095", "9096", "9097", "9098", "9102", "9103", "9108", "9112", "9113", "9120", "9122", "9123", "9125", "9128", "9129", "9130", "9132", "9133", "9137", "9140", "9143", "9145", "9146", "9147", "9149", "9153", "9154", "9157", "9158", "9159", "9163", "9164", "9166", "9167", "9168", "9171", "9172", "9174", "9175", "9176", "9177", "9178", "9179", "9181", "9182", "9184", "9188", "9193", "9194", "9195", "9197", "9198", "9199", "9200", "9202", "9203", "9205", "9206", "9210", "9212", "9216", "9220", "9221", "9222", "9224", "9225", "9227", "9229", "9232", "9234", "9240", "9242", "9243", "9245", "9247", "9251", "9253", "9254", "9256", "9257", "9260", "9262", "9263", "9264", "9265", "9266", "9268", "9269", "9271", "9272", "9274", "9275", "9279", "9280", "9282", "9283", "9284", "9286", "9288", "9289", "9290", "9291", "9294", "9295", "9296", "9297", "9298", "9301", "9302", "9304", "9305", "9307", "9309", "9311", "9312", "9313", "9315", "9316", "9318", "9319", "9320", "9321", "9322", "9323", "9324", "9332", "9333", "9334", "9338", "9339", "9341", "9345", "9346", "9347", "9348", "9349", "9350", "9352", "9353", "9354", "9355", "9357", "9359", "9360", "9362", "9363", "9366", "9367", "9371", "9373", "9376", "9377", "9378", "9381", "9383", "9384", "9385", "9386", "9389", "9390", "9394", "9395", "9398", "9403", "9404", "9405", "9406", "9409", "9414", "9415", "9416", "9418", "9419", "9424", "9425", "9426", "9428", "9430", "9431", "9432", "9433", "9434", "9435", "9436", "9437", "9442", "9443", "9445", "9447", "9449", "9450", "9452", "9453", "9454", "9456", "9458", "9459", "9461", "9465", "9466", "9467", "9468", "9469", "9470", "9471", "9472", "9473", "9474", "9475", "9478", "9480", "9481", "9482", "9483", "9486", "9488", "9491", "9492", "9493", "9494", "9499", "9500", "9504", "9505", "9511", "9513", "9515", "9518", "9521", "9524", "9525", "9527", "9528", "9531", "9532", "9533", "9534", "9535", "9536", "9537", "9539", "9541", "9545", "9548", "9549", "9550", "9551", "9552", "9553", "9554", "9556", "9558", "9559", "9560", "9562", "9563", "9566", "9567", "9570", "9572", "9573", "9574", "9576", "9578", "9579", "9580", "9581", "9582", "9583", "9585", "9586", "9587", "9588", "9591", "9594", "9595", "9596", "9597", "9598", "9599", "9600", "9601", "9603", "9606", "9607", "9609", "9610", "9611", "9612", "9614", "9616", "9619", "9622", "9623", "9625", "9629", "9631", "9632", "9637", "9639", "9641", "9645", "9647", "9651", "9653", "9654", "9655", "9659", "9664", "9665", "9668", "9670", "9671", "9672", "9674", "9675", "9679", "9680", "9682", "9685", "9688", "9690", "9693", "9694", "9697", "9700", "9701", "9702", "9704", "9705", "9706", "9707", "9711", "9713", "9714", "9715", "9716", "9717", "9718", "9719", "9720", "9721", "9723", "9724", "9729", "9732", "9733", "9734", "9736", "9738", "9740", "9741", "9742", "9745", "9746", "9747", "9748", "9752", "9759", "9760", "9763", "9764", "9767", "9768", "9769", "9772", "9775", "9778", "9779", "9780", "9782", "9785", "9787", "9788", "9789", "9790", "9792", "9795", "9796", "9798", "9800", "9801", "9805", "9807", "9809", "9813", "9814", "9815", "9818", "9819", "9821", "9828", "9829", "9831", "9835", "9836", "9837", "9838", "9839", "9840", "9841", "9846", "9851", "9852", "9853", "9854", "9860", "9861", "9865", "9867", "9870", "9872", "9874", "9878", "9879", "9881", "9883", "9884", "9885", "9887", "9889", "9891", "9892", "9893", "9894", "9895", "9896", "9897", "9905", "9906", "9908", "9911", "9912", "9913", "9914", "9916", "9917", "9920", "9927", "9929", "9933", "9934", "9936", "9938", "9942", "9944", "9945", "9946", "9947", "9949", "9950", "9955", "9963", "9966", "9967", "9970", "9971", "9976", "9978", "9979", "9983", "9984", "9985", "9986", "9987", "9988", "9990", "9994", "9995", "9996", "9999", "10003", "10005", "10006", "10007", "10011", "10015", "10016", "10021", "10024", "10027", "10029", "10030", "10033", "10034", "10036", "10037", "10038", "10039", "10040", "10042", "10047", "10050", "10055", "10058", "10063", "10064", "10065", "10066", "10069", "10072", "10075", "10076", "10077", "10078", "10079", "10084", "10085", "10088", "10089", "10091", "10095", "10096", "10098", "10099", "10100", "10103", "10104", "10108", "10110", "10111", "10112", "10113", "10115", "10120", "10123", "10124", "10125", "10128", "10131", "10135", "10138", "10139", "10140", "10141", "10142", "10144", "10146", "10148", "10149", "10150", "10151", "10152", "10154", "10155", "10156", "10157", "10161", "10165", "10167", "10168", "10169", "10174", "10175", "10176", "10177", "10179", "10180", "10181", "10182", "10183", "10184", "10187", "10189", "10190", "10191", "10192", "10197", "10205", "10208", "10209", "10213", "10215", "10218", "10221", "10222", "10223", "10224", "10225", "10227", "10228", "10230", "10231", "10232", "10233", "10234", "10236", "10237", "10238", "10239", "10240", "10243", "10244", "10246", "10249", "10250", "10254", "10259", "10261", "10263", "10264", "10265", "10266", "10267", "10272", "10273", "10275", "10278", "10281", "10282", "10283", "10284", "10286", "10287", "10289", "10290", "10292", "10293", "10295", "10296", "10297", "10299", "10301", "10302", "10303", "10306", "10307", "10308", "10310", "10311", "10313", "10314", "10316", "10317", "10318", "10319", "10321", "10322", "10324", "10325", "10326", "10327", "10328", "10329", "10330", "10333", "10335", "10336", "10338", "10339", "10340", "10341", "10343", "10345", "10346", "10347", "10348", "10349", "10351", "10357", "10358", "10359", "10362", "10365", "10366", "10367", "10368", "10369", "10370", "10371", "10373", "10375", "10377", "10378", "10379", "10381", "10382", "10384", "10385", "10386", "10387", "10388", "10389", "10391", "10392", "10393", "10394", "10397", "10398", "10400", "10401", "10402", "10404", "10407", "10408", "10410", "10411", "10412", "10413", "10414", "10418", "10421", "10425", "10426", "10429", "10430", "10431", "10432", "10439", "10441", "10442", "10445", "10447", "10451", "10452", "10454", "10462", "10464", "10465", "10466", "10467", "10469", "10471", "10473", "10475", "10481", "10484", "10486", "10488", "10490", "10491", "10492", "10497", "10498", "10500", "10501", "10502", "10503", "10504", "10505", "10506", "10508", "10510", "10512", "10514", "10516", "10518", "10519", "10520", "10521", "10527", "10529", "10531", "10533", "10534", "10536", "10539", "10543", "10545", "10546", "10547", "10548", "10550", "10551", "10552", "10553", "10554", "10555", "10556", "10559", "10561", "10564", "10566", "10570", "10571", "10573", "10574", "10575", "10576", "10577", "10578", "10581", "10583", "10585", "10587", "10589", "10592", "10594", "10595", "10596", "10597", "10598", "10599", "10600", "10602", "10603", "10606", "10611", "10617", "10618", "10620", "10624", "10626", "10633", "10634", "10636", "10637", "10638", "10639", "10642", "10643", "10646", "10647", "10652", "10653", "10654", "10655", "10658", "10661", "10662", "10668", "10669", "10675", "10679", "10682", "10683", "10684", "10687", "10689", "10691", "10693", "10694", "10696", "10697", "10698", "10699", "10702", "10703", "10704", "10711", "10712", "10713", "10715", "10717", "10720", "10721", "10723", "10725", "10726", "10728", "10730", "10731", "10732", "10733", "10734", "10737", "10738", "10739", "10740", "10741", "10743", "10746", "10747", "10748", "10749", "10750", "10751", "10752", "10756", "10760", "10761", "10763", "10768", "10769", "10770", "10774", "10775", "10777", "10779", "10780", "10782", "10783", "10784", "10785", "10787", "10789", "10790", "10796", "10797", "10799", "10800", "10801", "10804", "10808", "10809", "10812", "10817", "10823", "10825", "10828", "10830", "10831", "10836", "10837", "10839", "10840", "10843", "10844", "10845", "10847", "10850", "10853", "10854", "10857", "10858", "10861", "10862", "10863", "10866", "10868", "10869", "10871", "10872", "10873", "10875", "10876", "10878", "10880", "10888", "10891", "10892", "10894", "10895", "10896", "10897", "10903", "10905", "10906", "10907", "10908", "10909", "10912", "10913", "10916", "10917", "10918", "10923", "10925", "10926", "10927", "10929", "10931", "10933", "10934", "10936", "10940", "10941", "10943", "10944", "10945", "10948", "10951", "10953", "10954", "10957", "10961", "10962", "10967", "10968", "10969", "10970", "10974", "10975", "10980", "10982", "10983", "10984", "10986", "10988", "10990", "10991", "10992", "10995", "11002", "11003", "11006", "11007", "11008", "11010", "11013", "11014", "11015", "11016", "11017", "11018", "11020", "11024", "11027", "11029", "11030", "11033", "11036", "11037", "11040", "11041", "11046", "11050", "11052", "11053", "11054", "11055", "11056", "11057", "11060", "11061", "11062", "11063", "11064", "11070", "11071", "11072", "11073", "11075", "11076", "11077", "11078", "11079", "11082", "11084", "11085", "11087", "11088", "11089", "11095", "11096", "11097", "11099", "11102", "11103", "11108", "11109", "11110", "11112", "11113", "11114", "11116", "11117", "11118", "11121", "11122", "11123", "11125", "11126", "11127", "11129", "11131", "11132", "11133", "11137", "11139", "11155", "11156", "11158", "11164", "11165", "11166", "11170", "11173", "11175", "11176", "11178", "11179", "11180", "11182", "11183", "11186", "11187", "11188", "11189", "11190", "11191", "11193", "11194", "11196", "11197", "11198", "11199", "11201", "11203", "11206", "11207", "11208", "11211", "11213", "11214", "11215", "11216", "11219", "11220", "11223", "11224", "11229", "11231", "11234", "11235", "11236", "11237", "11240", "11241", "11242", "11244", "11245", "11246", "11247", "11249", "11250", "11256", "11258", "11261", "11262", "11263", "11265", "11266", "11268", "11269", "11271", "11273", "11274", "11275", "11277", "11282", "11286", "11288", "11289", "11290", "11292", "11293", "11295", "11297", "11299", "11302", "11308", "11314", "11315", "11316", "11317", "11319", "11320", "11321", "11323", "11326", "11327", "11328", "11329", "11330", "11331", "11335", "11337", "11338", "11340", "11341", "11342", "11345", "11349", "11350", "11351", "11352", "11355", "11358", "11360", "11361", "11363", "11370", "11372", "11373", "11374", "11375", "11379", "11386", "11387", "11389", "11392", "11393", "11394", "11396", "11398", "11399", "11400", "11401", "11402", "11404", "11410", "11411", "11416", "11419", "11422", "11424", "11426", "11429", "11430", "11433", "11434", "11435", "11437", "11438", "11440", "11442", "11444", "11445", "11447", "11448", "11450", "11451", "11453", "11455", "11457", "11458", "11460", "11463", "11464", "11474", "11475", "11476", "11480", "11481", "11482", "11483", "11485", "11487", "11488", "11492", "11498", "11503", "11504", "11506", "11507", "11510", "11511", "11515", "11517", "11520", "11523", "11525", "11527", "11532", "11534", "11535", "11537", "11541", "11544", "11545", "11551", "11552", "11555", "11556", "11557", "11559", "11560", "11564", "11565", "11566", "11570", "11574", "11581", "11585", "11587", "11588", "11589", "11590", "11592", "11593", "11594", "11595", "11597", "11599", "11601", "11603", "11607", "11608", "11610", "11611", "11613", "11614", "11616", "11618", "11623", "11627", "11629", "11630", "11632", "11633", "11634", "11635", "11637", "11647", "11650", "11651", "11652", "11656", "11657", "11658", "11662", "11666", "11667", "11670", "11675", "11676", "11677", "11680", "11683", "11685", "11687", "11689", "11690", "11692", "11694", "11696", "11697", "11699", "11700", "11704", "11705", "11706", "11707", "11711", "11712", "11713", "11714", "11715", "11716", "11717", "11719", "11724", "11725", "11729", "11731", "11732", "11733", "11740", "11745", "11746", "11748", "11751", "11753", "11758", "11759", "11762", "11764", "11765", "11766", "11767", "11769", "11771", "11773", "11775", "11777", "11779", "11780", "11781", "11782", "11783", "11785", "11786", "11788", "11789", "11791", "11793", "11795", "11796", "11797", "11800", "11805", "11806", "11807", "11808", "11812", "11813", "11814", "11815", "11818", "11819", "11820", "11821", "11825", "11826", "11832", "11833", "11834", "11835", "11837", "11838", "11839", "11841", "11842", "11844", "11846", "11847", "11849", "11850", "11852", "11855", "11856", "11860", "11861", "11862", "11864", "11866", "11867", "11868", "11871", "11872", "11876", "11877", "11878", "11879", "11881", "11886", "11888", "11889", "11891", "11893", "11895", "11897", "11898", "11899", "11902", "11903", "11908", "11910", "11913", "11914", "11917", "11918", "11919", "11922", "11923", "11924", "11925", "11930", "11932", "11933", "11934", "11936", "11937", "11939", "11941", "11942", "11943", "11944", "11946", "11948", "11949", "11950", "11951", "11953", "11955", "11956", "11959", "11960", "11963", "11966", "11967", "11970", "11971", "11972", "11973", "11974", "11976", "11978", "11979", "11983", "11984", "11986", "11987", "11992", "11993", "11994", "11996", "11997", "11999", "12004", "12005", "12006", "12007", "12008", "12009", "12013", "12014", "12020", "12021", "12022", "12023", "12026", "12030", "12031", "12033", "12034", "12035", "12037", "12038", "12044", "12045", "12047", "12048", "12052", "12054", "12055", "12061", "12063", "12065", "12066", "12067", "12068", "12069", "12070", "12071", "12076", "12078", "12081", "12083", "12085", "12088", "12089", "12090", "12092", "12093", "12100", "12102", "12103", "12104", "12105", "12109", "12110", "12111", "12112", "12113", "12115", "12121", "12122", "12123", "12124", "12137", "12141", "12142", "12144", "12147", "12149", "12151", "12154", "12155", "12156", "12158", "12159", "12160", "12161", "12163", "12165", "12168", "12171", "12174", "12175", "12176", "12177", "12183", "12186", "12188", "12189", "12191", "12196", "12199", "12200", "12201", "12204", "12205", "12207", "12208", "12212", "12214", "12215", "12216", "12217", "12218", "12219", "12220", "12223", "12226", "12228", "12229", "12231", "12232", "12239", "12241", "12245", "12247", "12248", "12252", "12255", "12259", "12261", "12262", "12263", "12265", "12266", "12267", "12268", "12278", "12280", "12283", "12287", "12289", "12290", "12291", "12292", "12294", "12295", "12297", "12300", "12302", "12303", "12304", "12305", "12309", "12310", "12311", "12312", "12313", "12317", "12318", "12320", "12322", "12324", "12326", "12328", "12330", "12331", "12332", "12334", "12335", "12338", "12340", "12343", "12344", "12345", "12347", "12349", "12351", "12355", "12361", "12362", "12363", "12366", "12368", "12369", "12372", "12373", "12376", "12378", "12380", "12381", "12383", "12387", "12388", "12389", "12390", "12391", "12394", "12397", "12399", "12403", "12404", "12405", "12406", "12407", "12408", "12409", "12410", "12412", "12413", "12414", "12415", "12417", "12420", "12422", "12423", "12424", "12426", "12427", "12432", "12433", "12434", "12435", "12436", "12437", "12438", "12439", "12440", "12442", "12444", "12448", "12449", "12455", "12458", "12460", "12461", "12462", "12464", "12465", "12466", "12470", "12477", "12478", "12481", "12483", "12489", "12491", "12492", "12493", "12494", "12496", "12497", "12500", "12503", "12504", "12505", "12506", "12507", "12508", "12509", "12510", "12512", "12514", "12515", "12516", "12518", "12519", "12521", "12522", "12524", "12525", "12529", "12536", "12537", "12538", "12542", "12543", "12545", "12546", "12548", "12550", "12552", "12554", "12556", "12557", "12562", "12563", "12565", "12566", "12567", "12570", "12572", "12573", "12574", "12575", "12576", "12580", "12581", "12582", "12583", "12586", "12593", "12594", "12595", "12597", "12598", "12599", "12600", "12602", "12605", "12607", "12608", "12609", "12612", "12613", "12617", "12618", "12620", "12622", "12623", "12625", "12626", "12627", "12628", "12630", "12631", "12634", "12636", "12638", "12640", "12643", "12650", "12653", "12654", "12656", "12657", "12658", "12660", "12662", "12664", "12668", "12669", "12671", "12676", "12678", "12680", "12682", "12683", "12686", "12688", "12690", "12693", "12694", "12695", "12697", "12698", "12701", "12703", "12706", "12708", "12709", "12711", "12714", "12719", "12721", "12723", "12724", "12725", "12726", "12727", "12732", "12734", "12735", "12736", "12737", "12738", "12741", "12742", "12743", "12748", "12750", "12753", "12754", "12755", "12756", "12757", "12759", "12760", "12762", "12763", "12764", "12766", "12768", "12773", "12774", "12775", "12776", "12777", "12778", "12781", "12783", "12784", "12785", "12786", "12788", "12790", "12792", "12794", "12797", "12807", "12810", "12814", "12815", "12818", "12819", "12820", "12822", "12826", "12827", "12828", "12829", "12833", "12835", "12836", "12838", "12840", "12841", "12842", "12848", "12849", "12851", "12852", "12854", "12855", "12856", "12857", "12858", "12859", "12860", "12862", "12866", "12868", "12871", "12873", "12874", "12875", "12876", "12877", "12881", "12884", "12892", "12895", "12896", "12899", "12900", "12901", "12902", "12903", "12904", "12906", "12907", "12915", "12916", "12917", "12920", "12921", "12922", "12923", "12927", "12934", "12938", "12941", "12945", "12947", "12948", "12949", "12953", "12955", "12956", "12958", "12961", "12963", "12964", "12967", "12968", "12971", "12972", "12973", "12979", "12980", "12984", "12990", "12991", "12993", "12994", "12995", "12998", "12999", "13000", "13002", "13005", "13006", "13007", "13009", "13013", "13014", "13016", "13020", "13021", "13022", "13029", "13031", "13032", "13034", "13035", "13036", "13040", "13043", "13044", "13049", "13050", "13051", "13053", "13054", "13059", "13061", "13064", "13065", "13068", "13069", "13070", "13072", "13073", "13074", "13075", "13077", "13082", "13086", "13091", "13092", "13093", "13094", "13098", "13099", "13102", "13103", "13105", "13106", "13109", "13110", "13113", "13119", "13120", "13121", "13122", "13123", "13125", "13128", "13129", "13130", "13132", "13135", "13136", "13138", "13139", "13140", "13141", "13144", "13145", "13150", "13153", "13154", "13156", "13157", "13159", "13161", "13165", "13166", "13167", "13170", "13173", "13177", "13178", "13179", "13180", "13183", "13188", "13191", "13192", "13194", "13197", "13198", "13199", "13203", "13204", "13205", "13210", "13213", "13215", "13216", "13218", "13219", "13222", "13223", "13225", "13226", "13228", "13229", "13230", "13233", "13234", "13235", "13236", "13239", "13241", "13242", "13245", "13246", "13248", "13251", "13253", "13255", "13257", "13260", "13261", "13262", "13263", "13264", "13265", "13268", "13271", "13272", "13273", "13275", "13281", "13282", "13283", "13285", "13287", "13291", "13294", "13298", "13299", "13302", "13304", "13305", "13306", "13309", "13311", "13312", "13314", "13315", "13316", "13319", "13320", "13322", "13323", "13325", "13326", "13327", "13329", "13332", "13333", "13335", "13336", "13340", "13342", "13343", "13344", "13345", "13348", "13350", "13352", "13353", "13354", "13355", "13356", "13357", "13359", "13360", "13363", "13364", "13365", "13366", "13367", "13368", "13369", "13373", "13375", "13380", "13383", "13385", "13389", "13393", "13397", "13398", "13400", "13401", "13403", "13404", "13405", "13406", "13409", "13411", "13412", "13413", "13414", "13415", "13418", "13420", "13421", "13423", "13428", "13440", "13443", "13444", "13446", "13447", "13453", "13457", "13459", "13461", "13464", "13465", "13466", "13467", "13468", "13469", "13470", "13471", "13478", "13479", "13487", "13490", "13491", "13494", "13497", "13498", "13505", "13508", "13510", "13512", "13513", "13515", "13516", "13517", "13518", "13520", "13524", "13525", "13531", "13532", "13533", "13534", "13535", "13536", "13541", "13542", "13546", "13547", "13548", "13549", "13550", "13554", "13555", "13556", "13559", "13562", "13563", "13564", "13577", "13578", "13579", "13580", "13581", "13582", "13583", "13584", "13585", "13588", "13591", "13593", "13597", "13598", "13603", "13605", "13606", "13607", "13608", "13609", "13611", "13612", "13613", "13614", "13616", "13617", "13618", "13619", "13620", "13621", "13622", "13624", "13625", "13630", "13632", "13633", "13636", "13644", "13647", "13648", "13649", "13651", "13652", "13655", "13659", "13662", "13663", "13668", "13669", "13670", "13671", "13676", "13677", "13678", "13679", "13681", "13684", "13687", "13688", "13689", "13691", "13693", "13694", "13696", "13697", "13699", "13700", "13701", "13703", "13705", "13706", "13707", "13708", "13709", "13711", "13713", "13717", "13719", "13721", "13724", "13725", "13727", "13728", "13729", "13736", "13737", "13738", "13739", "13740", "13741", "13742", "13743", "13746", "13749", "13750", "13752", "13753", "13754", "13755", "13757", "13760", "13764", "13765", "13766", "13767", "13771", "13772", "13773", "13775", "13776", "13780", "13781", "13782", "13783", "13784", "13787", "13793", "13794", "13796", "13797", "13798", "13799", "13801", "13802", "13804", "13806", "13807", "13809", "13810", "13814", "13815", "13816", "13817", "13818", "13820", "13823", "13825", "13827", "13829", "13833", "13838", "13839", "13840", "13841", "13842", "13844", "13845", "13850", "13851", "13852", "13855", "13856", "13858", "13859", "13860", "13862", "13863", "13864", "13865", "13867", "13869", "13872", "13873", "13874", "13876", "13880", "13881", "13882", "13883", "13884", "13886", "13887", "13888", "13890", "13891", "13897", "13900", "13901", "13902", "13903", "13905", "13906", "13909", "13912", "13913", "13914", "13919", "13920", "13921", "13923", "13926", "13929", "13931", "13933", "13934", "13935", "13937", "13938", "13939", "13941", "13943", "13945", "13947", "13950", "13951", "13952", "13954", "13955", "13957", "13958", "13959", "13963", "13964", "13966", "13968", "13969", "13970", "13971", "13972", "13974", "13975", "13979", "13981", "13982", "13983", "13985", "13986", "13987", "13989", "13991", "13992", "13996", "13998", "14000", "14002", "14003", "14006", "14007", "14009", "14012", "14015", "14017", "14019", "14022", "14023", "14027", "14028", "14029", "14032", "14033", "14034", "14036", "14038", "14039", "14041", "14046", "14047", "14050", "14052", "14054", "14055", "14057", "14058", "14059", "14064", "14066", "14067", "14070", "14077", "14078", "14079", "14081", "14082", "14083", "14084", "14086", "14091", "14092", "14093", "14094", "14097", "14101", "14102", "14103", "14105", "14107", "14109", "14110", "14111", "14114", "14115", "14116", "14118", "14119", "14124", "14126", "14129", "14131", "14135", "14136", "14137", "14138", "14140", "14142", "14143", "14144", "14146", "14147", "14150", "14152", "14153", "14154", "14155", "14156", "14157", "14162", "14163", "14165", "14166", "14167", "14168", "14172", "14175", "14176", "14180", "14181", "14183", "14184", "14185", "14189", "14191", "14193", "14194", "14195", "14196", "14197", "14198", "14199", "14200", "14202", "14203", "14205", "14206", "14207", "14209", "14210", "14211", "14212", "14213", "14215", "14216", "14217", "14219", "14221", "14222", "14230", "14232", "14234", "14237", "14239", "14241", "14242", "14244", "14247", "14248", "14252", "14254", "14256", "14257", "14259", "14262", "14263", "14264", "14267", "14269", "14271", "14272", "14277", "14281", "14283", "14284", "14285", "14287", "14288", "14290", "14291", "14292", "14294", "14297", "14301", "14303", "14304", "14305", "14306", "14307", "14309", "14313", "14315", "14318", "14320", "14322", "14323", "14324", "14325", "14333", "14334", "14335", "14339", "14342", "14343", "14346", "14347", "14348", "14350", "14351", "14354", "14360", "14363", "14370", "14375", "14377", "14378", "14379", "14381", "14383", "14384", "14387", "14389", "14390", "14392", "14395", "14397", "14398", "14400", "14401", "14403", "14404", "14405", "14407", "14408", "14409", "14410", "14415", "14416", "14417", "14419", "14420", "14421", "14423", "14424", "14427", "14429", "14430", "14431", "14432", "14434", "14436", "14438", "14442", "14446", "14447", "14450", "14451", "14452", "14454", "14464", "14473", "14477", "14479", "14480", "14481", "14482", "14483", "14484", "14486", "14488", "14491", "14495", "14496", "14498", "14503", "14504", "14505", "14506", "14509", "14524", "14525", "14532", "14533", "14537", "14541", "14545", "14546", "14547", "14548", "14549", "14550", "14556", "14562", "14566", "14567", "14570", "14571", "14572", "14576", "14577", "14579", "14582", "14584", "14585", "14586", "14587", "14588", "14590", "14595", "14596", "14597", "14598", "14600", "14601", "14602", "14605", "14612", "14613", "14616", "14619", "14620", "14623", "14624", "14628", "14630", "14637", "14641", "14642", "14643", "14645", "14646", "14647", "14649", "14652", "14654", "14656", "14660", "14663", "14665", "14669", "14670", "14671", "14673", "14674", "14675", "14676", "14677", "14678", "14680", "14681", "14682", "14685", "14687", "14689", "14691", "14692", "14693", "14698", "14702", "14703", "14704", "14705", "14707", "14711", "14713", "14715", "14717", "14718", "14719", "14720", "14724", "14729", "14730", "14731", "14732", "14745", "14746", "14749", "14751", "14753", "14754", "14755", "14757", "14758", "14759", "14763", "14766", "14767", "14769", "14770", "14774", "14775", "14779", "14785", "14787", "14788", "14789", "14790", "14792", "14795", "14796", "14797", "14798", "14799", "14800", "14803", "14806", "14807", "14808", "14809", "14811", "14818", "14820", "14821", "14823", "14826", "14829", "14833", "14835", "14836", "14838", "14839", "14840", "14841", "14843", "14845", "14846", "14849", "14852", "14855", "14856", "14857", "14858", "14860", "14861", "14863", "14865", "14868", "14870", "14871", "14872", "14873", "14875", "14877", "14879", "14881", "14888", "14890", "14892", "14893", "14894", "14896", "14901", "14902", "14903", "14904", "14906", "14907", "14909", "14910", "14911", "14913", "14915", "14918", "14919", "14921", "14922", "14923", "14924", "14927", "14929", "14931", "14932", "14934", "14935", "14937", "14938", "14940", "14944", "14946", "14950", "14951", "14952", "14953", "14956", "14958", "14959", "14962", "14964", "14967", "14969", "14970", "14972", "14973", "14974", "14975", "14976", "14977", "14978", "14981", "14982", "14983", "14985", "14989", "14991", "14992", "14993", "14994", "14995", "14997", "14998", "14999", "15000", "15002", "15005", "15006", "15007", "15008", "15010", "15013", "15015", "15018", "15019", "15020", "15022", "15023", "15026", "15031", "15032", "15035", "15039", "15043", "15045", "15048", "15050", "15051", "15055", "15056", "15057", "15058", "15060", "15063", "15071", "15072", "15074", "15076", "15077", "15078", "15079", "15080", "15082", "15084", "15085", "15086", "15087", "15089", "15090", "15092", "15094", "15096", "15099", "15101", "15102", "15108", "15109", "15114", "15116", "15117", "15118", "15119", "15120", "15121", "15122", "15125", "15127", "15128", "15138", "15139", "15140", "15142", "15146", "15148", "15150", "15154", "15164", "15165", "15168", "15171", "15172", "15174", "15180", "15183", "15185", "15187", "15188", "15189", "15192", "15193", "15194", "15197", "15199", "15202", "15203", "15205", "15210", "15214", "15215", "15219", "15221", "15224", "15225", "15226", "15227", "15231", "15234", "15235", "15239", "15240", "15241", "15243", "15246", "15247", "15248", "15252", "15254", "15256", "15257", "15258", "15259", "15262", "15263", "15266", "15272", "15274", "15275", "15278", "15280", "15282", "15284", "15290", "15293", "15295", "15296", "15297", "15298", "15299", "15300", "15303", "15304", "15306", "15307", "15309", "15310", "15311", "15312", "15315", "15320", "15324", "15331", "15333", "15337", "15340", "15342", "15344", "15345", "15347", "15348", "15350", "15351", "15352", "15353", "15355", "15359", "15360", "15361", "15363", "15364", "15365", "15366", "15368", "15369", "15371", "15372", "15373", "15375", "15377", "15378", "15380", "15381", "15383", "15384", "15385", "15386", "15389", "15390", "15395", "15396", "15398", "15400", "15402", "15403", "15404", "15406", "15408", "15409", "15411", "15414", "15415", "15418", "15423", "15425", "15428", "15430", "15432", "15434", "15435", "15438", "15439", "15440", "15441", "15443", "15445", "15446", "15447", "15449", "15450", "15455", "15456", "15457", "15462", "15463", "15465", "15467", "15468", "15470", "15471", "15473", "15477", "15478", "15480", "15481", "15482", "15484", "15485", "15489", "15493", "15497", "15498", "15499", "15500", "15502", "15505", "15509", "15512", "15519", "15521", "15523", "15524", "15526", "15530", "15531", "15536", "15537", "15539", "15540", "15542", "15544", "15546", "15548", "15550", "15556", "15558", "15560", "15561", "15563", "15569", "15570", "15572", "15574", "15575", "15576", "15577", "15578", "15583", "15584", "15588", "15590", "15592", "15593", "15594", "15595", "15598", "15602", "15603", "15606", "15608", "15611", "15612", "15615", "15616", "15617", "15618", "15621", "15622", "15623", "15626", "15627", "15628", "15629", "15631", "15634", "15635", "15638", "15640", "15641", "15643", "15644", "15648", "15651", "15653", "15654", "15656", "15659", "15662", "15663", "15665", "15667", "15668", "15669", "15672", "15673", "15677", "15678", "15680", "15683", "15684", "15687", "15689", "15690", "15695", "15696", "15697", "15698", "15699", "15701", "15702", "15704", "15705", "15710", "15711", "15716", "15717", "15721", "15722", "15723", "15725", "15726", "15727", "15728", "15729", "15731", "15733", "15734", "15736", "15738", "15742", "15743", "15744", "15745", "15746", "15750", "15751", "15752", "15755", "15757", "15758", "15759", "15762", "15765", "15769", "15770", "15773", "15774", "15775", "15776", "15777", "15778", "15780", "15782", "15789", "15790", "15791", "15792", "15793", "15795", "15799", "15801", "15804", "15805", "15808", "15809", "15810", "15811", "15812", "15814", "15816", "15818", "15819", "15820", "15821", "15822", "15825", "15828", "15829", "15830", "15834", "15835", "15838", "15840", "15842", "15843", "15845", "15848", "15851", "15853", "15855", "15860", "15863", "15865", "15868", "15869", "15871", "15872", "15873", "15874", "15879", "15881", "15883", "15885", "15886", "15888", "15889", "15891", "15894", "15896", "15899", "15905", "15910", "15911", "15912", "15917", "15919", "15920", "15921", "15929", "15930", "15933", "15935", "15942", "15943", "15944", "15945", "15946", "15951", "15954", "15957", "15958", "15962", "15964", "15966", "15967", "15968", "15969", "15971", "15972", "15977", "15981", "15982", "15984", "15985", "15987", "15988", "15990", "15994", "15996", "15999", "16000", "16004", "16006", "16007", "16011", "16014", "16015", "16017", "16019", "16022", "16026", "16028", "16029", "16032", "16035", "16036", "16038", "16041", "16046", "16051", "16054", "16059", "16060", "16062", "16064", "16067", "16069", "16073", "16074", "16076", "16077", "16079", "16083", "16084", "16087", "16088", "16092", "16093", "16094", "16095", "16098", "16099", "16102", "16103", "16104", "16105", "16107", "16109", "16111", "16113", "16117", "16118", "16119", "16120", "16122", "16126", "16129", "16131", "16132", "16133", "16135", "16138", "16141", "16144", "16146", "16149", "16150", "16153", "16159", "16160", "16161", "16164", "16165", "16166", "16171", "16173", "16174", "16176", "16177", "16179", "16182", "16184", "16187", "16190", "16193", "16195", "16196", "16198", "16200", "16202", "16203", "16205", "16207", "16212", "16213", "16214", "16217", "16220", "16221", "16222", "16223", "16224", "16226", "16229", "16230", "16231", "16233", "16236", "16238", "16241", "16242", "16244", "16245", "16246", "16247", "16250", "16252", "16253", "16255", "16257", "16258", "16260", "16261", "16265", "16267", "16268", "16272", "16277", "16280", "16281", "16283", "16284", "16286", "16288", "16290", "16295", "16296", "16297", "16298", "16301", "16302", "16305", "16307", "16317", "16319", "16324", "16327", "16328", "16330", "16331", "16332", "16336", "16337", "16338", "16342", "16343", "16345", "16354", "16355", "16356", "16358", "16361", "16366", "16368", "16369", "16370", "16371", "16372", "16377", "16379", "16380", "16381", "16384", "16389", "16390", "16391", "16392", "16393", "16394", "16395", "16396", "16399", "16400", "16404", "16405", "16407", "16409", "16410", "16411", "16414", "16418", "16422", "16425", "16426", "16427", "16428", "16430", "16432", "16434", "16435", "16436", "16437", "16438", "16442", "16444", "16445", "16446", "16447", "16449", "16450", "16451", "16456", "16458", "16461", "16464", "16466", "16473", "16480", "16481", "16482", "16483", "16484", "16486", "16487", "16489", "16490", "16491", "16492", "16494", "16495", "16497", "16498", "16501", "16502", "16504", "16507", "16508", "16509", "16511", "16513", "16514", "16516", "16518", "16519", "16520", "16521", "16525", "16529", "16533", "16539", "16540", "16542", "16543", "16547", "16549", "16551", "16554", "16557", "16560", "16561", "16562", "16564", "16566", "16568", "16570", "16571", "16572", "16573", "16578", "16582", "16583", "16586", "16587", "16589", "16590", "16593", "16595", "16598", "16602", "16603", "16607", "16608", "16609", "16614", "16619", "16620", "16621", "16622", "16623", "16625", "16628", "16629", "16630", "16632", "16637", "16638", "16639", "16641", "16643", "16644", "16645", "16646", "16647", "16649", "16650", "16652", "16654", "16661", "16662", "16665", "16669", "16671", "16672", "16673", "16678", "16679", "16680", "16682", "16684", "16685", "16686", "16688", "16690", "16695", "16697", "16698", "16703", "16705", "16707", "16708", "16709", "16717", "16718", "16719", "16721", "16722", "16723", "16726", "16728", "16731", "16732", "16733", "16737", "16738", "16739", "16740", "16741", "16742", "16743", "16744", "16746", "16747", "16748", "16750", "16751", "16752", "16753", "16754", "16756", "16757", "16758", "16759", "16762", "16763", "16765", "16766", "16770", "16771", "16774", "16776", "16779", "16783", "16788", "16790", "16791", "16792", "16793", "16794", "16796", "16797", "16798", "16800", "16804", "16805", "16808", "16809", "16811", "16812", "16813", "16814", "16815", "16817", "16818", "16823", "16826", "16829", "16830", "16831", "16832", "16833", "16834", "16838", "16842", "16843", "16844", "16850", "16855", "16857", "16858", "16865", "16867", "16868", "16870", "16872", "16873", "16874", "16876", "16877", "16884", "16885", "16886", "16889", "16890", "16891", "16895", "16896", "16897", "16899", "16900", "16903", "16904", "16905", "16908", "16909", "16913", "16915", "16916", "16917", "16918", "16919", "16922", "16923", "16925", "16927", "16928", "16929", "16930", "16931", "16932", "16934", "16935", "16936", "16937", "16943", "16944", "16946", "16951", "16954", "16955", "16956", "16957", "16959", "16960", "16962", "16963", "16968", "16969", "16970", "16971", "16972", "16978", "16980", "16981", "16983", "16984", "16987", "16989", "16990", "16995", "16996", "16997", "16999", "17000", "17001", "17008", "17010", "17011", "17016", "17018", "17019", "17021", "17025", "17026", "17027", "17030", "17031", "17037", "17038", "17039", "17040", "17042", "17046", "17048", "17049", "17050", "17056", "17058", "17062", "17064", "17067", "17072", "17078", "17082", "17083", "17084", "17085", "17087", "17088", "17090", "17095", "17097", "17100", "17103", "17107", "17108", "17110", "17112", "17113", "17115", "17120", "17121", "17123", "17124", "17126", "17127", "17129", "17130", "17131", "17132", "17134", "17137", "17139", "17142", "17143", "17148", "17149", "17153", "17155", "17158", "17160", "17161", "17162", "17164", "17165", "17167", "17169", "17171", "17173", "17176", "17177", "17180", "17181", "17184", "17185", "17186", "17189", "17192", "17194", "17195", "17197", "17199", "17204", "17207", "17209", "17211", "17212", "17214", "17217", "17221", "17222", "17223", "17226", "17227", "17228", "17229", "17230", "17232", "17236", "17237", "17238", "17241", "17243", "17244", "17248", "17250", "17252", "17253", "17254", "17255", "17261", "17262", "17264", "17266", "17268", "17270", "17273", "17274", "17275", "17277", "17278", "17280", "17281", "17282", "17283", "17284", "17285", "17290", "17293", "17294", "17296", "17298", "17307", "17311", "17314", "17316", "17318", "17321", "17322", "17323", "17325", "17326", "17329", "17330", "17331", "17333", "17334", "17336", "17337", "17339", "17340", "17341", "17342", "17343", "17344", "17347", "17348", "17351", "17353", "17354", "17355", "17357", "17358", "17360", "17363", "17366", "17367", "17369", "17371", "17373", "17374", "17376", "17377", "17379", "17380", "17383", "17384", "17385", "17386", "17387", "17388", "17389", "17394", "17395", "17396", "17400", "17402", "17404", "17405", "17406", "17408", "17409", "17410", "17411", "17413", "17418", "17427", "17429", "17432", "17433", "17437", "17439", "17441", "17444", "17445", "17446", "17447", "17448", "17450", "17451", "17452", "17453", "17455", "17456", "17458", "17459", "17461", "17462", "17464", "17466", "17468", "17470", "17472", "17473", "17476", "17477", "17478", "17481", "17483", "17484", "17487", "17491", "17493", "17494", "17495", "17503", "17504", "17507", "17513", "17514", "17515", "17516", "17518", "17519", "17522", "17523", "17524", "17527", "17535", "17537", "17540", "17541", "17542", "17543", "17544", "17546", "17552", "17553", "17555", "17557", "17560", "17561", "17574", "17575", "17576", "17577", "17579", "17582", "17585", "17586", "17588", "17589", "17591", "17592", "17594", "17596", "17600", "17601", "17605", "17606", "17607", "17610", "17611", "17612", "17614", "17616", "17618", "17619", "17623", "17624", "17625", "17629", "17630", "17631", "17636", "17639", "17645", "17647", "17649", "17652", "17654", "17655", "17662", "17663", "17666", "17668", "17671", "17673", "17674", "17676", "17679", "17680", "17681", "17682", "17684", "17685", "17687", "17688", "17689", "17692", "17696", "17698", "17699", "17703", "17704", "17705", "17706", "17709", "17710", "17711", "17712", "17717", "17718", "17720", "17724", "17729", "17730", "17731", "17738", "17740", "17741", "17743", "17744", "17746", "17752", "17754", "17755", "17756", "17758", "17763", "17764", "17765", "17766", "17767", "17768", "17770", "17772", "17774", "17778", "17779", "17780", "17782", "17785", "17787", "17788", "17789", "17793", "17795", "17796", "17804", "17805", "17807", "17808", "17809", "17812", "17815", "17816", "17826", "17828", "17831", "17832", "17836", "17843", "17844", "17851", "17853", "17856", "17857", "17859", "17861", "17863", "17866", "17870", "17871", "17873", "17877", "17878", "17879", "17881", "17882", "17889", "17890", "17891", "17894", "17896", "17898", "17899", "17900", "17905", "17908", "17910", "17911", "17913", "17914", "17915", "17916", "17917", "17918", "17921", "17922", "17923", "17925", "17927", "17932", "17933", "17934", "17935", "17941", "17942", "17943", "17944", "17946", "17953", "17956", "17957", "17959", "17962", "17963", "17965", "17967", "17969", "17970", "17971", "17973", "17974", "17975", "17978", "17979", "17981", "17982", "17985", "17987", "17988", "17992", "17993", "17996", "17997", "18001", "18002", "18003", "18004", "18005", "18007", "18008", "18013", "18015", "18021", "18022", "18025", "18026", "18027", "18028", "18029", "18030", "18031", "18036", "18039", "18040", "18042", "18043", "18044", "18045", "18047", "18049", "18050", "18052", "18055", "18058", "18061", "18062", "18063", "18064", "18065", "18066", "18067", "18068", "18070", "18071", "18073", "18077", "18078", "18080", "18082", "18086", "18087", "18088", "18089", "18090", "18091", "18092", "18093", "18094", "18096", "18097", "18098", "18099", "18100", "18102", "18104", "18105", "18106", "18111", "18112", "18113", "18114", "18119", "18121", "18125", "18129", "18131", "18132", "18133", "18136", "18137", "18138", "18140", "18142", "18144", "18145", "18146", "18147", "18148", "18152", "18153", "18154", "18158", "18159", "18160", "18162", "18165", "18167", "18169", "18171", "18174", "18176", "18180", "18181", "18182", "18183", "18184", "18189", "18191", "18192", "18193", "18196", "18201", "18203", "18205", "18208", "18211", "18212", "18213", "18214", "18215", "18216", "18218", "18219", "18226", "18232", "18233", "18236", "18237", "18238", "18240", "18242", "18243", "18244", "18245", "18247", "18248", "18251", "18252", "18253", "18255", "18256", "18257", "18259", "18262", "18265", "18268", "18270", "18271", "18272", "18275", "18281", "18282", "18283", "18285", "18288", "18290", "18292", "18295", "18296", "18297", "18298", "18300", "18301", "18302", "18303", "18304", "18305", "18306", "18308", "18310", "18313", "18314", "18318", "18325", "18327", "18330", "18332", "18333", "18335", "18337", "18338", "18339", "18340", "18341", "18343", "18344", "18345", "18349", "18352", "18354", "18355", "18356", "18359", "18361", "18362", "18364", "18365", "18366", "18369", "18372", "18373", "18375", "18379", "18383", "18384", "18386", "18390", "18392", "18393", "18395", "18396", "18397", "18398", "18399", "18401", "18404", "18405", "18407", "18408", "18409", "18416", "18418", "18423", "18429", "18430", "18436", "18438", "18439", "18441", "18443", "18444", "18448", "18450", "18451", "18452", "18453", "18454", "18455", "18457", "18458", "18461", "18464", "18465", "18466", "18468", "18473", "18475", "18478", "18484", "18485", "18487", "18488", "18489", "18490", "18491", "18492", "18494", "18495", "18496", "18500", "18505", "18506", "18508", "18510", "18511", "18512", "18514", "18516", "18517", "18518", "18521", "18522", "18523", "18524", "18525", "18526", "18527", "18532", "18533", "18534", "18536", "18539", "18543", "18546", "18549", "18550", "18551", "18552", "18555", "18558", "18559", "18560", "18563", "18565", "18566", "18567", "18569", "18570", "18572", "18574", "18575", "18577", "18579", "18582", "18583", "18584", "18586", "18587", "18590", "18591", "18600", "18602", "18603", "18605", "18606", "18608", "18610", "18612", "18614", "18615", "18616", "18619", "18621", "18623", "18627", "18631", "18634", "18635", "18636", "18637", "18641", "18643", "18645", "18647", "18648", "18652", "18653", "18654", "18656", "18657", "18659", "18660", "18662", "18663", "18665", "18666", "18667", "18672", "18673", "18677", "18678", "18679", "18680", "18682", "18684", "18685", "18686", "18687", "18689", "18690", "18694", "18695", "18698", "18703", "18704", "18705", "18708", "18709", "18710", "18716", "18717", "18718", "18719", "18723", "18725", "18727", "18729", "18731", "18732", "18733", "18734", "18735", "18736", "18737", "18740", "18741", "18742", "18743", "18746", "18754", "18756", "18760", "18763", "18773", "18774", "18778", "18779", "18782", "18783", "18785", "18786", "18790", "18792", "18794", "18796", "18798", "18799", "18801", "18803", "18807", "18809", "18810", "18812", "18814", "18815", "18817", "18820", "18825", "18826", "18827", "18828", "18829", "18831", "18832", "18833", "18836", "18840", "18842", "18844", "18847", "18852", "18853", "18854", "18855", "18856", "18857", "18859", "18860", "18861", "18865", "18866", "18867", "18868", "18869", "18871", "18872", "18873", "18876", "18877", "18878", "18879", "18881", "18882", "18885", "18886", "18888", "18891", "18896", "18899", "18903", "18904", "18905", "18906", "18912", "18913", "18914", "18915", "18916", "18918", "18920", "18921", "18922", "18923", "18924", "18925", "18927", "18928", "18932", "18933", "18938", "18941", "18942", "18944", "18946", "18947", "18949", "18953", "18954", "18957", "18960", "18962", "18965", "18967", "18972", "18974", "18976", "18978", "18980", "18985", "18993", "18995", "18997", "18998", "19001", "19003", "19006", "19008", "19009", "19011", "19013", "19015", "19016", "19018", "19019", "19020", "19021", "19022", "19023", "19026", "19027", "19030", "19033", "19034", "19036", "19040", "19044", "19045", "19046", "19047", "19054", "19055", "19059", "19060", "19061", "19062", "19063", "19066", "19067", "19069", "19071", "19072", "19073", "19075", "19077", "19079", "19082", "19083", "19084", "19085", "19097", "19101", "19102", "19105", "19107", "19108", "19110", "19111", "19113", "19114", "19116", "19118", "19119", "19122", "19124", "19125", "19126", "19132", "19133", "19135", "19136", "19138", "19139", "19141", "19142", "19144", "19148", "19150", "19151", "19152", "19153", "19154", "19157", "19158", "19159", "19161", "19162", "19163", "19165", "19167", "19168", "19170", "19171", "19173", "19174", "19175", "19177", "19180", "19181", "19182", "19187", "19190", "19191", "19193", "19194", "19203", "19204", "19205", "19206", "19208", "19211", "19212", "19215", "19216", "19219", "19220", "19222", "19223", "19224", "19225", "19229", "19230", "19231", "19233", "19234", "19236", "19238", "19239", "19241", "19243", "19244", "19245", "19246", "19247", "19248", "19249", "19250", "19253", "19255", "19257", "19259", "19263", "19265", "19267", "19268", "19269", "19270", "19271", "19277", "19280", "19282", "19284", "19286", "19287", "19289", "19292", "19293", "19294", "19295", "19297", "19298", "19303", "19304", "19307", "19310", "19311", "19312", "19313", "19314", "19315", "19316", "19317", "19318", "19322", "19324", "19325", "19326", "19327", "19329", "19332", "19334", "19335", "19338", "19340", "19341", "19342", "19346", "19347", "19348", "19349", "19352", "19353", "19356", "19359", "19360", "19361", "19364", "19365", "19366", "19367", "19368", "19370", "19371", "19374", "19375", "19376", "19379", "19380", "19382", "19384", "19385", "19387", "19389", "19395", "19396", "19398", "19400", "19403", "19409", "19411", "19412", "19414", "19416", "19418", "19419", "19421", "19422", "19423", "19425", "19427", "19428", "19429", "19430", "19431", "19432", "19433", "19434", "19435", "19437", "19438", "19439", "19440", "19441", "19443", "19444", "19445", "19446", "19450", "19452", "19453", "19454", "19461", "19467", "19468", "19473", "19475", "19477", "19480", "19483", "19488", "19489", "19490", "19492", "19496", "19497", "19498", "19499", "19501", "19502", "19503", "19504", "19508", "19510", "19511", "19514", "19515", "19517", "19521", "19522", "19524", "19527", "19528", "19529", "19531", "19536", "19537", "19540", "19544", "19545", "19548", "19553", "19554", "19555", "19556", "19557", "19558", "19561", "19563", "19565", "19567", "19568", "19571", "19575", "19576", "19578", "19581", "19586", "19587", "19588", "19591", "19592", "19596", "19598", "19599", "19600", "19601", "19603", "19604", "19607", "19608", "19612", "19613", "19614", "19618", "19623", "19624", "19631", "19634", "19635", "19636", "19638", "19639", "19640", "19642", "19643", "19645", "19648", "19649", "19652", "19653", "19654", "19656", "19657", "19658", "19659", "19662", "19664", "19666", "19670", "19671", "19672", "19673", "19675", "19676", "19680", "19681", "19682", "19683", "19685", "19687", "19688", "19689", "19690", "19693", "19694", "19701", "19703", "19704", "19705", "19707", "19710", "19711", "19713", "19715", "19716", "19717", "19718", "19719", "19720", "19721", "19722", "19723", "19726", "19728", "19729", "19730", "19733", "19734", "19736", "19737", "19740", "19741", "19742", "19744", "19745", "19748", "19750", "19751", "19752", "19753", "19755", "19756", "19757", "19758", "19760", "19763", "19764", "19765", "19766", "19768", "19769", "19770", "19771", "19772", "19773", "19774", "19775", "19776", "19777", "19781", "19782", "19785", "19788", "19789", "19790", "19795", "19796", "19797", "19801", "19803", "19805", "19806", "19807", "19808", "19809", "19811", "19812", "19815", "19818", "19821", "19830", "19831", "19838", "19839", "19840", "19842", "19847", "19848", "19849", "19850", "19851", "19852", "19854", "19855", "19858", "19859", "19860", "19863", "19864", "19868", "19871", "19873", "19875", "19878", "19879", "19880", "19882", "19884", "19890", "19892", "19893", "19895", "19896", "19897", "19898", "19899", "19900", "19901", "19902", "19905", "19906", "19907", "19908", "19911", "19915", "19916", "19917", "19918", "19919", "19921", "19922", "19923", "19926", "19928", "19930", "19933", "19935", "19936", "19939", "19941", "19944", "19946", "19947", "19948", "19950", "19951", "19952", "19956", "19957", "19961", "19963", "19964", "19967", "19969", "19971", "19972", "19973", "19975", "19976", "19977", "19978", "19979", "19982", "19983", "19984", "19985", "19986", "19987", "19988", "19989", "19991", "19993", "19994", "19995", "19997", "19998", "19999", "20001", "20003", "20005", "20006", "20009", "20010", "20011", "20013", "20014", "20015", "20017", "20018", "20019", "20023", "20024", "20025", "20026", "20027", "20029", "20030", "20032", "20033", "20034", "20036", "20037", "20039", "20042", "20044", "20045", "20046", "20048", "20050", "20055", "20056", "20059", "20063", "20064", "20065", "20066", "20068", "20070", "20071", "20072", "20073", "20074", "20076", "20077", "20079", "20080", "20081", "20083", "20084", "20085", "20089", "20091", "20093", "20095", "20096", "20097", "20102", "20109", "20112", "20113", "20114", "20115", "20118", "20119", "20121", "20123", "20124", "20125", "20126", "20127", "20128", "20130", "20131", "20137", "20141", "20142", "20143", "20145", "20152", "20153", "20155", "20156", "20158", "20159", "20160", "20161", "20163", "20164", "20167", "20168", "20169", "20171", "20173", "20174", "20175", "20182", "20183", "20185", "20186", "20192", "20193", "20194", "20196", "20199", "20200", "20201", "20204", "20209", "20212", "20213", "20214", "20215", "20216", "20217", "20218", "20220", "20222", "20223", "20224", "20226", "20230", "20232", "20233", "20234", "20237", "20238", "20239", "20240", "20241", "20242", "20243", "20244", "20246", "20247", "20250", "20253", "20254", "20256", "20258", "20262", "20263", "20267", "20268", "20271", "20273", "20274", "20275", "20279", "20281", "20282", "20284", "20286", "20287", "20290", "20292", "20294", "20297", "20299", "20301", "20303", "20305", "20309", "20310", "20315", "20317", "20318", "20321", "20322", "20323", "20324", "20325", "20326", "20330", "20333", "20334", "20338", "20341", "20343", "20347", "20352", "20357", "20358", "20360", "20361", "20363", "20365", "20367", "20372", "20380", "20381", "20382", "20383", "20385", "20389", "20394", "20396", "20397", "20399", "20405", "20407", "20409", "20410", "20412", "20416", "20417", "20418", "20421", "20424", "20428", "20429", "20431", "20434", "20436", "20437", "20438", "20439", "20441", "20442", "20444", "20446", "20447", "20448", "20451", "20452", "20453", "20456", "20457", "20460", "20462", "20465", "20466", "20469", "20471", "20472", "20473", "20475", "20476", "20479", "20480", "20482", "20491", "20493", "20494", "20495", "20496", "20497", "20499", "20500", "20501", "20503", "20507", "20508", "20509", "20510", "20511", "20512", "20514", "20515", "20517", "20519", "20527", "20528", "20532", "20533", "20535", "20536", "20538", "20540", "20545", "20546", "20547", "20548", "20549", "20551", "20552", "20554", "20556", "20558", "20565", "20567", "20570", "20571", "20572", "20574", "20575", "20576", "20577", "20582", "20586", "20587", "20588", "20590", "20592", "20593", "20594", "20599", "20603", "20605", "20606", "20608", "20609", "20611", "20616", "20617", "20619", "20621", "20622", "20623", "20625", "20630", "20632", "20634", "20637", "20638", "20639", "20641", "20643", "20646", "20647", "20648", "20650", "20651", "20652", "20653", "20655", "20658", "20661", "20665", "20667", "20669", "20670", "20674", "20676", "20677", "20678", "20680", "20681", "20682", "20687", "20692", "20693", "20697", "20698", "20699", "20700", "20701", "20703", "20705", "20707", "20708", "20709", "20711", "20716", "20717", "20718", "20720", "20722", "20723", "20724", "20733", "20734", "20736", "20737", "20743", "20744", "20745", "20746", "20750", "20752", "20753", "20755", "20756", "20757", "20758", "20759", "20761", "20764", "20765", "20766", "20767", "20770", "20772", "20773", "20774", "20775", "20776", "20778", "20779", "20780", "20781", "20783", "20784", "20785", "20789", "20791", "20792", "20793", "20794", "20797", "20798", "20800", "20802", "20804", "20807", "20808", "20809", "20810", "20812", "20816", "20818", "20819", "20820", "20823", "20825", "20826", "20827", "20828", "20829", "20832", "20833", "20834", "20835", "20836", "20837", "20840", "20841", "20842", "20843", "20844", "20848", "20850", "20853", "20854", "20861", "20862", "20865", "20866", "20869", "20871", "20872", "20875", "20876", "20877", "20880", "20881", "20882", "20883", "20884", "20885", "20886", "20887", "20891", "20895", "20896", "20901", "20903", "20904", "20905", "20906", "20908", "20909", "20910", "20911", "20912", "20914", "20915", "20916", "20918", "20920", "20921", "20923", "20924", "20926", "20928", "20929", "20930", "20931", "20934", "20936", "20937", "20938", "20939", "20941", "20947", "20950", "20952", "20953", "20955", "20956", "20958", "20962", "20963", "20964", "20966", "20968", "20970", "20971", "20979", "20982", "20985", "20986", "20987", "20988", "20990", "20991", "20993", "20995", "20997", "21000", "21001", "21010", "21011", "21012", "21013", "21014", "21016", "21019", "21020", "21025", "21031", "21033", "21035", "21036", "21037", "21041", "21044", "21045", "21046", "21047", "21050", "21051", "21052", "21054", "21055", "21061", "21062", "21063", "21065", "21066", "21067", "21070", "21074", "21076", "21079", "21080", "21081", "21082", "21083", "21085", "21087", "21090", "21091", "21092", "21093", "21094", "21096", "21097", "21099", "21102", "21103", "21105", "21107", "21108", "21109", "21112", "21115", "21117", "21118", "21119", "21120", "21124", "21125", "21126", "21127", "21129", "21131", "21132", "21134", "21135", "21138", "21143", "21145", "21147", "21152", "21153", "21154", "21155", "21156", "21158", "21159", "21162", "21163", "21164", "21165", "21172", "21174", "21176", "21177", "21180", "21182", "21183", "21185", "21186", "21191", "21192", "21196", "21197", "21199", "21201", "21203", "21209", "21210", "21213", "21214", "21215", "21219", "21220", "21222", "21225", "21226", "21228", "21229", "21230", "21233", "21235", "21237", "21238", "21239", "21242", "21243", "21247", "21249", "21251", "21252", "21259", "21261", "21262", "21263", "21265", "21266", "21267", "21271", "21272", "21273", "21275", "21276", "21277", "21278", "21282", "21285", "21286", "21287", "21288", "21289", "21290", "21291", "21292", "21293", "21294", "21295", "21296", "21298", "21300", "21302", "21303", "21306", "21307", "21317", "21318", "21319", "21320", "21322", "21323", "21328", "21332", "21333", "21334", "21335", "21340", "21341", "21344", "21346", "21348", "21349", "21355", "21356", "21357", "21362", "21365", "21366", "21367", "21369", "21370", "21372", "21375", "21377", "21378", "21379", "21380", "21381", "21384", "21389", "21390", "21392", "21393", "21395", "21396", "21400", "21402", "21403", "21405", "21407", "21408", "21409", "21411", "21412", "21415", "21416", "21417", "21418", "21419", "21420", "21421", "21422", "21424", "21426", "21428", "21429", "21430", "21432", "21433", "21434", "21437", "21438", "21439", "21440", "21442", "21447", "21449", "21450", "21452", "21453", "21455", "21457", "21459", "21460", "21464", "21466", "21470", "21471", "21472", "21474", "21478", "21481", "21482", "21484", "21485", "21490", "21491", "21492", "21494", "21495", "21497", "21498", "21499", "21500", "21501", "21502", "21505", "21506", "21507", "21508", "21510", "21511", "21512", "21514", "21515", "21516", "21517", "21522", "21523", "21524", "21527", "21529", "21532", "21534", "21537", "21538", "21539", "21541", "21543", "21545", "21547", "21548", "21551", "21552", "21555", "21557", "21558", "21559", "21560", "21562", "21568", "21569", "21573", "21574", "21581", "21584", "21585", "21586", "21587", "21588", "21589", "21591", "21595", "21596", "21599", "21600", "21601", "21602", "21603", "21605", "21608", "21609", "21610", "21614", "21615", "21617", "21620", "21624", "21625", "21627", "21628", "21635", "21644", "21645", "21647", "21648", "21653", "21654", "21655", "21660", "21661", "21662", "21665", "21666", "21667", "21669", "21670", "21671", "21672", "21674", "21675", "21676", "21677", "21678", "21679", "21680", "21681", "21684", "21688", "21690", "21691", "21692", "21698", "21705", "21707", "21708", "21712", "21713", "21714", "21716", "21717", "21721", "21724", "21725", "21726", "21731", "21737", "21738", "21739", "21741", "21743", "21744", "21746", "21748", "21749", "21754", "21755", "21756", "21757", "21761", "21762", "21763", "21767", "21768", "21769", "21770", "21772", "21775", "21776", "21777", "21779", "21780", "21784", "21785", "21786", "21787", "21789", "21790", "21791", "21792", "21793", "21795", "21796", "21797", "21798", "21801", "21804", "21806", "21808", "21809", "21812", "21816", "21817", "21818", "21819", "21821", "21823", "21824", "21825", "21826", "21827", "21830", "21831", "21833", "21837", "21839", "21841", "21843", "21845", "21846", "21853", "21855", "21856", "21858", "21861", "21863", "21867", "21871", "21872", "21874", "21875", "21878", "21881", "21882", "21886", "21889", "21890", "21891", "21894", "21896", "21897", "21900", "21901", "21903", "21904", "21906", "21907", "21910", "21912", "21917", "21918", "21923", "21924", "21925", "21929", "21930", "21931", "21932", "21935", "21936", "21937", "21940", "21943", "21945", "21946", "21950", "21955", "21957", "21959", "21960", "21961", "21962", "21965", "21966", "21967", "21968", "21970", "21971", "21973", "21974", "21975", "21976", "21980", "21981", "21982", "21983", "21984", "21988", "21989", "21990", "21992", "21993", "21994", "21995", "21998", "22002", "22003", "22004", "22005", "22007", "22008", "22011", "22012", "22015", "22016", "22019", "22021", "22022", "22025", "22027", "22031", "22032", "22034", "22035", "22039", "22040", "22043", "22045", "22047", "22049", "22051", "22053", "22055", "22056", "22057", "22059", "22061", "22064", "22065", "22066", "22068", "22069", "22072", "22076", "22079", "22082", "22083", "22084", "22085", "22088", "22089", "22092", "22094", "22095", "22096", "22097", "22099", "22104", "22108", "22109", "22110", "22114", "22115", "22118", "22120", "22126", "22127", "22128", "22129", "22131", "22133", "22135", "22136", "22137", "22139", "22146", "22148", "22150", "22152", "22154", "22155", "22156", "22157", "22159", "22162", "22165", "22167", "22168", "22171", "22173", "22176", "22177", "22181", "22182", "22185", "22188", "22189", "22190", "22191", "22193", "22194", "22195", "22198", "22204", "22207", "22208", "22210", "22211", "22212", "22214", "22216", "22221", "22227", "22228", "22231", "22232", "22237", "22242", "22244", "22246", "22250", "22252", "22253", "22254", "22257", "22259", "22260", "22262", "22263", "22264", "22265", "22267", "22269", "22270", "22272", "22274", "22275", "22276", "22277", "22278", "22279", "22280", "22282", "22283", "22285", "22291", "22292", "22293", "22296", "22298", "22301", "22302", "22306", "22308", "22309", "22311", "22312", "22314", "22315", "22316", "22317", "22319", "22321", "22322", "22325", "22327", "22328", "22330", "22335", "22337", "22339", "22341", "22343", "22344", "22346", "22347", "22351", "22353", "22361", "22363", "22364", "22365", "22367", "22368", "22369", "22374", "22375", "22376", "22378", "22379", "22382", "22383", "22386", "22387", "22390", "22391", "22393", "22394", "22395", "22404", "22405", "22407", "22413", "22415", "22417", "22418", "22419", "22424", "22426", "22434", "22435", "22436", "22439", "22440", "22441", "22442", "22443", "22444", "22445", "22449", "22451", "22452", "22453", "22456", "22458", "22459", "22460", "22462", "22463", "22465", "22466", "22467", "22469", "22470", "22472", "22474", "22475", "22479", "22480", "22482", "22484", "22485", "22486", "22488", "22489", "22491", "22492", "22495", "22499", "22500", "22501", "22502", "22503", "22505", "22506", "22509", "22511", "22514", "22517", "22518", "22519", "22523", "22525", "22526", "22528", "22529", "22531", "22536", "22537", "22538", "22541", "22544", "22546", "22550", "22551", "22555", "22558", "22560", "22561", "22565", "22568", "22569", "22570", "22572", "22573", "22574", "22577", "22579", "22581", "22582", "22585", "22587", "22588", "22589", "22591", "22593", "22594", "22595", "22597", "22598", "22599", "22602", "22603", "22604", "22608", "22609", "22611", "22612", "22614", "22615", "22617", "22624", "22625", "22627", "22628", "22629", "22631", "22632", "22633", "22638", "22639", "22641", "22644", "22647", "22650", "22651", "22653", "22654", "22655", "22656", "22660", "22662", "22663", "22665", "22666", "22667", "22668", "22669", "22670", "22672", "22673", "22677", "22679", "22680", "22681", "22682", "22686", "22687", "22688", "22689", "22690", "22693", "22694", "22696", "22697", "22699", "22701", "22704", "22706", "22707", "22709", "22714", "22717", "22720", "22726", "22728", "22729", "22731", "22733", "22742", "22745", "22747", "22748", "22751", "22752", "22758", "22759", "22764", "22765", "22766", "22771", "22773", "22774", "22775", "22777", "22780", "22782", "22783", "22787", "22789", "22790", "22792", "22800", "22802", "22803", "22805", "22809", "22810", "22815", "22818", "22820", "22821", "22824", "22825", "22826", "22827", "22828", "22830", "22831", "22832", "22833", "22835", "22838", "22840", "22842", "22843", "22844", "22847", "22848", "22854", "22855", "22856", "22857", "22858", "22863", "22867", "22869", "22872", "22873", "22874", "22875", "22876", "22877", "22878", "22879", "22880", "22886", "22887", "22888", "22890", "22891", "22892", "22896", "22897", "22898", "22900", "22908", "22909", "22910", "22911", "22913", "22915", "22917", "22918", "22919", "22924", "22925", "22926", "22928", "22930", "22931", "22932", "22933", "22939", "22941", "22942", "22943", "22945", "22947", "22949", "22952", "22953", "22954", "22957", "22958", "22960", "22962", "22964", "22967", "22968", "22969", "22973", "22975", "22976", "22980", "22983", "22984", "22987", "22989", "22990", "22992", "22993", "22994", "22997", "22998", "22999", "23001", "23005", "23006", "23007", "23011", "23015", "23017", "23018", "23026", "23029", "23037", "23038", "23039", "23042", "23044", "23045", "23047", "23048", "23052", "23053", "23054", "23057", "23058", "23059", "23062", "23064", "23065", "23070", "23072", "23074", "23075", "23078", "23079", "23080", "23082", "23088", "23089", "23092", "23094", "23095", "23098", "23100", "23101", "23102", "23103", "23105", "23106", "23107", "23108", "23110", "23111", "23113", "23117", "23120", "23122", "23127", "23131", "23132", "23134", "23141", "23142", "23146", "23147", "23149", "23150", "23151", "23154", "23155", "23157", "23164", "23165", "23166", "23167", "23168", "23169", "23171", "23172", "23173", "23174", "23179", "23181", "23183", "23185", "23186", "23188", "23192", "23193", "23194", "23195", "23196", "23197", "23198", "23200", "23201", "23202", "23203", "23204", "23207", "23208", "23210", "23211", "23216", "23217", "23218", "23220", "23226", "23227", "23228", "23231", "23232", "23233", "23237", "23239", "23242", "23244", "23247", "23249", "23251", "23252", "23253", "23255", "23257", "23261", "23264", "23266", "23267", "23268", "23269", "23272", "23273", "23274", "23279", "23280", "23283", "23284", "23291", "23295", "23296", "23299", "23300", "23301", "23306", "23308", "23311", "23316", "23317", "23318", "23319", "23320", "23321", "23322", "23323", "23324", "23326", "23327", "23329", "23330", "23332", "23333", "23336", "23340", "23343", "23344", "23345", "23347", "23348", "23350", "23351", "23352", "23354", "23355", "23358", "23359", "23362", "23363", "23369", "23371", "23372", "23373", "23374", "23375", "23382", "23383", "23384", "23385", "23387", "23389", "23391", "23393", "23394", "23396", "23397", "23400", "23403", "23405", "23408", "23409", "23410", "23411", "23412", "23413", "23417", "23418", "23419", "23424", "23426", "23428", "23431", "23432", "23435", "23438", "23439", "23440", "23441", "23443", "23446", "23447", "23449", "23450", "23452", "23453", "23455", "23457", "23458", "23461", "23463", "23465", "23466", "23468", "23470", "23471", "23474", "23475", "23476", "23477", "23478", "23479", "23480", "23481", "23487", "23489", "23490", "23493", "23499", "23500", "23503", "23505", "23506", "23510", "23511", "23512", "23514", "23515", "23516", "23518", "23519", "23521", "23523", "23526", "23527", "23529", "23531", "23532", "23534", "23536", "23540", "23542", "23544", "23551", "23553", "23555", "23557", "23562", "23568", "23569", "23573", "23574", "23575", "23576", "23578", "23581", "23586", "23587", "23588", "23590", "23597", "23598", "23599", "23600", "23601", "23602", "23604", "23606", "23608", "23611", "23613", "23620", "23622", "23624", "23625", "23632", "23634", "23638", "23644", "23647", "23649", "23651", "23656", "23659", "23660", "23664", "23667", "23668", "23669", "23671", "23672", "23675", "23676", "23684", "23685", "23687", "23690", "23691", "23692", "23694", "23695", "23698", "23701", "23702", "23703", "23706", "23707", "23708", "23711", "23712", "23714", "23715", "23716", "23719", "23722", "23723", "23724", "23725", "23726", "23727", "23728", "23730", "23731", "23732", "23734", "23735", "23736", "23737", "23741", "23748", "23750", "23751", "23752", "23753", "23756", "23757", "23760", "23762", "23763", "23764", "23766", "23767", "23768", "23769", "23775", "23776", "23778", "23780", "23781", "23783", "23785", "23787", "23788", "23789", "23791", "23792", "23795", "23796", "23797", "23798", "23800", "23802", "23803", "23804", "23806", "23807", "23810", "23811", "23814", "23816", "23822", "23823", "23824", "23826", "23827", "23829", "23831", "23832", "23835", "23839", "23840", "23841", "23843", "23844", "23845", "23847", "23849", "23850", "23851", "23852", "23853", "23854", "23857", "23860", "23865", "23866", "23868", "23869", "23871", "23872", "23874", "23875", "23876", "23877", "23879", "23880", "23882", "23886", "23888", "23889", "23890", "23891", "23892", "23894", "23896", "23900", "23901", "23902", "23903", "23904", "23912", "23915", "23916", "23917", "23918", "23919", "23920", "23921", "23923", "23924", "23926", "23929", "23930", "23931", "23933", "23936", "23937", "23938", "23939", "23940", "23943", "23947", "23948", "23951", "23953", "23955", "23956", "23957", "23958", "23960", "23962", "23965", "23969", "23970", "23971", "23972", "23974", "23975", "23977", "23979", "23980", "23981", "23982", "23986", "23991", "23992", "23995", "24000", "24003", "24004", "24006", "24011", "24016", "24021", "24022", "24024", "24026", "24027", "24028", "24030", "24032", "24035", "24037", "24038", "24044", "24046", "24049", "24050", "24051", "24053", "24054", "24055", "24059", "24060", "24061", "24063", "24064", "24067", "24069", "24072", "24075", "24077", "24078", "24079", "24082", "24084", "24086", "24087", "24091", "24099", "24100", "24101", "24102", "24104", "24105", "24106", "24107", "24108", "24110", "24111", "24112", "24113", "24114", "24116", "24117", "24118", "24119", "24121", "24122", "24125", "24127", "24128", "24132", "24134", "24135", "24137", "24139", "24145", "24147", "24148", "24150", "24152", "24153", "24154", "24156", "24158", "24159", "24160", "24164", "24166", "24171", "24172", "24173", "24174", "24176", "24178", "24179", "24180", "24182", "24183", "24185", "24188", "24190", "24191", "24192", "24193", "24196", "24198", "24199", "24204", "24205", "24206", "24208", "24211", "24214", "24216", "24219", "24221", "24230", "24231", "24234", "24235", "24240", "24242", "24243", "24246", "24248", "24249", "24252", "24254", "24255", "24256", "24258", "24260", "24264", "24267", "24268", "24270", "24271", "24275", "24276", "24277", "24278", "24281", "24282", "24283", "24286", "24287", "24288", "24289", "24290", "24291", "24293", "24295", "24298", "24300", "24301", "24305", "24306", "24307", "24309", "24310", "24312", "24313", "24314", "24318", "24320", "24321", "24322", "24327", "24330", "24331", "24333", "24334", "24335", "24341", "24342", "24343", "24344", "24345", "24346", "24349", "24350", "24352", "24353", "24354", "24355", "24357", "24362", "24363", "24365", "24366", "24367", "24368", "24369", "24371", "24372", "24373", "24374", "24375", "24376", "24377", "24378", "24380", "24383", "24386", "24387", "24390", "24391", "24392", "24398", "24400", "24401", "24402", "24404", "24407", "24408", "24409", "24411", "24413", "24416", "24417", "24418", "24422", "24425", "24428", "24430", "24432", "24433", "24434", "24436", "24437", "24438", "24441", "24443", "24446", "24447", "24448", "24449", "24451", "24453", "24456", "24460", "24462", "24463", "24464", "24465", "24466", "24468", "24469", "24470", "24473", "24477", "24478", "24480", "24483", "24485", "24486", "24488", "24489", "24490", "24491", "24492", "24493", "24495", "24496", "24499", "24500", "24501", "24502", "24506", "24510", "24513", "24514", "24515", "24516", "24517", "24519", "24528", "24529", "24531", "24533", "24534", "24535", "24537", "24546", "24552", "24553", "24554", "24555", "24558", "24561", "24562", "24569", "24571", "24572", "24574", "24575", "24576", "24582", "24583", "24585", "24587", "24589", "24591", "24592", "24593", "24594", "24596", "24597", "24599", "24601", "24605", "24606", "24608", "24611", "24613", "24614", "24615", "24616", "24617", "24618", "24619", "24622", "24626", "24628", "24631", "24635", "24637", "24638", "24640", "24643", "24645", "24648", "24650", "24651", "24652", "24653", "24654", "24655", "24658", "24659", "24661", "24662", "24665", "24666", "24668", "24669", "24670", "24674", "24681", "24683", "24687", "24689", "24691", "24692", "24693", "24695", "24697", "24701", "24704", "24705", "24710", "24711", "24713", "24714", "24715", "24718", "24722", "24725", "24727", "24728", "24730", "24732", "24736", "24739", "24740", "24741", "24744", "24745", "24746", "24747", "24748", "24749", "24750", "24751", "24753", "24756", "24762", "24763", "24764", "24766", "24768", "24769", "24770", "24778", "24779", "24780", "24781", "24783", "24784", "24785", "24787", "24799", "24805", "24806", "24808", "24809", "24810", "24812", "24814", "24817", "24819", "24820", "24821", "24824", "24827", "24828", "24829", "24830", "24832", "24835", "24838", "24840", "24843", "24844", "24847", "24850", "24851", "24853", "24854", "24855", "24856", "24860", "24862", "24863", "24865", "24866", "24867", "24870", "24871", "24872", "24874", "24875", "24878", "24879", "24880", "24882", "24885", "24886", "24888", "24889", "24890", "24891", "24892", "24895", "24896", "24897", "24898", "24899", "24900", "24901", "24903", "24904", "24905", "24906", "24907", "24909", "24911", "24912", "24917", "24918", "24919", "24920", "24923", "24924", "24930", "24932", "24933", "24934", "24938", "24939", "24941", "24942", "24943", "24944", "24946", "24948", "24950", "24953", "24955", "24956", "24957", "24960", "24961", "24962", "24965", "24969", "24970", "24971", "24974", "24975", "24976", "24979", "24980", "24982", "24983", "24984", "24986", "24987", "24989", "24990", "24991", "24999", "25004", "25005", "25008", "25010", "25012", "25016", "25017", "25024", "25027", "25028", "25031", "25033", "25034", "25037", "25040", "25042", "25044", "25046", "25047", "25048", "25054", "25055", "25057", "25058", "25059", "25066", "25067", "25069", "25070", "25071", "25078", "25079", "25080", "25081", "25082", "25086", "25089", "25090", "25093", "25094", "25096", "25102", "25104", "25105", "25108", "25111", "25112", "25113", "25114", "25116", "25118", "25121", "25122", "25124", "25126", "25128", "25129", "25130", "25131", "25133", "25138", "25139", "25142", "25143", "25144", "25148", "25151", "25152", "25153", "25154", "25158", "25159", "25160", "25162", "25163", "25164", "25166", "25168", "25170", "25171", "25172", "25173", "25176", "25178", "25179", "25181", "25183", "25187", "25188", "25190", "25194", "25195", "25197", "25198", "25199", "25201", "25203", "25205", "25207", "25208", "25209", "25210", "25211", "25212", "25216", "25223", "25224", "25227", "25231", "25237", "25239", "25240", "25241", "25242", "25243", "25244", "25248", "25249", "25256", "25258", "25259", "25262", "25265", "25268", "25270", "25274", "25276", "25277", "25278", "25282", "25284", "25288", "25290", "25292", "25293", "25299", "25302", "25303", "25305", "25306", "25307", "25310", "25317", "25318", "25319", "25323", "25332", "25337", "25338", "25339", "25340", "25342", "25354", "25358", "25359", "25360", "25364", "25365", "25367", "25368", "25369", "25370", "25371", "25376", "25377", "25378", "25380", "25382", "25386", "25387", "25388", "25389", "25390", "25391", "25393", "25396", "25401", "25402", "25403", "25411", "25413", "25415", "25417", "25419", "25421", "25422", "25423", "25424", "25425", "25428", "25429", "25432", "25433", "25435", "25437", "25438", "25439", "25444", "25448", "25451", "25452", "25456", "25457", "25460", "25463", "25466", "25469", "25470", "25478", "25481", "25482", "25483", "25484", "25485", "25487", "25488", "25489", "25498", "25500", "25501", "25502", "25504", "25505", "25506", "25508", "25509", "25510", "25511", "25516", "25517", "25518", "25519", "25521", "25523", "25525", "25526", "25527", "25528", "25531", "25532", "25533", "25535", "25536", "25537", "25538", "25540", "25541", "25542", "25543", "25547", "25549", "25550", "25551", "25552", "25553", "25558", "25559", "25560", "25561", "25562", "25565", "25573", "25577", "25578", "25580", "25581", "25583", "25587", "25588", "25589", "25590", "25591", "25592", "25595", "25596", "25598", "25600", "25603", "25607", "25609", "25610", "25612", "25615", "25616", "25617", "25626", "25628", "25633", "25634", "25636", "25637", "25639", "25640", "25641", "25645", "25646", "25647", "25648", "25649", "25650", "25651", "25653", "25654", "25655", "25658", "25660", "25662", "25666", "25667", "25669", "25671", "25673", "25674", "25675", "25676", "25679", "25682", "25683", "25685", "25686", "25689", "25690", "25692", "25695", "25698", "25699", "25700", "25701", "25703", "25706", "25708", "25709", "25710", "25711", "25713", "25716", "25718", "25720", "25721", "25724", "25725", "25727", "25730", "25732", "25734", "25736", "25738", "25739", "25746", "25748", "25749", "25752", "25754", "25760", "25762", "25763", "25765", "25766", "25767", "25768", "25774", "25778", "25780", "25781", "25782", "25784", "25785", "25787", "25788", "25791", "25792", "25793", "25795", "25796", "25797", "25800", "25802", "25803", "25805", "25806", "25808", "25810", "25812", "25813", "25814", "25815", "25820", "25821", "25822", "25825", "25833", "25837", "25839", "25840", "25841", "25843", "25854", "25856", "25860", "25862", "25865", "25866", "25867", "25868", "25871", "25873", "25875", "25878", "25881", "25883", "25884", "25886", "25887", "25891", "25892", "25893", "25900", "25901", "25902", "25908", "25909", "25912", "25913", "25914", "25915", "25918", "25919", "25920", "25921", "25922", "25925", "25927", "25933", "25934", "25935", "25936", "25937", "25940", "25950", "25951", "25953", "25956", "25959", "25960", "25962", "25964", "25965", "25966", "25968", "25969", "25971", "25972", "25973", "25976", "25979", "25981", "25985", "25988", "25990", "25991", "25993", "25994", "25995", "25997", "26000", "26003", "26007", "26013", "26014", "26019", "26021", "26023", "26024", "26027", "26028", "26029", "26030", "26032", "26034", "26037", "26038", "26039", "26040", "26043", "26045", "26052", "26058", "26059", "26064", "26065", "26067", "26068", "26069", "26070", "26071", "26074", "26075", "26076", "26077", "26079", "26080", "26082", "26083", "26084", "26085", "26086", "26087", "26089", "26090", "26091", "26092", "26094", "26100", "26101", "26102", "26105", "26107", "26109", "26111", "26115", "26117", "26120", "26121", "26122", "26123", "26126", "26127", "26136", "26142", "26143", "26146", "26148", "26150", "26151", "26152", "26155", "26157", "26160", "26162", "26164", "26165", "26168", "26169", "26170", "26172", "26173", "26174", "26177", "26181", "26183", "26186", "26191", "26192", "26194", "26196", "26197", "26201", "26202", "26204", "26205", "26206", "26207", "26208", "26209", "26211", "26212", "26216", "26217", "26218", "26219", "26221", "26223", "26224", "26225", "26227", "26230", "26232", "26235", "26236", "26241", "26242", "26243", "26244", "26245", "26246", "26247", "26253", "26255", "26256", "26257", "26258", "26259", "26260", "26261", "26262", "26263", "26264", "26266", "26271", "26272", "26274", "26275", "26278", "26279", "26280", "26284", "26285", "26288", "26291", "26295", "26296", "26297", "26298", "26299", "26302", "26303", "26304", "26306", "26307", "26312", "26313", "26315", "26316", "26319", "26320", "26322", "26326", "26331", "26332", "26333", "26335", "26336", "26339", "26340", "26341", "26342", "26344", "26345", "26346", "26348", "26352", "26353", "26355", "26357", "26359", "26360", "26365", "26366", "26367", "26369", "26371", "26375", "26376", "26378", "26380", "26381", "26382", "26383", "26384", "26385", "26387", "26388", "26389", "26390", "26391", "26397", "26400", "26402", "26404", "26410", "26411", "26414", "26420", "26421", "26422", "26423", "26425", "26428", "26436", "26438", "26439", "26445", "26446", "26448", "26449", "26454", "26455", "26457", "26459", "26461", "26465", "26466", "26467", "26468", "26469", "26471", "26474", "26478", "26481", "26482", "26485", "26486", "26490", "26491", "26492", "26493", "26494", "26496", "26501", "26507", "26511", "26513", "26517", "26518", "26519", "26527", "26528", "26529", "26532", "26534", "26535", "26536", "26539", "26542", "26544", "26545", "26547", "26548", "26551", "26553", "26554", "26555", "26556", "26557", "26558", "26559", "26562", "26563", "26566", "26568", "26570", "26572", "26574", "26575", "26579", "26581", "26583", "26584", "26585", "26586", "26587", "26588", "26589", "26592", "26598", "26601", "26602", "26603", "26606", "26611", "26615", "26616", "26619", "26622", "26624", "26627", "26629", "26630", "26631", "26632", "26636", "26637", "26638", "26641", "26643", "26647", "26648", "26650", "26651", "26652", "26655", "26656", "26658", "26660", "26663", "26665", "26666", "26667", "26669", "26671", "26674", "26675", "26679", "26680", "26683", "26689", "26691", "26692", "26693", "26694", "26695", "26696", "26697", "26699", "26700", "26704", "26706", "26710", "26711", "26713", "26714", "26715", "26716", "26717", "26721", "26722", "26725", "26727", "26728", "26730", "26731", "26734", "26735", "26736", "26738", "26740", "26741", "26743", "26746", "26749", "26750", "26752", "26754", "26758", "26759", "26760", "26761", "26762", "26763", "26764", "26765", "26767", "26768", "26770", "26771", "26772", "26773", "26774", "26776", "26778", "26779", "26781", "26782", "26783", "26784", "26785", "26788", "26789", "26790", "26791", "26792", "26793", "26795", "26801", "26802", "26804", "26805", "26807", "26810", "26813", "26814", "26815", "26816", "26817", "26818", "26819", "26820", "26823", "26825", "26827", "26828", "26829", "26833", "26834", "26836", "26837", "26838", "26842", "26845", "26847", "26848", "26849", "26850", "26851", "26852", "26853", "26854", "26855", "26857", "26860", "26862", "26863", "26864", "26865", "26869", "26870", "26872", "26873", "26876", "26877", "26878", "26881", "26882", "26885", "26886", "26887", "26889", "26891", "26892", "26894", "26895", "26897", "26900", "26902", "26914", "26915", "26918", "26919", "26925", "26926", "26927", "26929", "26930", "26933", "26934", "26937", "26945", "26946", "26947", "26948", "26949", "26950", "26951", "26952", "26954", "26955", "26957", "26958", "26959", "26961", "26963", "26964", "26968", "26970", "26971", "26972", "26976", "26977", "26978", "26980", "26981", "26982", "26983", "26984", "26985", "26989", "26990", "26991", "26992", "26993", "26994", "26996", "26999", "27000", "27001", "27002", "27003", "27004", "27005", "27008", "27009", "27013", "27014", "27016", "27017", "27018", "27019", "27023", "27024", "27025", "27028", "27029", "27032", "27035", "27036", "27037", "27038", "27039", "27040", "27042", "27047", "27048", "27049", "27050", "27051", "27052", "27054", "27055", "27056", "27057", "27058", "27063", "27064", "27065", "27066", "27068", "27069", "27071", "27074", "27077", "27079", "27080", "27082", "27084", "27085", "27087", "27088", "27089", "27090", "27092", "27094", "27097", "27098", "27100", "27101", "27102", "27103", "27108", "27111", "27112", "27113", "27115", "27117", "27118", "27120", "27122", "27124", "27125", "27126", "27128", "27132", "27133", "27134", "27139", "27141", "27146", "27147", "27150", "27152", "27154", "27156", "27158", "27159", "27163", "27164", "27165", "27168", "27171", "27172", "27173", "27176", "27181", "27187", "27188", "27190", "27191", "27192", "27194", "27195", "27196", "27197", "27198", "27199", "27202", "27204", "27206", "27207", "27208", "27209", "27210", "27213", "27215", "27217", "27218", "27221", "27222", "27223", "27226", "27230", "27231", "27233", "27236", "27237", "27239", "27240", "27241", "27242", "27243", "27245", "27246", "27247", "27249", "27250", "27253", "27254", "27257", "27258", "27259", "27263", "27265", "27269", "27270", "27274", "27275", "27278", "27279", "27281", "27282", "27289", "27290", "27292", "27293", "27294", "27296", "27298", "27299", "27302", "27303", "27304", "27306", "27308", "27310", "27314", "27315", "27317", "27319", "27321", "27323", "27325", "27330", "27335", "27340", "27342", "27343", "27344", "27345", "27347", "27349", "27350", "27351", "27357", "27358", "27360", "27362", "27369", "27371", "27375", "27376", "27377", "27378", "27380", "27381", "27382", "27386", "27387", "27389", "27390", "27391", "27395", "27396", "27397", "27398", "27400", "27402", "27405", "27409", "27410", "27411", "27416", "27419", "27421", "27425", "27426", "27427", "27428", "27429", "27430", "27431", "27432", "27434", "27436", "27440", "27443", "27444", "27445", "27447", "27452", "27453", "27454", "27457", "27459", "27460", "27461", "27463", "27470", "27472", "27473", "27474", "27476", "27478", "27481", "27482", "27483", "27486", "27487", "27488", "27489", "27491", "27492", "27495", "27496", "27497", "27501", "27502", "27503", "27506", "27507", "27508", "27510", "27511", "27512", "27514", "27515", "27517", "27518", "27519", "27520", "27521", "27526", "27528", "27529", "27530", "27534", "27536", "27537", "27539", "27540", "27542", "27543", "27544", "27545", "27547", "27549", "27551", "27553", "27554", "27556", "27557", "27560", "27561", "27562", "27563", "27565", "27566", "27568", "27569", "27570", "27571", "27572", "27574", "27575", "27576", "27578", "27579", "27581", "27584", "27588", "27590", "27593", "27596", "27597", "27598", "27600", "27601", "27602", "27605", "27607", "27608", "27609", "27615", "27618", "27619", "27623", "27624", "27626", "27627", "27628", "27630", "27634", "27635", "27636", "27637", "27640", "27643", "27644", "27646", "27648", "27650", "27651", "27652", "27653", "27657", "27659", "27661", "27663", "27664", "27666", "27667", "27670", "27671", "27674", "27676", "27678", "27680", "27684", "27685", "27686", "27687", "27688", "27690", "27692", "27693", "27697", "27698", "27701", "27703", "27705", "27710", "27711", "27714", "27716", "27717", "27718", "27720", "27721", "27722", "27723", "27724", "27725", "27727", "27729", "27730", "27731", "27734", "27736", "27741", "27742", "27743", "27745", "27746", "27749", "27751", "27755", "27756", "27757", "27760", "27762", "27764", "27771", "27773", "27774", "27775", "27776", "27777", "27779", "27780", "27782", "27783", "27785", "27786", "27787", "27789", "27791", "27794", "27796", "27798", "27800", "27802", "27803", "27808", "27809", "27810", "27816", "27818", "27821", "27822", "27823", "27825", "27826", "27828", "27831", "27834", "27835", "27838", "27839", "27841", "27842", "27844", "27846", "27847", "27849", "27851", "27852", "27854", "27855", "27857", "27863", "27864", "27866", "27867", "27868", "27869", "27870", "27872", "27873", "27876", "27878", "27879", "27881", "27882", "27885", "27886", "27887", "27894", "27897", "27899", "27900", "27901", "27903", "27905", "27906", "27907", "27909", "27911", "27913", "27916", "27918", "27920", "27921", "27923", "27927", "27929", "27930", "27931", "27934", "27936", "27943", "27944", "27946", "27947", "27948", "27950", "27951", "27957", "27959", "27960", "27961", "27962", "27965", "27969", "27973", "27974", "27975", "27976", "27979", "27981", "27985", "27994", "27995", "27999", "28002", "28004", "28005", "28006", "28007", "28008", "28009", "28010", "28011", "28012", "28013", "28016", "28017", "28018", "28020", "28024", "28025", "28026", "28028", "28029", "28030", "28031", "28032", "28035", "28039", "28041", "28043", "28044", "28048", "28050", "28051", "28053", "28055", "28057", "28058", "28063", "28067", "28072", "28074", "28075", "28076", "28078", "28080", "28082", "28083", "28086", "28087", "28094", "28096", "28097", "28100", "28101", "28106", "28107", "28109", "28110", "28111", "28112", "28115", "28117", "28119", "28124", "28126", "28127", "28129", "28130", "28132", "28133", "28134", "28137", "28140", "28141", "28144", "28147", "28148", "28149", "28151", "28154", "28155", "28156", "28157", "28158", "28159", "28166", "28167", "28168", "28170", "28172", "28173", "28175", "28176", "28178", "28180", "28182", "28183", "28184", "28186", "28189", "28190", "28192", "28194", "28197", "28200", "28202", "28204", "28205", "28206", "28210", "28213", "28215", "28217", "28219", "28221", "28222", "28223", "28225", "28226", "28228", "28229", "28231", "28232", "28233", "28235", "28238", "28239", "28241", "28242", "28244", "28247", "28249", "28250", "28253", "28255", "28257", "28261", "28262", "28266", "28268", "28269", "28270", "28271", "28273", "28274", "28275", "28277", "28278", "28281", "28282", "28283", "28285", "28290", "28291", "28292", "28293", "28294", "28299", "28301", "28302", "28304", "28305", "28306", "28311", "28319", "28321", "28322", "28323", "28324", "28326", "28329", "28332", "28334", "28340", "28342", "28346", "28347", "28348", "28350", "28351", "28353", "28356", "28357", "28358", "28360", "28361", "28363", "28365", "28366", "28368", "28371", "28374", "28377", "28378", "28381", "28385", "28386", "28390", "28391", "28392", "28393", "28397", "28398", "28401", "28402", "28404", "28407", "28408", "28409", "28410", "28411", "28414", "28415", "28416", "28417", "28418", "28419", "28422", "28425", "28426", "28428", "28432", "28433", "28434", "28435", "28436", "28437", "28439", "28444", "28446", "28448", "28449", "28450", "28451", "28454", "28457", "28458", "28459", "28461", "28462", "28463", "28464", "28466", "28469", "28470", "28472", "28473", "28476", "28477", "28479", "28480", "28481", "28483", "28485", "28487", "28489", "28492", "28493", "28497", "28498", "28500", "28501", "28502", "28505", "28508", "28509", "28510", "28512", "28513", "28514", "28515", "28518", "28528", "28529", "28533", "28534", "28536", "28537", "28539", "28541", "28542", "28544", "28547", "28548", "28549", "28550", "28552", "28554", "28557", "28558", "28560", "28561", "28562", "28564", "28568", "28569", "28573", "28575", "28577", "28582", "28584", "28588", "28600", "28601", "28602", "28603", "28604", "28607", "28608", "28612", "28613", "28617", "28621", "28623", "28625", "28627", "28630", "28631", "28632", "28636", "28637", "28638", "28641", "28643", "28646", "28647", "28650", "28651", "28656", "28659", "28660", "28661", "28662", "28663", "28665", "28666", "28668", "28669", "28673", "28675", "28681", "28683", "28684", "28685", "28689", "28690", "28692", "28693", "28698", "28700", "28702", "28704", "28705", "28707", "28708", "28709", "28710", "28711", "28713", "28714", "28715", "28716", "28720", "28721", "28724", "28726", "28727", "28728", "28731", "28732", "28733", "28734", "28736", "28739", "28742", "28744", "28746", "28750", "28755", "28758", "28759", "28760", "28762", "28764", "28768", "28770", "28771", "28775", "28777", "28778", "28782", "28784", "28786", "28787", "28788", "28791", "28793", "28796", "28798", "28799", "28800", "28801", "28802", "28805", "28807", "28809", "28810", "28811", "28816", "28819", "28821", "28822", "28833", "28834", "28835", "28839", "28843", "28845", "28846", "28848", "28849", "28850", "28856", "28858", "28860", "28866", "28867", "28868", "28875", "28877", "28878", "28879", "28881", "28882", "28883", "28884", "28885", "28888", "28892", "28894", "28895", "28897", "28898", "28900", "28901", "28904", "28909", "28910", "28911", "28912", "28915", "28918", "28919", "28923", "28927", "28930", "28933", "28934", "28935", "28936", "28937", "28939", "28940", "28948", "28950", "28959", "28960", "28961", "28963", "28970", "28972", "28974", "28979", "28980", "28982", "28983", "28988", "28992", "28993", "28999", "29004", "29006", "29007", "29009", "29010", "29011", "29013", "29016", "29018", "29020", "29026", "29027", "29028", "29029", "29030", "29033", "29035", "29036", "29037", "29038", "29039", "29043", "29044", "29046", "29049", "29052", "29053", "29054", "29055", "29056", "29061", "29064", "29068", "29071", "29074", "29077", "29081", "29082", "29083", "29084", "29085", "29086", "29087", "29088", "29090", "29091", "29096", "29097", "29098", "29100", "29102", "29104", "29107", "29109", "29111", "29114", "29115", "29116", "29117", "29118", "29119", "29120", "29126", "29127", "29135", "29137", "29139", "29141", "29142", "29151", "29152", "29154", "29155", "29158", "29159", "29161", "29162", "29166", "29168", "29169", "29172", "29175", "29179", "29182", "29185", "29187", "29189", "29190", "29191", "29192", "29195", "29196", "29198", "29199", "29200", "29201", "29204", "29207", "29210", "29213", "29215", "29216", "29222", "29223", "29224", "29226", "29227", "29228", "29229", "29230", "29231", "29232", "29234", "29239", "29243", "29245", "29247", "29249", "29256", "29258", "29259", "29262", "29265", "29266", "29268", "29269", "29270", "29272", "29273", "29275", "29276", "29277", "29280", "29283", "29284", "29285", "29288", "29289", "29290", "29291", "29297", "29298", "29299", "29300", "29301", "29302", "29303", "29304", "29309", "29318", "29320", "29321", "29322", "29325", "29328", "29329", "29332", "29333", "29334", "29336", "29337", "29338", "29339", "29342", "29345", "29350", "29351", "29354", "29356", "29358", "29360", "29366", "29369", "29370", "29375", "29376", "29378", "29379", "29383", "29384", "29385", "29388", "29392", "29393", "29394", "29397", "29400", "29401", "29402", "29404", "29408", "29410", "29412", "29413", "29414", "29415", "29416", "29423", "29425", "29427", "29428", "29430", "29431", "29432", "29433", "29435", "29440", "29441", "29442", "29443", "29445", "29446", "29452", "29454", "29455", "29459", "29460", "29462", "29463", "29465", "29466", "29467", "29470", "29472", "29473", "29474", "29475", "29477", "29478", "29479", "29480", "29482", "29485", "29490", "29491", "29493", "29495", "29497", "29498", "29501", "29505", "29506", "29507", "29509", "29511", "29512", "29513", "29515", "29516", "29517", "29519", "29520", "29521", "29522", "29525", "29526", "29529", "29531", "29532", "29537", "29538", "29542", "29543", "29548", "29549", "29550", "29551", "29553", "29555", "29558", "29559", "29562", "29564", "29565", "29566", "29567", "29570", "29573", "29574", "29575", "29577", "29579", "29580", "29581", "29582", "29584", "29586", "29587", "29589", "29591", "29592", "29594", "29597", "29599", "29601", "29603", "29604", "29605", "29606", "29608", "29611", "29612", "29613", "29615", "29616", "29618", "29619", "29620", "29621", "29626", "29628", "29632", "29636", "29637", "29639", "29640", "29641", "29642", "29643", "29648", "29649", "29650", "29653", "29654", "29655", "29657", "29660", "29661", "29662", "29663", "29664", "29670", "29673", "29677", "29678", "29680", "29681", "29684", "29685", "29686", "29687", "29689", "29692", "29695", "29696", "29697", "29699", "29700", "29702", "29703", "29705", "29706", "29707", "29711", "29715", "29717", "29719", "29722", "29725", "29726", "29727", "29728", "29730", "29731", "29732", "29733", "29735", "29737", "29741", "29743", "29745", "29746", "29747", "29748", "29749", "29752", "29753", "29754", "29757", "29758", "29760", "29762", "29766", "29768", "29770", "29773", "29775", "29778", "29779", "29781", "29782", "29787", "29792", "29793", "29795", "29796", "29798", "29799", "29800", "29801", "29802", "29803", "29804", "29807", "29810", "29813", "29816", "29817", "29818", "29819", "29820", "29821", "29822", "29823", "29824", "29828", "29829", "29830", "29832", "29834", "29835", "29836", "29838", "29840", "29841", "29842", "29843", "29844", "29851", "29853", "29857", "29858", "29859", "29860", "29861", "29862", "29865", "29866", "29868", "29871", "29872", "29873", "29874", "29876", "29882", "29884", "29888", "29889", "29891", "29892", "29894", "29895", "29896", "29900", "29901", "29902", "29904", "29905", "29907", "29908", "29909", "29910", "29913", "29915", "29916", "29917", "29918", "29920", "29924", "29926", "29927", "29932", "29933", "29935", "29936", "29937", "29939", "29943", "29945", "29948", "29950", "29951", "29952", "29953", "29954", "29955", "29957", "29960", "29961", "29964", "29965", "29966", "29967", "29968", "29972", "29974", "29976", "29977", "29979", "29980", "29981", "29985", "29987", "29988", "29989", "29993", "29994", "29995", "29997", "29998", "30000", "30003", "30004", "30005", "30007", "30009", "30012", "30013", "30014", "30015", "30018", "30019", "30020", "30021", "30023", "30025", "30026", "30028", "30029", "30030", "30031", "30032", "30033", "30034", "30036", "30037", "30038", "30039", "30041", "30042", "30046", "30048", "30050", "30051", "30052", "30054", "30055", "30058", "30060", "30061", "30064", "30066", "30068", "30075", "30082", "30084", "30087", "30088", "30089", "30090", "30091", "30092", "30094", "30095", "30096", "30097", "30100", "30101", "30105", "30109", "30111", "30112", "30113", "30114", "30115", "30119", "30121", "30123", "30126", "30127", "30133", "30135", "30137", "30138", "30139", "30141", "30143", "30146", "30147", "30151", "30157", "30161", "30164", "30174", "30176", "30178", "30181", "30183", "30186", "30188", "30190", "30191", "30192", "30193", "30197", "30200", "30202", "30205", "30207", "30212", "30216", "30217", "30222", "30223", "30224", "30225", "30226", "30227", "30228", "30229", "30230", "30231", "30237", "30240", "30241", "30243", "30245", "30248", "30250", "30251", "30252", "30254", "30255", "30256", "30257", "30262", "30264", "30265", "30268", "30273", "30276", "30278", "30279", "30282", "30283", "30284", "30286", "30288", "30290", "30291", "30292", "30293", "30296", "30297", "30298", "30300", "30301", "30302", "30304", "30305", "30306", "30308", "30309", "30312", "30315", "30317", "30319", "30320", "30322", "30323", "30330", "30332", "30333", "30337", "30339", "30342", "30344", "30348", "30349", "30350", "30354", "30355", "30357", "30358", "30359", "30361", "30363", "30371", "30375", "30377", "30379", "30380", "30383", "30384", "30385", "30387", "30389", "30391", "30392", "30393", "30394", "30395", "30396", "30404", "30405", "30407", "30408", "30409", "30411", "30412", "30413", "30415", "30416", "30418", "30420", "30421", "30423", "30424", "30426", "30427", "30428", "30429", "30431", "30432", "30433", "30436", "30438", "30444", "30450", "30454", "30459", "30466", "30467", "30468", "30469", "30471", "30472", "30474", "30477", "30481", "30482", "30483", "30486", "30487", "30489", "30490", "30491", "30494", "30495", "30498", "30499", "30500", "30502", "30503", "30506", "30508", "30509", "30510", "30515", "30517", "30520", "30522", "30524", "30525", "30526", "30528", "30529", "30532", "30535", "30536", "30539", "30540", "30542", "30545", "30546", "30552", "30553", "30556", "30558", "30559", "30560", "30564", "30565", "30567", "30568", "30570", "30572", "30573", "30574", "30578", "30579", "30580", "30582", "30584", "30585", "30587", "30595", "30596", "30597", "30598", "30600", "30601", "30605", "30607", "30611", "30613", "30615", "30617", "30618", "30620", "30622", "30623", "30627", "30629", "30631", "30632", "30633", "30635", "30638", "30640", "30641", "30646", "30647", "30650", "30651", "30652", "30653", "30656", "30657", "30662", "30663", "30664", "30665", "30666", "30668", "30671", "30673", "30674", "30681", "30684", "30686", "30689", "30691", "30692", "30693", "30695", "30696", "30698", "30699", "30700", "30702", "30703", "30705", "30706", "30707", "30712", "30713", "30714", "30715", "30718", "30721", "30722", "30725", "30726", "30727", "30728", "30729", "30731", "30732", "30733", "30735", "30736", "30738", "30743", "30744", "30746", "30748", "30751", "30754", "30757", "30761", "30762", "30763", "30764", "30767", "30768", "30769", "30770", "30773", "30777", "30779", "30780", "30783", "30788", "30790", "30794", "30796", "30797", "30798", "30801", "30802", "30803", "30810", "30811", "30812", "30814", "30815", "30816", "30817", "30819", "30822", "30823", "30824", "30826", "30831", "30832", "30833", "30834", "30835", "30836", "30840", "30841", "30842", "30843", "30846", "30849", "30850", "30852", "30853", "30854", "30855", "30856", "30858", "30859", "30863", "30864", "30865", "30866", "30867", "30868", "30869", "30871", "30872", "30874", "30877", "30881", "30882", "30883", "30884", "30896", "30897", "30898", "30899", "30900", "30901", "30902", "30903", "30907", "30909", "30911", "30912", "30914", "30915", "30918", "30919", "30921", "30922", "30927", "30928", "30930", "30938", "30942", "30943", "30946", "30947", "30948", "30949", "30950", "30951", "30954", "30955", "30957", "30958", "30959", "30960", "30963", "30964", "30965", "30966", "30969", "30974", "30976", "30979", "30981", "30982", "30983", "30985", "30986", "30988", "30989", "30990", "30991", "30995", "30996", "30997", "30998", "30999", "31003", "31005", "31008", "31009", "31011", "31013", "31015", "31017", "31018", "31019", "31021", "31022", "31023", "31024", "31025", "31027", "31030", "31033", "31034", "31035", "31037", "31039", "31040", "31041", "31042", "31043", "31044", "31046", "31048", "31050", "31054", "31055", "31056", "31057", "31060", "31061", "31065", "31067", "31068", "31069", "31070", "31071", "31072", "31075", "31076", "31077", "31078", "31082", "31084", "31085", "31087", "31088", "31090", "31097", "31100", "31104", "31107", "31110", "31111", "31112", "31113", "31116", "31117", "31118", "31120", "31123", "31124", "31125", "31128", "31130", "31132", "31134", "31136", "31138", "31140", "31143", "31146", "31147", "31148", "31150", "31152", "31154", "31155", "31156", "31158", "31162", "31163", "31165", "31168", "31169", "31171", "31173", "31174", "31176", "31178", "31179", "31180", "31183", "31185", "31186", "31191", "31193", "31195", "31196", "31207", "31208", "31209", "31216", "31217", "31220", "31221", "31224", "31225", "31227", "31228", "31229", "31233", "31234", "31237", "31238", "31240", "31244", "31245", "31246", "31247", "31248", "31251", "31252", "31254", "31255", "31256", "31257", "31260", "31261", "31263", "31264", "31265", "31267", "31268", "31271", "31272", "31274", "31275", "31277", "31278", "31281", "31284", "31287", "31290", "31291", "31292", "31293", "31295", "31298", "31300", "31301", "31303", "31305", "31307", "31308", "31312", "31313", "31316", "31317", "31320", "31322", "31323", "31327", "31329", "31330", "31331", "31332", "31334", "31335", "31339", "31341", "31342", "31351", "31352", "31353", "31354", "31356", "31357", "31358", "31360", "31361", "31362", "31364", "31365", "31366", "31371", "31375", "31377", "31379", "31380", "31383", "31384", "31387", "31390", "31393", "31395", "31396", "31397", "31402", "31404", "31405", "31408", "31412", "31414", "31416", "31417", "31419", "31420", "31421", "31423", "31430", "31431", "31433", "31435", "31437", "31439", "31440", "31442", "31447", "31448", "31449", "31451", "31455", "31456", "31460", "31462", "31464", "31467", "31470", "31471", "31473", "31475", "31476", "31477", "31479", "31481", "31483", "31486", "31488", "31490", "31491", "31496", "31498", "31499", "31502", "31503", "31504", "31506", "31507", "31509", "31510", "31511", "31512", "31514", "31516", "31518", "31520", "31522", "31524", "31525", "31526", "31527", "31529", "31530", "31532", "31534", "31535", "31536", "31540", "31541", "31542", "31543", "31544", "31545", "31547", "31549", "31551", "31552", "31554", "31556", "31559", "31560", "31563", "31565", "31569", "31570", "31571", "31572", "31573", "31574", "31575", "31576", "31577", "31578", "31579", "31583", "31584", "31587", "31591", "31592", "31593", "31594", "31598", "31599", "31600", "31601", "31602", "31603", "31605", "31608", "31609", "31610", "31613", "31615", "31617", "31618", "31620", "31623", "31624", "31625", "31630", "31632", "31634", "31635", "31636", "31638", "31640", "31641", "31642", "31644", "31645", "31648", "31649", "31650", "31651", "31653", "31656", "31657", "31658", "31659", "31664", "31667", "31668", "31670", "31672", "31677", "31679", "31680", "31683", "31684", "31685", "31686", "31687", "31688", "31693", "31694", "31695", "31696", "31697", "31699", "31700", "31702", "31704", "31707", "31708", "31710", "31711", "31712", "31717", "31718", "31722", "31724", "31729", "31731", "31735", "31736", "31737", "31741", "31742", "31746", "31748", "31749", "31750", "31752", "31754", "31755", "31757", "31758", "31763", "31764", "31765", "31767", "31774", "31775", "31776", "31777", "31778", "31779", "31780", "31782", "31783", "31784", "31786", "31788", "31791", "31794", "31796", "31799", "31801", "31802", "31803", "31804", "31805", "31806", "31807", "31809", "31811", "31812", "31813", "31814", "31816", "31817", "31818", "31821", "31822", "31823", "31824", "31825", "31826", "31828", "31829", "31831", "31832", "31833", "31838", "31839", "31840", "31842", "31843", "31846", "31849", "31855", "31860", "31861", "31862", "31863", "31864", "31865", "31867", "31868", "31870", "31871", "31873", "31874", "31883", "31884", "31885", "31886", "31887", "31888", "31890", "31892", "31894", "31895", "31899", "31900", "31905", "31906", "31908", "31910", "31912", "31914", "31916", "31917", "31918", "31920", "31921", "31922", "31929", "31930", "31931", "31933", "31935", "31936", "31937", "31939", "31944", "31945", "31946", "31947", "31948", "31949", "31950", "31951", "31954", "31955", "31956", "31958", "31960", "31962", "31963", "31964", "31965", "31966", "31967", "31969", "31971", "31973", "31975", "31978", "31979", "31981", "31982", "31985", "31987", "31988", "31990", "31991", "31992", "31993", "31996", "31997", "31999", "32000", "32001", "32002", "32003", "32004", "32006", "32007", "32008", "32009", "32012", "32013", "32014", "32015", "32017", "32020", "32021", "32022", "32024", "32025", "32031", "32032", "32035", "32037", "32040", "32041", "32043", "32044", "32046", "32047", "32049", "32051", "32052", "32054", "32055", "32056", "32057", "32058", "32059", "32060", "32064", "32066", "32069", "32070", "32072", "32078", "32079", "32083", "32085", "32086", "32087", "32089", "32093", "32094", "32097", "32101", "32108", "32111", "32113", "32115", "32116", "32117", "32118", "32119", "32121", "32125", "32129", "32130", "32131", "32135", "32136", "32138", "32139", "32140", "32141", "32143", "32144", "32145", "32146", "32148", "32151", "32152", "32155", "32156", "32157", "32158", "32160", "32161", "32164", "32166", "32167", "32172", "32173", "32175", "32177", "32178", "32182", "32183", "32184", "32186", "32187", "32189", "32190", "32191", "32192", "32193", "32194", "32196", "32198", "32206", "32207", "32210", "32215", "32216", "32217", "32222", "32225", "32226", "32227", "32229", "32230", "32231", "32232", "32234", "32237", "32241", "32242", "32251", "32252", "32253", "32254", "32255", "32257", "32259", "32261", "32262", "32264", "32265", "32268", "32269", "32271", "32273", "32275", "32277", "32279", "32280", "32281", "32282", "32283", "32286", "32288", "32290", "32291", "32293", "32294", "32296", "32299", "32300", "32306", "32308", "32309", "32311", "32319", "32320", "32322", "32323", "32324", "32325", "32327", "32331", "32335", "32336", "32337", "32341", "32342", "32343", "32346", "32347", "32348", "32349", "32350", "32352", "32354", "32357", "32362", "32366", "32367", "32369", "32370", "32371", "32373", "32378", "32380", "32381", "32382", "32383", "32386", "32391", "32392", "32395", "32396", "32397", "32399", "32400", "32401", "32404", "32407", "32408", "32409", "32413", "32416", "32417", "32419", "32425", "32426", "32427", "32430", "32436", "32438", "32442", "32443", "32444", "32445", "32446", "32447", "32452", "32453", "32454", "32457", "32458", "32460", "32461", "32462", "32464", "32468", "32470", "32473", "32477", "32478", "32486", "32487", "32489", "32491", "32493", "32494", "32498", "32500", "32503", "32504", "32506", "32507", "32510", "32512", "32513", "32516", "32518", "32523", "32524", "32525", "32526", "32528", "32529", "32530", "32531", "32533", "32536", "32537", "32538", "32539", "32541", "32547", "32553", "32556", "32557", "32558", "32559", "32560", "32561", "32563", "32564", "32566", "32567", "32568", "32571", "32573", "32574", "32579", "32580", "32581", "32582", "32583", "32585", "32587", "32588", "32589", "32590", "32595", "32597", "32598", "32602", "32603", "32605", "32606", "32607", "32608", "32610", "32611", "32614", "32617", "32618", "32619", "32622", "32624", "32625", "32627", "32629", "32633", "32634", "32638", "32644", "32645", "32646", "32651", "32652", "32655", "32659", "32663", "32664", "32665", "32669", "32670", "32671", "32672", "32673", "32674", "32675", "32678", "32680", "32681", "32683", "32684", "32685", "32686", "32689", "32691", "32696", "32698", "32699", "32700", "32702", "32703", "32707", "32708", "32710", "32711", "32713", "32714", "32716", "32718", "32719", "32720", "32723", "32724", "32730", "32732", "32735", "32736", "32737", "32739", "32742", "32744", "32748", "32751", "32752", "32753", "32754", "32755", "32756", "32757", "32758", "32761", "32763", "32768", "32769", "32770", "32771", "32772", "32774", "32776", "32777", "32778", "32785", "32786", "32789", "32790", "32791", "32795", "32796", "32798", "32800", "32801", "32809", "32810", "32811", "32812", "32816", "32817", "32822", "32823", "32824", "32825", "32826", "32830", "32835", "32836", "32837", "32838", "32840", "32843", "32845", "32846", "32847", "32848", "32849", "32851", "32853", "32856", "32858", "32864", "32867", "32868", "32869", "32872", "32875", "32877", "32879", "32880", "32883", "32884", "32887", "32888", "32889", "32890", "32891", "32892", "32896", "32897", "32898", "32899", "32903", "32905", "32907", "32908", "32910", "32913", "32914", "32915", "32919", "32920", "32922", "32923", "32927", "32930", "32931", "32934", "32935", "32939", "32941", "32942", "32943", "32944", "32946", "32952", "32953", "32954", "32957", "32959", "32962", "32964", "32968", "32971", "32972", "32974", "32978", "32981", "32984", "32985", "32987", "32991", "32993", "32995", "32997", "32999", "33001", "33002", "33003", "33006", "33008", "33010", "33012", "33016", "33017", "33018", "33023", "33024", "33026", "33029", "33032", "33035", "33038", "33040", "33044", "33048", "33053", "33059", "33062", "33063", "33065", "33070", "33071", "33072", "33073", "33074", "33075", "33076", "33080", "33084", "33085", "33088", "33089", "33090", "33091", "33093", "33095", "33099", "33101", "33104", "33108", "33109", "33112", "33113", "33114", "33115", "33117", "33124", "33126", "33127", "33131", "33132", "33136", "33137", "33140", "33143", "33144", "33145", "33149", "33150", "33151", "33152", "33155", "33156", "33157", "33158", "33159", "33161", "33162", "33163", "33164", "33165", "33172", "33176", "33180", "33182", "33183", "33184", "33185", "33188", "33190", "33191", "33194", "33195", "33196", "33197", "33198", "33202", "33204", "33205", "33208", "33211", "33213", "33218", "33219", "33220", "33222", "33223", "33226", "33228", "33229", "33231", "33232", "33233", "33234", "33235", "33239", "33241", "33243", "33246", "33249", "33250", "33253", "33254", "33255", "33256", "33257", "33258", "33260", "33264", "33266", "33269", "33274", "33276", "33278", "33279", "33283", "33284", "33289", "33292", "33293", "33299", "33302", "33305", "33306", "33308", "33309", "33310", "33312", "33313", "33316", "33322", "33325", "33330", "33334", "33335", "33337", "33339", "33341", "33342", "33343", "33347", "33349", "33350", "33352", "33353", "33354", "33356", "33357", "33359", "33360", "33362", "33363", "33365", "33368", "33369", "33370", "33372", "33374", "33379", "33380", "33381", "33384", "33386", "33387", "33389", "33392", "33394", "33395", "33396", "33397", "33398", "33399", "33400", "33401", "33406", "33408", "33411", "33412", "33413", "33415", "33417", "33419", "33422", "33426", "33427", "33429", "33433", "33434", "33435", "33437", "33442", "33444", "33446", "33448", "33450", "33451", "33453", "33455", "33456", "33457", "33458", "33459", "33460", "33461", "33462", "33463", "33464", "33466", "33468", "33470", "33471", "33472", "33474", "33475", "33476", "33477", "33478", "33480", "33482", "33486", "33488", "33489", "33490", "33492", "33493", "33495", "33496", "33502", "33503", "33506", "33507", "33508", "33510", "33512", "33513", "33514", "33516", "33520", "33521", "33525", "33526", "33535", "33536", "33537", "33538", "33540", "33541", "33545", "33548", "33549", "33551", "33555", "33557", "33560", "33562", "33563", "33566", "33569", "33570", "33574", "33575", "33576", "33577", "33579", "33580", "33581", "33582", "33583", "33585", "33587", "33590", "33591", "33592", "33595", "33596", "33598", "33603", "33604", "33608", "33610", "33611", "33614", "33615", "33616", "33618", "33623", "33625", "33627", "33629", "33632", "33634", "33635", "33636", "33637", "33638", "33639", "33640", "33643", "33645", "33646", "33647", "33650", "33652", "33655", "33658", "33660", "33663", "33664", "33666", "33667", "33669", "33672", "33674", "33681", "33685", "33686", "33688", "33691", "33697", "33698", "33700", "33705", "33708", "33709", "33714", "33715", "33716", "33717", "33719", "33724", "33728", "33730", "33732", "33734", "33736", "33737", "33738", "33739", "33743", "33744", "33745", "33746", "33747", "33748", "33749", "33750", "33753", "33754", "33756", "33757", "33758", "33762", "33763", "33764", "33767", "33769", "33771", "33772", "33774", "33775", "33777", "33778", "33781", "33782", "33783", "33784", "33786", "33787", "33788", "33789", "33790", "33791", "33792", "33794", "33795", "33796", "33802", "33803", "33804", "33806", "33808", "33809", "33810", "33811", "33812", "33813", "33815", "33816", "33817", "33819", "33820", "33821", "33822", "33824", "33825", "33827", "33828", "33832", "33835", "33838", "33839", "33841", "33842", "33844", "33845", "33847", "33848", "33852", "33853", "33856", "33857", "33858", "33860", "33861", "33864", "33865", "33868", "33874", "33876", "33878", "33879", "33880", "33881", "33882", "33885", "33886", "33887", "33889", "33892", "33895", "33896", "33897", "33900", "33901", "33902", "33903", "33904", "33911", "33912", "33915", "33916", "33918", "33919", "33920", "33921", "33922", "33925", "33926", "33927", "33928", "33929", "33932", "33934", "33935", "33937", "33939", "33940", "33942", "33943", "33944", "33947", "33948", "33949", "33950", "33952", "33953", "33955", "33957", "33960", "33962", "33964", "33967", "33969", "33972", "33975", "33976", "33977", "33979", "33980", "33981", "33982", "33983", "33985", "33986", "33989", "33991", "33996", "33998", "34001", "34005", "34006", "34007", "34008", "34009", "34015", "34016", "34018", "34020", "34021", "34027", "34028", "34031", "34032", "34033", "34035", "34036", "34037", "34038", "34040", "34042", "34045", "34048", "34050", "34051", "34052", "34053", "34054", "34058", "34060", "34061", "34062", "34063", "34064", "34066", "34067", "34068", "34069", "34070", "34071", "34073", "34074", "34075", "34076", "34077", "34078", "34079", "34080", "34082", "34083", "34087", "34090", "34091", "34092", "34093", "34095", "34100", "34101", "34103", "34105", "34112", "34114", "34115", "34116", "34117", "34123", "34124", "34127", "34130", "34131", "34132", "34135", "34137", "34138", "34139", "34146", "34147", "34148", "34149", "34150", "34153", "34156", "34158", "34160", "34163", "34164", "34169", "34170", "34174", "34176", "34180", "34181", "34182", "34183", "34184", "34186", "34187", "34188", "34189", "34193", "34198", "34199", "34200", "34201", "34202", "34203", "34204", "34207", "34216", "34220", "34222", "34223", "34226", "34229", "34230", "34231", "34236", "34244", "34245", "34246", "34251", "34252", "34253", "34254", "34256", "34257", "34259", "34261", "34262", "34263", "34265", "34266", "34269", "34270", "34271", "34273", "34274", "34275", "34277", "34278", "34279", "34281", "34282", "34284", "34286", "34288", "34289", "34295", "34296", "34298", "34303", "34305", "34306", "34310", "34314", "34316", "34320", "34321", "34324", "34328", "34332", "34333", "34334", "34335", "34336", "34338", "34339", "34340", "34343", "34344", "34347", "34351", "34352", "34353", "34354", "34358", "34359", "34360", "34361", "34363", "34364", "34365", "34371", "34372", "34373", "34376", "34383", "34384", "34385", "34387", "34388", "34391", "34393", "34394", "34396", "34398", "34399", "34401", "34403", "34404", "34405", "34407", "34412", "34417", "34419", "34422", "34425", "34427", "34428", "34430", "34432", "34433", "34436", "34438", "34441", "34442", "34444", "34447", "34448", "34454", "34457", "34461", "34462", "34464", "34465", "34466", "34467", "34469", "34472", "34473", "34475", "34476", "34477", "34485", "34488", "34489", "34491", "34492", "34497", "34500", "34501", "34502", "34505", "34508", "34511", "34512", "34513", "34514", "34516", "34519", "34521", "34524", "34526", "34528", "34529", "34530", "34531", "34534", "34536", "34538", "34539", "34540", "34541", "34544", "34545", "34548", "34549", "34551", "34552", "34555", "34560", "34562", "34563", "34564", "34566", "34567", "34570", "34572", "34577", "34579", "34582", "34583", "34585", "34586", "34587", "34589", "34596", "34598", "34599", "34600", "34602", "34609", "34612", "34614", "34619", "34623", "34624", "34625", "34628", "34632", "34633", "34636", "34637", "34638", "34639", "34641", "34642", "34646", "34647", "34650", "34655", "34656", "34657", "34658", "34659", "34660", "34661", "34662", "34663", "34664", "34665", "34667", "34669", "34673", "34674", "34675", "34678", "34679", "34680", "34684", "34687", "34696", "34697", "34698", "34702", "34704", "34706", "34709", "34711", "34714", "34717", "34719", "34722", "34723", "34725", "34726", "34729", "34730", "34731", "34733", "34736", "34740", "34741", "34742", "34743", "34744", "34745", "34749", "34751", "34752", "34753", "34754", "34756", "34760", "34763", "34764", "34765", "34766", "34767", "34768", "34770", "34773", "34774", "34776", "34781", "34782", "34784", "34787", "34789", "34792", "34794", "34797", "34800", "34801", "34802", "34804", "34806", "34807", "34811", "34812", "34813", "34815", "34816", "34818", "34819", "34821", "34822", "34823", "34824", "34826", "34828", "34829", "34831", "34834", "34835", "34841", "34843", "34844", "34847", "34848", "34850", "34851", "34852", "34853", "34855", "34856", "34858", "34859", "34862", "34863", "34867", "34868", "34869", "34870", "34873", "34874", "34876", "34877", "34878", "34882", "34884", "34887", "34889", "34890", "34891", "34893", "34898", "34900", "34901", "34902", "34903", "34904", "34908", "34909", "34910", "34915", "34916", "34919", "34920", "34924", "34927", "34930", "34933", "34937", "34938", "34939", "34940", "34941", "34942", "34944", "34945", "34949", "34951", "34953", "34956", "34957", "34959", "34960", "34963", "34964", "34965", "34970", "34972", "34973", "34974", "34975", "34978", "34980", "34987", "34990", "34991", "34993", "34999", "35000", "35003", "35004", "35005", "35006", "35008", "35009", "35012", "35014", "35017", "35019", "35020", "35021", "35023", "35027", "35029", "35030", "35031", "35032", "35033", "35035", "35037", "35038", "35039", "35043", "35044", "35045", "35046", "35048", "35049", "35050", "35051", "35053", "35054", "35057", "35061", "35063", "35064", "35066", "35067", "35069", "35070", "35071", "35072", "35076", "35079", "35081", "35084", "35085", "35086", "35089", "35090", "35091", "35092", "35093", "35094", "35095", "35098", "35099", "35103", "35105", "35108", "35109", "35113", "35122", "35123", "35124", "35125", "35129", "35130", "35131", "35132", "35135", "35136", "35139", "35140", "35143", "35144", "35146", "35148", "35152", "35154", "35156", "35159", "35161", "35162", "35163", "35164", "35166", "35167", "35168", "35169", "35170", "35171", "35172", "35173", "35178", "35179", "35181", "35186", "35188", "35190", "35195", "35196", "35198", "35199", "35200", "35201", "35204", "35205", "35212", "35219", "35220", "35224", "35225", "35229", "35230", "35231", "35233", "35234", "35235", "35237", "35242", "35244", "35246", "35247", "35250", "35251", "35252", "35254", "35256", "35258", "35263", "35264", "35266", "35272", "35275", "35276", "35277", "35279", "35282", "35283", "35286", "35287", "35288", "35295", "35296", "35298", "35299", "35300", "35304", "35307", "35309", "35311", "35313", "35314", "35316", "35318", "35319", "35320", "35321", "35322", "35323", "35324", "35325", "35328", "35329", "35330", "35334", "35338", "35339", "35341", "35343", "35344", "35348", "35349", "35350", "35358", "35361", "35362", "35364", "35369", "35371", "35373", "35374", "35375", "35379", "35380", "35382", "35384", "35386", "35387", "35388", "35391", "35392", "35394", "35395", "35398", "35399", "35402", "35403", "35405", "35409", "35414", "35416", "35418", "35419", "35420", "35421", "35422", "35427", "35431", "35432", "35433", "35434", "35436", "35439", "35440", "35442", "35443", "35444", "35445", "35446", "35447", "35451", "35455", "35457", "35458", "35459", "35463", "35465", "35468", "35469", "35472", "35473", "35480", "35481", "35482", "35484", "35488", "35490", "35491", "35494", "35495", "35496", "35502", "35503", "35505", "35507", "35508", "35510", "35513", "35515", "35516", "35517", "35519", "35520", "35521", "35522", "35523", "35524", "35526", "35528", "35529", "35530", "35531", "35534", "35537", "35542", "35543", "35544", "35548", "35549", "35550", "35555", "35556", "35557", "35558", "35560", "35561", "35562", "35566", "35571", "35572", "35573", "35574", "35578", "35581", "35583", "35586", "35588", "35594", "35595", "35597", "35598", "35599", "35600", "35605", "35607", "35609", "35611", "35613", "35614", "35617", "35620", "35621", "35626", "35628", "35630", "35632", "35635", "35636", "35637", "35638", "35646", "35648", "35649", "35654", "35655", "35656", "35657", "35659", "35663", "35664", "35668", "35669", "35671", "35672", "35673", "35677", "35678", "35681", "35682", "35683", "35684", "35685", "35687", "35688", "35689", "35691", "35692", "35696", "35697", "35698", "35699", "35700", "35702", "35703", "35706", "35712", "35714", "35716", "35718", "35720", "35724", "35725", "35726", "35727", "35728", "35729", "35736", "35743", "35746", "35747", "35751", "35753", "35754", "35757", "35762", "35763", "35764", "35765", "35766", "35767", "35768", "35772", "35775", "35778", "35779", "35781", "35782", "35785", "35792", "35794", "35798", "35799", "35802", "35803", "35804", "35805", "35807", "35814", "35815", "35816", "35817", "35818", "35825", "35826", "35829", "35832", "35835", "35836", "35838", "35839", "35841", "35842", "35843", "35846", "35847", "35848", "35849", "35850", "35851", "35852", "35853", "35854", "35855", "35856", "35859", "35861", "35863", "35864", "35865", "35866", "35868", "35870", "35872", "35876", "35879", "35880", "35881", "35882", "35883", "35884", "35885", "35887", "35889", "35891", "35892", "35893", "35895", "35898", "35900", "35902", "35908", "35910", "35911", "35912", "35916", "35917", "35918", "35921", "35927", "35929", "35930", "35935", "35940", "35941", "35943", "35944", "35948", "35952", "35953", "35954", "35959", "35969", "35970", "35971", "35975", "35976", "35977", "35978", "35979", "35982", "35983", "35984", "35985", "35986", "35988", "35989", "35990", "35992", "35999", "36001", "36002", "36003", "36004", "36005", "36007", "36008", "36009", "36012", "36013", "36016", "36017", "36019", "36021", "36023", "36024", "36031", "36033", "36041", "36042", "36047", "36048", "36050", "36051", "36057", "36059", "36060", "36063", "36064", "36065", "36068", "36070", "36071", "36072", "36074", "36075", "36077", "36078", "36079", "36081", "36085", "36088", "36090", "36094", "36096", "36098", "36102", "36106", "36107", "36108", "36111", "36112", "36115", "36116", "36119", "36126", "36127", "36128", "36129", "36130", "36134", "36142", "36145", "36147", "36148", "36150", "36151", "36153", "36156", "36157", "36158", "36159", "36161", "36162", "36170", "36172", "36174", "36176", "36180", "36182", "36183", "36186", "36189", "36192", "36193", "36194", "36202", "36203", "36205", "36209", "36210", "36214", "36217", "36222", "36223", "36224", "36226", "36228", "36231", "36232", "36233", "36234", "36235", "36236", "36239", "36240", "36241", "36242", "36245", "36246", "36248", "36250", "36251", "36252", "36253", "36256", "36257", "36258", "36262", "36263", "36265", "36266", "36267", "36270", "36272", "36273", "36274", "36275", "36276", "36279", "36280", "36282", "36284", "36285", "36287", "36288", "36289", "36290", "36291", "36292", "36295", "36296", "36297", "36298", "36300", "36305", "36307", "36308", "36309", "36311", "36314", "36319", "36321", "36322", "36327", "36328", "36329", "36330", "36331", "36335", "36336", "36337", "36338", "36343", "36348", "36349", "36354", "36355", "36359", "36360", "36361", "36365", "36368", "36369", "36370", "36371", "36372", "36373", "36377", "36382", "36383", "36384", "36385", "36386", "36387", "36388", "36389", "36393", "36394", "36403", "36404", "36407", "36411", "36413", "36414", "36415", "36418", "36422", "36423", "36425", "36428", "36429", "36431", "36433", "36435", "36437", "36438", "36440", "36442", "36443", "36444", "36446", "36447", "36448", "36449", "36453", "36454", "36456", "36457", "36458", "36459", "36460", "36461", "36463", "36466", "36476", "36477", "36479", "36480", "36483", "36484", "36485", "36487", "36490", "36497", "36499", "36500", "36501", "36502", "36506", "36508", "36509", "36511", "36512", "36513", "36514", "36515", "36517", "36518", "36520", "36522", "36525", "36526", "36528", "36530", "36536", "36538", "36539", "36542", "36543", "36544", "36545", "36549", "36551", "36553", "36554", "36556", "36557", "36558", "36559", "36569", "36570", "36571", "36572", "36574", "36575", "36576", "36577", "36579", "36580", "36581", "36589", "36591", "36592", "36593", "36594", "36599", "36600", "36604", "36605", "36609", "36612", "36614", "36618", "36619", "36620", "36626", "36630", "36633", "36634", "36635", "36636", "36637", "36639", "36640", "36641", "36643", "36646", "36652", "36653", "36654", "36655", "36661", "36662", "36663", "36664", "36665", "36666", "36667", "36668", "36671", "36673", "36674", "36679", "36681", "36682", "36683", "36686", "36692", "36693", "36694", "36696", "36697", "36698", "36699", "36701", "36704", "36705", "36709", "36711", "36713", "36716", "36717", "36722", "36725", "36727", "36728", "36729", "36730", "36731", "36732", "36734", "36735", "36736", "36738", "36740", "36742", "36744", "36746", "36749", "36750", "36751", "36753", "36754", "36755", "36756", "36758", "36759", "36762", "36765", "36766", "36769", "36770", "36771", "36772", "36773", "36774", "36777", "36780", "36782", "36783", "36784", "36785", "36787", "36788", "36790", "36791", "36792", "36793", "36796", "36797", "36798", "36801", "36803", "36805", "36806", "36807", "36808", "36811", "36813", "36815", "36816", "36817", "36818", "36819", "36820", "36822", "36824", "36825", "36827", "36829", "36830", "36834", "36835", "36836", "36837", "36838", "36839", "36842", "36845", "36850", "36852", "36853", "36862", "36863", "36868", "36869", "36870", "36877", "36879", "36880", "36886", "36887", "36888", "36891", "36892", "36895", "36896", "36897", "36901", "36902", "36904", "36905", "36911", "36912", "36913", "36914", "36915", "36917", "36918", "36919", "36920", "36921", "36922", "36924", "36925", "36926", "36927", "36928", "36929", "36930", "36933", "36937", "36938", "36939", "36940", "36942", "36943", "36944", "36945", "36949", "36953", "36954", "36957", "36960", "36961", "36963", "36969", "36970", "36972", "36977", "36980", "36983", "36984", "36989", "36990", "36992", "36993", "36995", "36996", "36998", "36999", "37001", "37002", "37003", "37004", "37006", "37008", "37009", "37011", "37012", "37013", "37014", "37015", "37017", "37018", "37022", "37024", "37025", "37026", "37027", "37029", "37030", "37031", "37034", "37036", "37037", "37038", "37041", "37043", "37044", "37045", "37046", "37047", "37049", "37050", "37053", "37054", "37059", "37061", "37062", "37063", "37065", "37068", "37069", "37070", "37071", "37072", "37074", "37077", "37078", "37081", "37084", "37086", "37090", "37098", "37099", "37100", "37101", "37106", "37108", "37112", "37114", "37117", "37119", "37121", "37125", "37126", "37131", "37133", "37135", "37137", "37140", "37143", "37144", "37145", "37146", "37149", "37150", "37151", "37152", "37154", "37157", "37158", "37159", "37160", "37161", "37164", "37169", "37170", "37171", "37172", "37175", "37177", "37178", "37184", "37185", "37188", "37190", "37191", "37192", "37193", "37194", "37196", "37197", "37198", "37200", "37202", "37205", "37207", "37208", "37210", "37211", "37212", "37213", "37215", "37216", "37218", "37219", "37221", "37222", "37223", "37226", "37227", "37228", "37229", "37233", "37237", "37238", "37239", "37240", "37245", "37247", "37250", "37252", "37256", "37261", "37262", "37263", "37264", "37265", "37268", "37269", "37270", "37272", "37273", "37274", "37275", "37276", "37281", "37284", "37285", "37288", "37290", "37291", "37294", "37295", "37296", "37300", "37302", "37303", "37304", "37309", "37311", "37315", "37316", "37318", "37319", "37322", "37323", "37324", "37326", "37330", "37331", "37333", "37334", "37336", "37339", "37342", "37343", "37344", "37345", "37346", "37348", "37349", "37355", "37357", "37360", "37362", "37363", "37365", "37368", "37369", "37370", "37371", "37372", "37373", "37374", "37381", "37382", "37384", "37387", "37392", "37393", "37394", "37395", "37397", "37399", "37406", "37407", "37410", "37415", "37418", "37421", "37422", "37424", "37426", "37427", "37429", "37430", "37432", "37434", "37435", "37436", "37440", "37442", "37444", "37446", "37447", "37449", "37450", "37453", "37456", "37457", "37458", "37459", "37460", "37461", "37468", "37472", "37475", "37478", "37480", "37482", "37485", "37487", "37488", "37489", "37491", "37492", "37495", "37496", "37498", "37505", "37507", "37508", "37509", "37512", "37514", "37515", "37516", "37517", "37519", "37520", "37521", "37522", "37525", "37526", "37528", "37530", "37531", "37532", "37533", "37534", "37537", "37538", "37539", "37541", "37544", "37545", "37550", "37552", "37553", "37554", "37555", "37557", "37559", "37560", "37562", "37563", "37564", "37569", "37570", "37571", "37574", "37575", "37576", "37577", "37578", "37580", "37581", "37583", "37588", "37589", "37590", "37591", "37592", "37594", "37599", "37600", "37602", "37605", "37607", "37608", "37609", "37612", "37616", "37617", "37618", "37619", "37622", "37629", "37630", "37631", "37633", "37634", "37637", "37640", "37642", "37643", "37644", "37645", "37649", "37650", "37653", "37657", "37659", "37661", "37662", "37663", "37667", "37669", "37670", "37675", "37677", "37678", "37682", "37684", "37685", "37686", "37687", "37688", "37689", "37690", "37691", "37692", "37693", "37694", "37695", "37697", "37700", "37701", "37702", "37704", "37706", "37708", "37710", "37712", "37715", "37718", "37719", "37721", "37723", "37725", "37726", "37732", "37733", "37736", "37741", "37744", "37745", "37746", "37748", "37751", "37754", "37757", "37762", "37763", "37767", "37769", "37772", "37773", "37774", "37775", "37777", "37778", "37779", "37780", "37781", "37782", "37783", "37784", "37786", "37789", "37790", "37793", "37794", "37796", "37799", "37800", "37803", "37804", "37805", "37807", "37809", "37812", "37814", "37816", "37819", "37820", "37821", "37822", "37823", "37825", "37828", "37829", "37830", "37833", "37835", "37836", "37839", "37843", "37844", "37846", "37848", "37849", "37850", "37851", "37853", "37854", "37855", "37858", "37860", "37862", "37863", "37864", "37867", "37870", "37872", "37876", "37877", "37878", "37880", "37881", "37882", "37884", "37885", "37888", "37889", "37891", "37892", "37893", "37897", "37900", "37901", "37902", "37908", "37910", "37911", "37912", "37913", "37914", "37921", "37922", "37924", "37926", "37928", "37929", "37931", "37933", "37934", "37938", "37939", "37943", "37944", "37945", "37946", "37948", "37949", "37951", "37954", "37958", "37960", "37962", "37966", "37969", "37970", "37972", "37977", "37978", "37981", "37983", "37984", "37988", "37991", "37993", "37996", "37997", "37998", "37999", "38002", "38003", "38006", "38007", "38008", "38009", "38010", "38011", "38012", "38013", "38016", "38019", "38020", "38022", "38025", "38028", "38029", "38030", "38033", "38036", "38037", "38043", "38044", "38047", "38048", "38054", "38055", "38056", "38057", "38058", "38062", "38063", "38064", "38065", "38066", "38067", "38068", "38069", "38070", "38078", "38079", "38082", "38083", "38085", "38086", "38087", "38089", "38090", "38091", "38092", "38093", "38094", "38095", "38097", "38103", "38107", "38108", "38111", "38112", "38115", "38119", "38120", "38121", "38123", "38126", "38127", "38131", "38132", "38134", "38136", "38139", "38140", "38142", "38144", "38146", "38147", "38148", "38149", "38153", "38154", "38155", "38158", "38160", "38161", "38163", "38165", "38166", "38169", "38173", "38176", "38187", "38190", "38191", "38192", "38193", "38194", "38196", "38197", "38199", "38203", "38205", "38206", "38207", "38210", "38212", "38214", "38216", "38218", "38220", "38222", "38225", "38226", "38227", "38230", "38231", "38233", "38236", "38237", "38239", "38240", "38241", "38243", "38244", "38245", "38246", "38250", "38252", "38253", "38254", "38255", "38257", "38260", "38261", "38263", "38265", "38267", "38268", "38269", "38270", "38274", "38276", "38277", "38278", "38280", "38281", "38282", "38283", "38285", "38287", "38288", "38289", "38292", "38295", "38300", "38301", "38304", "38308", "38309", "38310", "38312", "38314", "38315", "38316", "38317", "38318", "38320", "38323", "38326", "38327", "38328", "38329", "38330", "38331", "38334", "38335", "38336", "38337", "38338", "38343", "38344", "38345", "38349", "38351", "38354", "38361", "38363", "38365", "38367", "38369", "38370", "38374", "38375", "38376", "38380", "38381", "38382", "38386", "38387", "38388", "38389", "38393", "38394", "38397", "38398", "38400", "38401", "38405", "38408", "38409", "38410", "38411", "38412", "38413", "38419", "38422", "38423", "38425", "38427", "38428", "38429", "38431", "38432", "38434", "38435", "38437", "38438", "38441", "38443", "38444", "38446", "38447", "38449", "38450", "38452", "38453", "38455", "38456", "38457", "38458", "38463", "38464", "38466", "38468", "38469", "38470", "38472", "38475", "38478", "38479", "38482", "38483", "38485", "38487", "38488", "38490", "38492", "38493", "38494", "38496", "38497", "38498", "38500", "38501", "38505", "38506", "38509", "38510", "38511", "38517", "38521", "38523", "38524", "38526", "38527", "38529", "38530", "38531", "38539", "38540", "38541", "38542", "38544", "38545", "38546", "38548", "38549", "38552", "38560", "38561", "38562", "38564", "38566", "38570", "38574", "38575", "38576", "38578", "38580", "38581", "38582", "38583", "38584", "38585", "38587", "38589", "38590", "38591", "38592", "38596", "38597", "38600", "38601", "38602", "38603", "38608", "38610", "38614", "38616", "38618", "38621", "38622", "38625", "38628", "38629", "38631", "38632", "38635", "38638", "38639", "38640", "38645", "38647", "38648", "38649", "38650", "38652", "38653", "38654", "38655", "38657", "38659", "38668", "38669", "38670", "38671", "38672", "38673", "38674", "38677", "38680", "38682", "38683", "38684", "38687", "38688", "38690", "38691", "38693", "38694", "38695", "38698", "38699", "38701", "38702", "38706", "38707", "38708", "38709", "38710", "38712", "38714", "38715", "38718", "38719", "38721", "38722", "38723", "38725", "38726", "38729", "38730", "38733", "38735", "38736", "38737", "38740", "38746", "38747", "38748", "38750", "38753", "38754", "38755", "38757", "38759", "38760", "38763", "38767", "38769", "38771", "38772", "38773", "38774", "38775", "38776", "38777", "38780", "38782", "38783", "38784", "38785", "38786", "38788", "38789", "38791", "38793", "38794", "38795", "38796", "38803", "38804", "38805", "38806", "38807", "38809", "38813", "38814", "38816", "38818", "38819", "38823", "38825", "38828", "38830", "38832", "38834", "38835", "38839", "38840", "38842", "38844", "38847", "38848", "38850", "38851", "38855", "38857", "38859", "38863", "38864", "38866", "38867", "38868", "38869", "38873", "38874", "38877", "38881", "38882", "38884", "38886", "38890", "38892", "38893", "38896", "38899", "38900", "38902", "38908", "38911", "38913", "38914", "38915", "38916", "38918", "38919", "38920", "38922", "38923", "38924", "38925", "38927", "38928", "38931", "38933", "38934", "38936", "38938", "38939", "38940", "38943", "38944", "38948", "38949", "38950", "38951", "38952", "38953", "38954", "38956", "38957", "38959", "38961", "38962", "38963", "38964", "38965", "38966", "38971", "38973", "38974", "38982", "38985", "38987", "38992", "38998", "38999", "39000", "39001", "39003", "39008", "39010", "39014", "39015", "39016", "39017", "39018", "39021", "39024", "39025", "39026", "39027", "39029", "39030", "39031", "39032", "39034", "39036", "39037", "39038", "39039", "39042", "39043", "39045", "39046", "39049", "39050", "39052", "39056", "39060", "39061", "39062", "39065", "39066", "39069", "39072", "39073", "39074", "39077", "39079", "39081", "39082", "39083", "39088", "39091", "39093", "39095", "39097", "39103", "39107", "39110", "39113", "39114", "39115", "39116", "39117", "39119", "39129", "39130", "39131", "39133", "39135", "39137", "39138", "39139", "39143", "39145", "39146", "39147", "39149", "39154", "39155", "39157", "39160", "39165", "39168", "39169", "39174", "39175", "39176", "39177", "39179", "39183", "39185", "39186", "39187", "39189", "39190", "39191", "39193", "39194", "39196", "39198", "39200", "39201", "39204", "39206", "39207", "39209", "39210", "39212", "39214", "39215", "39217", "39218", "39222", "39223", "39224", "39225", "39226", "39227", "39229", "39232", "39234", "39238", "39239", "39240", "39242", "39245", "39246", "39247", "39250", "39251", "39253", "39260", "39261", "39262", "39264", "39269", "39270", "39273", "39282", "39285", "39287", "39288", "39289", "39293", "39294", "39297", "39298", "39301", "39302", "39304", "39306", "39307", "39308", "39310", "39312", "39313", "39314", "39317", "39320", "39321", "39323", "39329", "39331", "39333", "39335", "39339", "39341", "39342", "39344", "39347", "39350", "39352", "39353", "39357", "39360", "39364", "39369", "39370", "39371", "39374", "39375", "39380", "39384", "39386", "39387", "39388", "39390", "39391", "39392", "39393", "39396", "39398", "39399", "39400", "39401", "39404", "39405", "39407", "39409", "39426", "39432", "39433", "39435", "39436", "39437", "39438", "39440", "39445", "39448", "39451", "39452", "39453", "39455", "39458", "39459", "39460", "39466", "39468", "39469", "39470", "39472", "39475", "39477", "39480", "39484", "39485", "39487", "39490", "39491", "39492", "39494", "39495", "39496", "39498", "39499", "39500", "39505", "39506", "39507", "39509", "39510", "39511", "39512", "39513", "39518", "39519", "39522", "39523", "39524", "39525", "39526", "39527", "39530", "39533", "39535", "39537", "39539", "39541", "39543", "39545", "39546", "39548", "39552", "39553", "39554", "39555", "39556", "39557", "39558", "39560", "39563", "39564", "39567", "39570", "39571", "39576", "39579", "39582", "39586", "39587", "39589", "39590", "39591", "39595", "39597", "39599", "39601", "39605", "39608", "39609", "39610", "39612", "39613", "39614", "39615", "39618", "39620", "39621", "39622", "39623", "39624", "39626", "39627", "39629", "39630", "39632", "39633", "39635", "39636", "39639", "39640", "39642", "39646", "39650", "39651", "39652", "39653", "39654", "39655", "39656", "39657", "39658", "39659", "39661", "39662", "39663", "39664", "39668", "39669", "39671", "39673", "39674", "39675", "39676", "39677", "39678", "39684", "39685", "39686", "39688", "39689", "39690", "39694", "39699", "39702", "39703", "39704", "39705", "39707", "39708", "39712", "39713", "39714", "39719", "39720", "39722", "39723", "39725", "39726", "39727", "39728", "39729", "39732", "39734", "39735", "39736", "39737", "39738", "39739", "39740", "39741", "39744", "39746", "39747", "39753", "39754", "39755", "39758", "39760", "39761", "39762", "39763", "39765", "39766", "39768", "39769", "39771", "39773", "39774", "39775", "39776", "39777", "39778", "39784", "39785", "39786", "39787", "39788", "39792", "39794", "39797", "39801", "39802", "39805", "39806", "39808", "39809", "39810", "39811", "39812", "39816", "39818", "39819", "39820", "39821", "39822", "39825", "39828", "39829", "39830", "39831", "39833", "39834", "39836", "39841", "39842", "39843", "39858", "39860", "39861", "39863", "39867", "39868", "39869", "39871", "39872", "39873", "39875", "39876", "39879", "39880", "39883", "39885", "39887", "39889", "39893", "39896", "39897", "39898", "39900", "39903", "39905", "39906", "39908", "39910", "39913", "39914", "39916", "39918", "39920", "39923", "39926", "39928", "39930", "39934", "39935", "39941", "39942", "39947", "39948", "39952", "39953", "39954", "39955", "39957", "39958", "39961", "39967", "39969", "39971", "39972", "39973", "39977", "39983", "39985", "39986", "39987", "39988", "39989", "39991", "39992", "39993", "39995", "39998", "39999", "40001", "40005", "40006", "40007", "40008", "40009", "40010", "40011", "40013", "40014", "40015", "40016", "40021", "40024", "40027", "40030", "40031", "40032", "40033", "40034", "40035", "40037", "40040", "40045", "40046", "40048", "40050", "40051", "40052", "40053", "40054", "40058", "40060", "40061", "40064", "40065", "40066", "40067", "40068", "40071", "40072", "40073", "40075", "40081", "40083", "40086", "40090", "40093", "40095", "40096", "40098", "40099", "40103", "40106", "40107", "40110", "40112", "40113", "40115", "40116", "40118", "40119", "40122", "40123", "40124", "40126", "40129", "40135", "40136", "40137", "40138", "40139", "40143", "40146", "40147", "40150", "40151", "40152", "40153", "40154", "40157", "40158", "40159", "40162", "40164", "40165", "40166", "40167", "40168", "40169", "40170", "40175", "40176", "40177", "40179", "40180", "40181", "40183", "40184", "40185", "40187", "40189", "40190", "40191", "40192", "40193", "40199", "40201", "40204", "40207", "40211", "40215", "40220", "40223", "40224", "40226", "40227", "40228", "40230", "40231", "40232", "40234", "40235", "40237", "40239", "40242", "40243", "40244", "40245", "40247", "40248", "40252", "40253", "40254", "40255", "40256", "40258", "40259", "40262", "40263", "40265", "40268", "40269", "40273", "40275", "40276", "40277", "40278", "40281", "40283", "40284", "40287", "40288", "40290", "40291", "40292", "40294", "40296", "40298", "40299", "40304", "40306", "40307", "40309", "40310", "40312", "40313", "40318", "40319", "40320", "40321", "40324", "40331", "40339", "40341", "40342", "40344", "40348", "40350", "40351", "40352", "40356", "40357", "40359", "40362", "40363", "40364", "40366", "40368", "40371", "40372", "40373", "40374", "40375", "40376", "40378", "40379", "40381", "40383", "40384", "40390", "40392", "40394", "40396", "40397", "40399", "40400", "40401", "40402", "40404", "40407", "40408", "40409", "40412", "40414", "40418", "40419", "40421", "40422", "40423", "40424", "40426", "40431", "40433", "40434", "40435", "40438", "40440", "40442", "40444", "40449", "40450", "40451", "40452", "40453", "40454", "40455", "40458", "40459", "40460", "40466", "40467", "40474", "40475", "40478", "40480", "40485", "40486", "40489", "40490", "40493", "40494", "40495", "40496", "40497", "40499", "40500", "40503", "40506", "40507", "40508", "40509", "40510", "40511", "40512", "40513", "40515", "40516", "40518", "40519", "40521", "40523", "40524", "40527", "40528", "40529", "40530", "40531", "40532", "40533", "40536", "40537", "40538", "40542", "40546", "40549", "40550", "40553", "40555", "40556", "40558", "40560", "40566", "40567", "40568", "40576", "40578", "40581", "40582", "40583", "40586", "40587", "40590", "40591", "40592", "40595", "40596", "40597", "40598", "40599", "40600", "40602", "40605", "40609", "40610", "40611", "40612", "40613", "40615", "40616", "40617", "40619", "40622", "40623", "40624", "40630", "40637", "40642", "40643", "40644", "40646", "40648", "40651", "40652", "40655", "40656", "40659", "40660", "40661", "40662", "40663", "40664", "40665", "40671", "40672", "40673", "40675", "40676", "40678", "40680", "40681", "40682", "40684", "40685", "40687", "40688", "40689", "40693", "40694", "40695", "40698", "40704", "40705", "40709", "40711", "40713", "40718", "40721", "40722", "40723", "40724", "40725", "40727", "40731", "40732", "40733", "40734", "40735", "40736", "40738", "40739", "40741", "40742", "40745", "40746", "40748", "40751", "40752", "40753", "40760", "40763", "40764", "40766", "40768", "40769", "40774", "40775", "40776", "40777", "40779", "40780", "40782", "40784", "40786", "40787", "40788", "40790", "40792", "40793", "40797", "40798", "40800", "40801", "40802", "40803", "40804", "40806", "40807", "40810", "40813", "40814", "40816", "40818", "40820", "40821", "40824", "40826", "40827", "40829", "40836", "40839", "40841", "40845", "40850", "40851", "40852", "40853", "40854", "40858", "40859", "40861", "40862", "40863", "40864", "40866", "40867", "40869", "40870", "40872", "40873", "40876", "40877", "40878", "40879", "40880", "40881", "40882", "40883", "40884", "40886", "40888", "40889", "40895", "40896", "40897", "40901", "40903", "40906", "40908", "40910", "40913", "40914", "40924", "40925", "40926", "40928", "40932", "40933", "40935", "40937", "40938", "40939", "40941", "40945", "40949", "40950", "40951", "40952", "40953", "40957", "40958", "40959", "40963", "40964", "40966", "40969", "40970", "40971", "40972", "40973", "40974", "40979", "40984", "40986", "40987", "40988", "40989", "40990", "40993", "40995", "40996", "40997", "40998", "40999", "41003", "41005", "41006", "41007", "41012", "41015", "41016", "41017", "41018", "41020", "41022", "41029", "41032", "41033", "41034", "41035", "41036", "41037", "41040", "41044", "41046", "41047", "41050", "41055", "41056", "41057", "41058", "41060", "41061", "41063", "41067", "41069", "41072", "41074", "41077", "41079", "41083", "41085", "41087", "41088", "41091", "41093", "41094", "41095", "41100", "41104", "41105", "41107", "41108", "41109", "41111", "41114", "41116", "41117", "41118", "41119", "41122", "41124", "41125", "41126", "41129", "41130", "41131", "41133", "41134", "41135", "41137", "41140", "41141", "41142", "41143", "41145", "41147", "41148", "41149", "41151", "41152", "41153", "41156", "41159", "41162", "41164", "41165", "41166", "41167", "41170", "41171", "41173", "41177", "41178", "41179", "41180", "41181", "41184", "41190", "41191", "41193", "41194", "41195", "41198", "41201", "41203", "41206", "41211", "41215", "41217", "41218", "41220", "41224", "41225", "41226", "41230", "41231", "41232", "41233", "41234", "41236", "41239", "41240", "41241", "41250", "41253", "41255", "41256", "41258", "41259", "41260", "41263", "41266", "41267", "41270", "41271", "41272", "41274", "41275", "41279", "41280", "41281", "41283", "41284", "41285", "41288", "41289", "41293", "41294", "41295", "41300", "41305", "41306", "41307", "41308", "41311", "41313", "41314", "41315", "41316", "41317", "41318", "41319", "41320", "41324", "41325", "41329", "41334", "41335", "41338", "41340", "41342", "41343", "41345", "41347", "41349", "41350", "41352", "41353", "41355", "41356", "41357", "41358", "41359", "41362", "41363", "41364", "41365", "41367", "41368", "41369", "41370", "41371", "41372", "41375", "41376", "41377", "41381", "41383", "41384", "41386", "41388", "41389", "41393", "41394", "41395", "41396", "41397", "41398", "41400", "41401", "41402", "41405", "41409", "41410", "41412", "41418", "41419", "41421", "41423", "41425", "41426", "41428", "41434", "41437", "41440", "41442", "41444", "41445", "41447", "41449", "41451", "41452", "41454", "41456", "41459", "41461", "41464", "41470", "41474", "41475", "41476", "41478", "41480", "41481", "41483", "41484", "41487", "41490", "41491", "41492", "41493", "41494", "41495", "41496", "41497", "41498", "41499", "41500", "41501", "41502", "41505", "41506", "41509", "41510", "41511", "41513", "41515", "41518", "41519", "41521", "41524", "41526", "41528", "41532", "41534", "41535", "41537", "41539", "41541", "41544", "41545", "41547", "41548", "41549", "41551", "41553", "41554", "41555", "41556", "41557", "41558", "41562", "41565", "41566", "41567", "41568", "41570", "41571", "41573", "41574", "41575", "41577", "41578", "41580", "41581", "41583", "41586", "41587", "41588", "41590", "41591", "41592", "41594", "41598", "41600", "41602", "41604", "41605", "41606", "41610", "41611", "41613", "41618", "41620", "41622", "41624", "41630", "41632", "41635", "41638", "41640", "41642", "41643", "41648", "41650", "41651", "41656", "41657", "41658", "41660", "41663", "41665", "41666", "41667", "41672", "41674", "41676", "41678", "41681", "41683", "41684", "41686", "41687", "41689", "41691", "41695", "41696", "41699", "41701", "41703", "41706", "41711", "41712", "41713", "41714", "41716", "41723", "41726", "41727", "41728", "41729", "41733", "41734", "41736", "41739", "41741", "41743", "41744", "41745", "41746", "41748", "41755", "41756", "41757", "41761", "41763", "41765", "41767", "41770", "41773", "41774", "41777", "41778", "41779", "41780", "41785", "41786", "41787", "41788", "41791", "41792", "41794", "41797", "41800", "41803", "41804", "41807", "41810", "41812", "41813", "41814", "41815", "41816", "41817", "41818", "41819", "41820", "41822", "41826", "41828", "41830", "41833", "41834", "41835", "41838", "41839", "41844", "41846", "41847", "41849", "41854", "41855", "41856", "41857", "41859", "41861", "41862", "41863", "41865", "41868", "41869", "41870", "41871", "41874", "41878", "41880", "41881", "41882", "41883", "41884", "41886", "41887", "41888", "41890", "41892", "41896", "41897", "41899", "41907", "41909", "41913", "41914", "41916", "41918", "41919", "41920", "41921", "41922", "41927", "41928", "41931", "41932", "41934", "41936", "41937", "41938", "41940", "41943", "41944", "41947", "41948", "41949", "41954", "41955", "41956", "41957", "41961", "41962", "41963", "41964", "41967", "41968", "41969", "41970", "41972", "41973", "41975", "41977", "41978", "41979", "41980", "41981", "41982", "41983", "41984", "41985", "41986", "41987", "41989", "41993", "41994", "41995", "41996", "41998", "41999", "42003", "42004", "42005", "42006", "42010", "42011", "42013", "42016", "42017", "42019", "42020", "42021", "42025", "42027", "42028", "42031", "42032", "42034", "42038", "42041", "42043", "42044", "42045", "42050", "42051", "42053", "42054", "42055", "42056", "42057", "42059", "42061", "42063", "42064", "42067", "42068", "42069", "42070", "42072", "42074", "42075", "42077", "42078", "42081", "42083", "42085", "42086", "42089", "42092", "42093", "42096", "42098", "42099", "42101", "42105", "42107", "42109", "42111", "42114", "42115", "42116", "42117", "42118", "42124", "42126", "42127", "42128", "42129", "42131", "42132", "42137", "42139", "42140", "42141", "42144", "42145", "42152", "42153", "42154", "42155", "42159", "42161", "42163", "42164", "42166", "42167", "42169", "42171", "42172", "42173", "42175", "42178", "42180", "42181", "42191", "42193", "42196", "42197", "42198", "42202", "42204", "42207", "42209", "42210", "42211", "42213", "42219", "42220", "42225", "42226", "42227", "42229", "42232", "42235", "42237", "42243", "42246", "42248", "42254", "42256", "42258", "42259", "42260", "42262", "42263", "42265", "42266", "42267", "42268", "42270", "42274", "42275", "42276", "42278", "42280", "42283", "42284", "42285", "42286", "42292", "42293", "42296", "42297", "42301", "42310", "42313", "42314", "42315", "42316", "42318", "42322", "42323", "42324", "42325", "42326", "42328", "42330", "42331", "42334", "42335", "42337", "42339", "42340", "42341", "42342", "42343", "42344", "42345", "42346", "42347", "42348", "42349", "42352", "42354", "42355", "42357", "42358", "42360", "42361", "42362", "42364", "42366", "42367", "42368", "42372", "42373", "42375", "42376", "42377", "42378", "42380", "42381", "42382", "42383", "42384", "42391", "42394", "42398", "42399", "42401", "42403", "42407", "42409", "42410", "42411", "42413", "42414", "42415", "42416", "42417", "42418", "42420", "42421", "42422", "42424", "42428", "42430", "42432", "42434", "42435", "42436", "42437", "42438", "42441", "42444", "42446", "42447", "42453", "42454", "42456", "42459", "42460", "42461", "42465", "42466", "42470", "42472", "42475", "42476", "42481", "42483", "42484", "42486", "42487", "42489", "42490", "42491", "42495", "42497", "42499", "42500", "42501", "42504", "42505", "42509", "42510", "42516", "42517", "42519", "42520", "42522", "42523", "42524", "42525", "42526", "42527", "42528", "42533", "42534", "42535", "42536", "42538", "42542", "42545", "42547", "42548", "42550", "42551", "42554", "42555", "42557", "42558", "42560", "42561", "42564", "42565", "42567", "42569", "42571", "42572", "42573", "42576", "42577", "42580", "42582", "42584", "42587", "42590", "42593", "42594", "42596", "42598", "42599", "42602", "42606", "42609", "42612", "42615", "42618", "42621", "42622", "42623", "42624", "42625", "42626", "42635", "42637", "42641", "42643", "42645", "42648", "42651", "42655", "42656", "42659", "42660", "42666", "42667", "42669", "42670", "42671", "42672", "42673", "42674", "42675", "42676", "42678", "42680", "42681", "42682", "42686", "42687", "42690", "42692", "42693", "42697", "42698", "42699", "42700", "42705", "42706", "42707", "42711", "42712", "42713", "42714", "42716", "42717", "42718", "42719", "42721", "42723", "42724", "42727", "42728", "42729", "42731", "42733", "42734", "42738", "42741", "42745", "42749", "42750", "42752", "42757", "42759", "42760", "42764", "42765", "42769", "42771", "42772", "42773", "42774", "42776", "42781", "42782", "42783", "42784", "42786", "42788", "42789", "42791", "42792", "42793", "42794", "42797", "42798", "42802", "42806", "42807", "42808", "42810", "42811", "42814", "42817", "42821", "42822", "42824", "42825", "42826", "42828", "42829", "42830", "42831", "42832", "42833", "42834", "42835", "42836", "42840", "42841", "42842", "42844", "42845", "42849", "42850", "42851", "42852", "42853", "42854", "42855", "42856", "42857", "42858", "42859", "42862", "42863", "42865", "42867", "42868", "42870", "42872", "42875", "42876", "42877", "42878", "42880", "42882", "42884", "42885", "42887", "42889", "42890", "42892", "42894", "42897", "42900", "42903", "42904", "42905", "42907", "42908", "42909", "42913", "42914", "42916", "42919", "42920", "42922", "42925", "42926", "42929", "42933", "42934", "42935", "42936", "42937", "42938", "42947", "42948", "42951", "42956", "42957", "42961", "42962", "42963", "42965", "42967", "42968", "42973", "42974", "42975", "42977", "42980", "42982", "42983", "42984", "42985", "42987", "42988", "42989", "42990", "42995", "42996", "42999", "43001", "43002", "43003", "43006", "43013", "43019", "43022", "43023", "43027", "43029", "43032", "43038", "43039", "43041", "43042", "43047", "43048", "43051", "43054", "43055", "43060", "43061", "43062", "43064", "43065", "43067", "43068", "43069", "43070", "43071", "43072", "43077", "43079", "43080", "43081", "43085", "43086", "43087", "43088", "43089", "43094", "43100", "43101", "43102", "43107", "43108", "43113", "43114", "43117", "43118", "43121", "43122", "43124", "43125", "43127", "43129", "43130", "43132", "43133", "43134", "43135", "43138", "43141", "43142", "43146", "43147", "43150", "43152", "43156", "43157", "43160", "43167", "43170", "43172", "43175", "43178", "43179", "43180", "43181", "43182", "43183", "43184", "43185", "43187", "43190", "43192", "43194", "43196", "43198", "43199", "43200", "43202", "43205", "43207", "43208", "43209", "43211", "43214", "43216", "43219", "43223", "43226", "43227", "43228", "43229", "43230", "43233", "43234", "43235", "43237", "43238", "43239", "43240", "43241", "43244", "43245", "43246", "43247", "43249", "43250", "43252", "43254", "43256", "43257", "43260", "43261", "43262", "43263", "43265", "43266", "43267", "43268", "43269", "43270", "43271", "43272", "43274", "43275", "43276", "43279", "43281", "43284", "43286", "43287", "43289", "43291", "43295", "43296", "43297", "43299", "43303", "43306", "43308", "43309", "43312", "43314", "43315", "43318", "43321", "43324", "43325", "43330", "43331", "43332", "43334", "43335", "43338", "43339", "43340", "43341", "43344", "43345", "43346", "43347", "43348", "43349", "43350", "43351", "43355", "43356", "43357", "43358", "43360", "43365", "43366", "43367", "43368", "43370", "43371", "43373", "43374", "43378", "43379", "43382", "43386", "43389", "43390", "43392", "43397", "43401", "43402", "43408", "43409", "43410", "43411", "43412", "43415", "43419", "43420", "43422", "43423", "43426", "43427", "43430", "43431", "43432", "43433", "43437", "43439", "43441", "43442", "43443", "43446", "43447", "43448", "43450", "43453", "43454", "43456", "43458", "43459", "43460", "43461", "43462", "43465", "43467", "43469", "43471", "43473", "43474", "43476", "43481", "43483", "43484", "43485", "43486", "43490", "43495", "43498", "43500", "43501", "43502", "43508", "43509", "43510", "43520", "43521", "43524", "43525", "43526", "43527", "43528", "43532", "43533", "43534", "43540", "43542", "43543", "43544", "43548", "43549", "43555", "43556", "43558", "43559", "43563", "43566", "43567", "43570", "43571", "43575", "43576", "43580", "43581", "43583", "43584", "43586", "43587", "43588", "43589", "43590", "43592", "43594", "43595", "43596", "43598", "43599", "43600", "43601", "43605", "43606", "43607", "43610", "43612", "43614", "43616", "43617", "43622", "43623", "43625", "43626", "43627", "43630", "43631", "43632", "43636", "43638", "43642", "43643", "43644", "43645", "43647", "43650", "43651", "43653", "43658", "43659", "43663", "43665", "43666", "43667", "43669", "43670", "43677", "43678", "43679", "43680", "43683", "43685", "43689", "43691", "43692", "43693", "43694", "43697", "43698", "43699", "43703", "43708", "43711", "43716", "43718", "43720", "43722", "43723", "43724", "43725", "43726", "43730", "43731", "43734", "43739", "43741", "43742", "43744", "43747", "43748", "43749", "43751", "43752", "43760", "43763", "43764", "43768", "43770", "43776", "43780", "43782", "43783", "43787", "43788", "43789", "43791", "43793", "43795", "43796", "43798", "43799", "43804", "43805", "43808", "43809", "43815", "43816", "43817", "43818", "43819", "43820", "43821", "43822", "43823", "43825", "43826", "43828", "43830", "43833", "43834", "43838", "43842", "43843", "43844", "43847", "43848", "43850", "43851", "43857", "43860", "43861", "43863", "43866", "43867", "43868", "43869", "43870", "43872", "43873", "43874", "43875", "43877", "43878", "43879", "43880", "43881", "43882", "43883", "43884", "43886", "43887", "43888", "43892", "43898", "43899", "43903", "43907", "43908", "43912", "43914", "43916", "43917", "43918", "43921", "43922", "43923", "43925", "43931", "43932", "43934", "43936", "43939", "43944", "43946", "43948", "43951", "43952", "43956", "43957", "43959", "43960", "43963", "43966", "43968", "43969", "43970", "43971", "43972", "43975", "43976", "43978", "43979", "43982", "43983", "43984", "43985", "43986", "43989", "43990", "43993", "43994", "43997", "43998", "44001", "44003", "44005", "44007", "44008", "44009", "44010", "44012", "44013", "44016", "44018", "44019", "44023", "44025", "44026", "44027", "44029", "44030", "44031", "44032", "44034", "44035", "44036", "44038", "44040", "44041", "44042", "44044", "44046", "44048", "44050", "44051", "44053", "44054", "44055", "44057", "44059", "44060", "44062", "44068", "44069", "44071", "44073", "44074", "44075", "44076", "44080", "44081", "44084", "44085", "44086", "44090", "44091", "44092", "44094", "44097", "44098", "44099", "44100", "44101", "44102", "44104", "44106", "44107", "44108", "44110", "44112", "44115", "44116", "44118", "44119", "44120", "44121", "44123", "44124", "44125", "44126", "44127", "44128", "44129", "44131", "44133", "44136", "44137", "44138", "44142", "44144", "44145", "44146", "44147", "44148", "44149", "44150", "44153", "44156", "44157", "44161", "44162", "44164", "44165", "44166", "44171", "44174", "44178", "44180", "44181", "44182", "44183", "44184", "44185", "44187", "44188", "44189", "44192", "44193", "44196", "44197", "44200", "44201", "44203", "44204", "44207", "44210", "44212", "44214", "44215", "44221", "44225", "44228", "44232", "44233", "44235", "44236", "44237", "44238", "44239", "44240", "44241", "44242", "44246", "44247", "44248", "44249", "44250", "44251", "44253", "44256", "44261", "44263", "44268", "44269", "44270", "44273", "44274", "44275", "44278", "44282", "44284", "44286", "44288", "44292", "44293", "44295", "44296", "44297", "44298", "44304", "44305", "44306", "44308", "44309", "44311", "44313", "44314", "44318", "44319", "44321", "44323", "44326", "44328", "44329", "44330", "44334", "44335", "44337", "44340", "44341", "44342", "44345", "44346", "44347", "44348", "44351", "44353", "44356", "44358", "44359", "44360", "44361", "44362", "44364", "44365", "44367", "44369", "44371", "44372", "44373", "44374", "44376", "44377", "44379", "44380", "44385", "44389", "44390", "44395", "44396", "44398", "44401", "44403", "44404", "44407", "44408", "44409", "44410", "44411", "44412", "44413", "44415", "44416", "44418", "44420", "44421", "44424", "44425", "44428", "44429", "44430", "44432", "44433", "44435", "44436", "44440", "44441", "44443", "44444", "44446", "44447", "44448", "44449", "44451", "44455", "44457", "44458", "44459", "44460", "44462", "44463", "44464", "44467", "44469", "44472", "44474", "44475", "44478", "44481", "44482", "44484", "44485", "44486", "44490", "44491", "44496", "44497", "44498", "44499", "44502", "44503", "44504", "44505", "44507", "44515", "44517", "44522", "44523", "44525", "44531", "44534", "44539", "44541", "44544", "44547", "44548", "44550", "44556", "44560", "44561", "44564", "44565", "44566", "44571", "44572", "44576", "44579", "44582", "44584", "44585", "44587", "44588", "44589", "44591", "44594", "44595", "44598", "44602", "44604", "44608", "44609", "44616", "44619", "44620", "44623", "44624", "44627", "44628", "44633", "44634", "44636", "44637", "44639", "44641", "44645", "44651", "44654", "44657", "44660", "44661", "44662", "44667", "44669", "44670", "44672", "44674", "44675", "44677", "44678", "44679", "44680", "44685", "44689", "44690", "44692", "44693", "44694", "44696", "44697", "44699", "44700", "44702", "44703", "44704", "44706", "44707", "44708", "44710", "44711", "44712", "44713", "44715", "44716", "44719", "44720", "44721", "44724", "44726", "44727", "44731", "44733", "44736", "44738", "44739", "44740", "44742", "44743", "44744", "44746", "44748", "44749", "44750", "44751", "44759", "44760", "44762", "44763", "44764", "44768", "44770", "44771", "44775", "44776", "44778", "44779", "44781", "44782", "44784", "44785", "44786", "44787", "44788", "44790", "44791", "44796", "44799", "44802", "44803", "44804", "44805", "44806", "44808", "44810", "44813", "44816", "44817", "44818", "44823", "44831", "44832", "44834", "44835", "44839", "44840", "44841", "44844", "44849", "44850", "44851", "44852", "44853", "44854", "44855", "44857", "44860", "44863", "44864", "44867", "44868", "44874", "44876", "44877", "44884", "44885", "44886", "44887", "44888", "44890", "44891", "44893", "44894", "44899", "44900", "44904", "44905", "44907", "44908", "44909", "44915", "44916", "44917", "44918", "44919", "44921", "44923", "44924", "44925", "44926", "44930", "44932", "44933", "44934", "44936", "44937", "44940", "44941", "44943", "44944", "44945", "44949", "44952", "44957", "44959", "44963", "44965", "44966", "44967", "44968", "44969", "44970", "44971", "44979", "44980", "44981", "44982", "44983", "44984", "44985", "44987", "44989", "44990", "44992", "44997", "45000", "45001", "45003", "45006", "45012", "45014", "45015", "45016", "45022", "45024", "45025", "45029", "45031", "45032", "45033", "45035", "45037", "45038", "45043", "45044", "45046", "45048", "45049", "45050", "45052", "45053", "45054", "45061", "45062", "45063", "45064", "45065", "45067", "45068", "45070", "45071", "45073", "45074", "45077", "45078", "45082", "45083", "45084", "45085", "45086", "45089", "45091", "45092", "45094", "45096", "45099", "45101", "45102", "45103", "45105", "45106", "45107", "45108", "45115", "45116", "45118", "45120", "45121", "45123", "45124", "45125", "45126", "45128", "45134", "45136", "45137", "45139", "45140", "45142", "45145", "45146", "45147", "45149", "45150", "45154", "45155", "45156", "45157", "45158", "45160", "45162", "45164", "45165", "45168", "45169", "45171", "45173", "45176", "45178", "45179", "45180", "45181", "45182", "45186", "45187", "45189", "45190", "45197", "45198", "45201", "45202", "45205", "45211", "45217", "45220", "45223", "45224", "45227", "45229", "45230", "45231", "45233", "45235", "45236", "45237", "45239", "45240", "45241", "45243", "45244", "45245", "45246", "45248", "45249", "45251", "45252", "45254", "45258", "45260", "45267", "45268", "45269", "45274", "45275", "45276", "45278", "45282", "45283", "45284", "45285", "45286", "45288", "45290", "45291", "45295", "45296", "45298", "45299", "45300", "45301", "45302", "45304", "45305", "45309", "45311", "45312", "45313", "45320", "45324", "45326", "45327", "45328", "45329", "45333", "45334", "45335", "45336", "45337", "45338", "45339", "45340", "45342", "45347", "45349", "45352", "45353", "45354", "45355", "45358", "45362", "45363", "45368", "45370", "45372", "45373", "45374", "45375", "45378", "45379", "45380", "45382", "45383", "45387", "45388", "45391", "45393", "45396", "45397", "45399", "45402", "45403", "45406", "45407", "45408", "45409", "45412", "45413", "45414", "45415", "45418", "45421", "45422", "45423", "45427", "45429", "45430", "45431", "45432", "45434", "45438", "45439", "45440", "45442", "45445", "45446", "45449", "45450", "45452", "45455", "45456", "45457", "45458", "45460", "45461", "45463", "45464", "45467", "45469", "45470", "45471", "45472", "45478", "45479", "45483", "45487", "45490", "45492", "45493", "45494", "45496", "45499", "45501", "45505", "45506", "45509", "45514", "45515", "45517", "45518", "45520", "45521", "45522", "45523", "45524", "45526", "45529", "45530", "45532", "45533", "45535", "45536", "45539", "45542", "45544", "45546", "45547", "45551", "45555", "45559", "45562", "45564", "45565", "45566", "45567", "45568", "45569", "45572", "45575", "45579", "45580", "45581", "45584", "45586", "45587", "45588", "45589", "45593", "45594", "45595", "45596", "45598", "45599", "45602", "45604", "45607", "45609", "45612", "45613", "45614", "45615", "45616", "45617", "45620", "45621", "45622", "45623", "45625", "45626", "45629", "45630", "45631", "45632", "45633", "45638", "45639", "45640", "45642", "45643", "45644", "45645", "45646", "45647", "45648", "45649", "45652", "45653", "45654", "45655", "45656", "45657", "45661", "45662", "45663", "45664", "45665", "45666", "45674", "45675", "45676", "45677", "45679", "45680", "45684", "45685", "45687", "45689", "45690", "45691", "45692", "45694", "45695", "45697", "45699", "45700", "45701", "45704", "45705", "45707", "45709", "45710", "45712", "45714", "45715", "45717", "45718", "45719", "45720", "45722", "45723", "45724", "45726", "45727", "45728", "45731", "45732", "45735", "45736", "45741", "45743", "45744", "45749", "45752", "45753", "45754", "45756", "45760", "45768", "45770", "45771", "45772", "45776", "45777", "45778", "45779", "45781", "45783", "45784", "45787", "45792", "45801", "45806", "45807", "45808", "45809", "45812", "45813", "45816", "45819", "45820", "45824", "45825", "45830", "45831", "45833", "45834", "45835", "45836", "45838", "45841", "45845", "45846", "45848", "45849", "45855", "45856", "45860", "45863", "45866", "45867", "45868", "45869", "45871", "45872", "45874", "45875", "45876", "45877", "45879", "45880", "45883", "45885", "45886", "45887", "45889", "45890", "45893", "45894", "45898", "45900", "45901", "45906", "45909", "45913", "45915", "45919", "45920", "45922", "45924", "45925", "45926", "45928", "45934", "45935", "45937", "45940", "45942", "45943", "45944", "45945", "45946", "45947", "45949", "45951", "45952", "45957", "45959", "45961", "45964", "45965", "45968", "45970", "45976", "45977", "45978", "45980", "45981", "45982", "45983", "45985", "45986", "45988", "45992", "45993", "46003", "46004", "46005", "46012", "46014", "46017", "46018", "46019", "46021", "46022", "46023", "46029", "46032", "46033", "46036", "46037", "46041", "46043", "46047", "46048", "46051", "46052", "46055", "46057", "46058", "46059", "46062", "46063", "46068", "46069", "46071", "46072", "46074", "46075", "46080", "46081", "46084", "46085", "46089", "46091", "46095", "46096", "46097", "46098", "46099", "46100", "46103", "46104", "46105", "46107", "46109", "46111", "46112", "46113", "46115", "46119", "46121", "46122", "46123", "46124", "46127", "46129", "46130", "46131", "46133", "46134", "46135", "46136", "46137", "46138", "46139", "46141", "46144", "46146", "46147", "46149", "46150", "46154", "46155", "46158", "46159", "46164", "46165", "46171", "46172", "46173", "46174", "46177", "46178", "46185", "46186", "46188", "46189", "46190", "46191", "46194", "46199", "46200", "46206", "46209", "46212", "46214", "46215", "46216", "46219", "46222", "46223", "46224", "46225", "46231", "46233", "46235", "46236", "46243", "46246", "46248", "46249", "46257", "46259", "46264", "46265", "46267", "46268", "46269", "46272", "46273", "46278", "46279", "46280", "46281", "46282", "46283", "46284", "46286", "46288", "46290", "46295", "46296", "46297", "46298", "46300", "46301", "46303", "46307", "46308", "46310", "46311", "46313", "46316", "46321", "46328", "46331", "46332", "46333", "46336", "46337", "46338", "46339", "46341", "46342", "46344", "46348", "46349", "46350", "46351", "46352", "46353", "46355", "46356", "46359", "46360", "46361", "46362", "46364", "46366", "46370", "46371", "46372", "46376", "46378", "46379", "46380", "46385", "46386", "46390", "46391", "46395", "46398", "46399", "46401", "46402", "46403", "46404", "46406", "46407", "46411", "46413", "46414", "46415", "46421", "46422", "46423", "46424", "46426", "46427", "46428", "46432", "46437", "46438", "46439", "46440", "46441", "46442", "46443", "46444", "46446", "46447", "46448", "46450", "46452", "46455", "46456", "46459", "46461", "46462", "46463", "46464", "46467", "46471", "46472", "46474", "46475", "46476", "46477", "46478", "46480", "46484", "46485", "46486", "46490", "46491", "46494", "46495", "46503", "46505", "46507", "46508", "46510", "46511", "46512", "46517", "46519", "46520", "46522", "46524", "46526", "46527", "46528", "46531", "46532", "46534", "46537", "46541", "46542", "46543", "46545", "46546", "46549", "46553", "46560", "46562", "46564", "46567", "46568", "46569", "46570", "46571", "46572", "46573", "46574", "46580", "46585", "46587", "46588", "46589", "46591", "46592", "46601", "46603", "46605", "46606", "46607", "46609", "46610", "46611", "46616", "46617", "46621", "46622", "46623", "46625", "46627", "46632", "46633", "46639", "46640", "46641", "46642", "46646", "46648", "46649", "46650", "46652", "46653", "46655", "46657", "46658", "46659", "46661", "46665", "46666", "46667", "46668", "46669", "46670", "46671", "46679", "46680", "46681", "46683", "46684", "46685", "46686", "46687", "46688", "46689", "46694", "46699", "46702", "46704", "46705", "46707", "46710", "46711", "46713", "46716", "46719", "46721", "46722", "46723", "46725", "46726", "46729", "46734", "46735", "46736", "46740", "46741", "46744", "46746", "46747", "46749", "46751", "46754", "46759", "46761", "46762", "46764", "46765", "46766", "46767", "46768", "46769", "46772", "46773", "46774", "46775", "46777", "46781", "46784", "46785", "46786", "46788", "46789", "46791", "46793", "46794", "46795", "46797", "46798", "46802", "46806", "46810", "46812", "46814", "46816", "46820", "46824", "46827", "46828", "46830", "46833", "46835", "46837", "46838", "46841", "46842", "46848", "46850", "46851", "46852", "46853", "46854", "46855", "46857", "46858", "46859", "46863", "46868", "46869", "46872", "46873", "46874", "46875", "46876", "46877", "46881", "46884", "46885", "46888", "46889", "46890", "46894", "46896", "46898", "46899", "46901", "46906", "46907", "46908", "46910", "46912", "46913", "46914", "46915", "46916", "46917", "46918", "46922", "46924", "46925", "46926", "46927", "46928", "46930", "46932", "46933", "46937", "46939", "46940", "46946", "46947", "46948", "46951", "46952", "46954", "46956", "46959", "46961", "46962", "46963", "46965", "46966", "46971", "46973", "46975", "46980", "46983", "46986", "46989", "46991", "46993", "46994", "46995", "46998", "46999", "47000", "47003", "47004", "47005", "47009", "47011", "47013", "47015", "47016", "47019", "47021", "47025", "47027", "47029", "47030", "47034", "47035", "47036", "47042", "47043", "47046", "47048", "47049", "47053", "47056", "47057", "47058", "47059", "47060", "47062", "47063", "47064", "47066", "47067", "47069", "47071", "47075", "47076", "47077", "47078", "47079", "47081", "47083", "47085", "47086", "47088", "47089", "47090", "47092", "47093", "47095", "47096", "47098", "47099", "47101", "47103", "47104", "47106", "47108", "47115", "47117", "47119", "47122", "47130", "47131", "47132", "47133", "47135", "47137", "47138", "47139", "47140", "47142", "47144", "47146", "47147", "47148", "47149", "47150", "47151", "47154", "47155", "47166", "47169", "47170", "47172", "47174", "47176", "47177", "47178", "47182", "47183", "47186", "47187", "47188", "47189", "47190", "47191", "47192", "47197", "47199", "47204", "47205", "47206", "47211", "47214", "47215", "47216", "47217", "47218", "47221", "47222", "47223", "47225", "47229", "47231", "47233", "47234", "47235", "47236", "47238", "47239", "47240", "47244", "47245", "47249", "47255", "47257", "47259", "47262", "47263", "47264", "47265", "47266", "47267", "47268", "47270", "47272", "47273", "47274", "47277", "47278", "47279", "47280", "47282", "47283", "47284", "47287", "47292", "47293", "47294", "47295", "47296", "47299", "47300", "47301", "47303", "47305", "47306", "47307", "47309", "47310", "47312", "47315", "47318", "47320", "47321", "47322", "47323", "47326", "47327", "47330", "47332", "47334", "47336", "47337", "47338", "47342", "47344", "47345", "47348", "47351", "47352", "47354", "47355", "47358", "47359", "47360", "47363", "47366", "47370", "47373", "47376", "47384", "47386", "47387", "47388", "47389", "47391", "47392", "47393", "47395", "47399", "47401", "47402", "47403", "47404", "47405", "47406", "47408", "47409", "47412", "47413", "47415", "47417", "47418", "47419", "47421", "47422", "47424", "47425", "47428", "47429", "47432", "47433", "47436", "47438", "47440", "47444", "47445", "47446", "47447", "47448", "47449", "47450", "47451", "47455", "47456", "47457", "47458", "47459", "47460", "47461", "47464", "47465", "47466", "47467", "47468", "47469", "47471", "47477", "47478", "47479", "47480", "47481", "47483", "47484", "47485", "47487", "47491", "47492", "47493", "47497", "47498", "47499", "47502", "47503", "47504", "47505", "47506", "47509", "47513", "47514", "47515", "47517", "47518", "47519", "47520", "47522", "47523", "47525", "47528", "47531", "47533", "47534", "47537", "47539", "47540", "47542", "47547", "47554", "47555", "47556", "47557", "47564", "47565", "47567", "47570", "47571", "47573", "47574", "47575", "47578", "47580", "47582", "47583", "47584", "47588", "47589", "47590", "47594", "47595", "47596", "47599", "47600", "47601", "47603", "47606", "47607", "47613", "47614", "47617", "47618", "47622", "47623", "47628", "47629", "47632", "47633", "47634", "47635", "47637", "47639", "47641", "47646", "47649", "47650", "47653", "47654", "47655", "47658", "47659", "47661", "47662", "47663", "47664", "47665", "47666", "47667", "47668", "47669", "47673", "47674", "47675", "47679", "47680", "47681", "47684", "47685", "47688", "47691", "47694", "47696", "47697", "47698", "47699", "47700", "47701", "47702", "47704", "47706", "47707", "47709", "47711", "47714", "47716", "47717", "47718", "47722", "47724", "47726", "47727", "47728", "47731", "47733", "47736", "47741", "47742", "47743", "47747", "47754", "47764", "47766", "47767", "47768", "47769", "47770", "47772", "47774", "47778", "47780", "47781", "47784", "47785", "47788", "47789", "47795", "47796", "47797", "47798", "47800", "47805", "47809", "47812", "47814", "47816", "47820", "47821", "47826", "47827", "47829", "47830", "47831", "47836", "47837", "47840", "47841", "47845", "47846", "47847", "47850", "47851", "47852", "47853", "47854", "47855", "47856", "47857", "47858", "47861", "47863", "47865", "47866", "47870", "47876", "47878", "47879", "47880", "47881", "47883", "47886", "47889", "47890", "47891", "47892", "47896", "47897", "47898", "47899", "47901", "47903", "47905", "47906", "47907", "47908", "47910", "47912", "47914", "47916", "47917", "47918", "47921", "47923", "47924", "47927", "47930", "47931", "47932", "47933", "47935", "47936", "47937", "47938", "47939", "47940", "47941", "47942", "47945", "47946", "47948", "47951", "47952", "47954", "47957", "47958", "47961", "47962", "47965", "47966", "47967", "47969", "47970", "47971", "47974", "47975", "47976", "47979", "47980", "47985", "47986", "47987", "47988", "47989", "47990", "47991", "47992", "47993", "47995", "47996", "47997", "47998", "48002", "48003", "48006", "48007", "48008", "48010", "48011", "48014", "48017", "48018", "48019", "48020", "48021", "48027", "48029", "48030", "48032", "48033", "48035", "48036", "48037", "48038", "48042", "48043", "48047", "48049", "48050", "48053", "48055", "48056", "48057", "48059", "48062", "48064", "48065", "48066", "48067", "48068", "48070", "48076", "48079", "48080", "48084", "48085", "48086", "48088", "48089", "48090", "48093", "48098", "48100", "48105", "48106", "48110", "48112", "48113", "48114", "48116", "48117", "48119", "48122", "48123", "48124", "48125", "48127", "48128", "48132", "48135", "48136", "48137", "48138", "48139", "48140", "48141", "48142", "48144", "48145", "48146", "48148", "48151", "48152", "48153", "48158", "48159", "48160", "48162", "48164", "48168", "48169", "48170", "48172", "48174", "48176", "48178", "48179", "48186", "48188", "48190", "48191", "48194", "48195", "48197", "48199", "48201", "48203", "48204", "48207", "48208", "48211", "48212", "48216", "48217", "48220", "48221", "48225", "48226", "48229", "48230", "48232", "48233", "48235", "48239", "48242", "48243", "48244", "48246", "48249", "48250", "48251", "48252", "48257", "48258", "48259", "48261", "48264", "48267", "48269", "48270", "48273", "48274", "48280", "48284", "48287", "48289", "48290", "48296", "48298", "48300", "48302", "48303", "48306", "48307", "48309", "48311", "48312", "48313", "48315", "48316", "48319", "48321", "48324", "48326", "48330", "48331", "48332", "48336", "48339", "48341", "48344", "48345", "48346", "48347", "48348", "48349", "48351", "48353", "48360", "48362", "48363", "48364", "48365", "48369", "48370", "48371", "48373", "48375", "48378", "48380", "48381", "48383", "48386", "48388", "48389", "48392", "48393", "48396", "48397", "48398", "48401", "48402", "48404", "48405", "48407", "48409", "48410", "48412", "48414", "48415", "48416", "48417", "48418", "48419", "48422", "48424", "48425", "48427", "48430", "48431", "48434", "48436", "48438", "48439", "48440", "48442", "48443", "48444", "48445", "48446", "48448", "48449", "48450", "48453", "48455", "48456", "48457", "48458", "48462", "48465", "48466", "48467", "48468", "48469", "48470", "48471", "48476", "48477", "48479", "48480", "48482", "48484", "48485", "48486", "48487", "48488", "48489", "48492", "48494", "48495", "48496", "48497", "48498", "48500", "48505", "48506", "48508", "48509", "48511", "48512", "48515", "48517", "48519", "48521", "48522", "48523", "48525", "48526", "48527", "48528", "48532", "48533", "48534", "48536", "48537", "48540", "48542", "48549", "48551", "48552", "48555", "48556", "48557", "48558", "48561", "48562", "48563", "48565", "48566", "48567", "48568", "48570", "48574", "48577", "48578", "48579", "48583", "48584", "48587", "48590", "48591", "48592", "48593", "48596", "48597", "48600", "48603", "48607", "48608", "48610", "48611", "48614", "48615", "48617", "48618", "48620", "48621", "48624", "48625", "48628", "48631", "48632", "48634", "48636", "48637", "48638", "48640", "48641", "48644", "48645", "48647", "48648", "48649", "48650", "48651", "48656", "48657", "48658", "48659", "48661", "48662", "48665", "48666", "48668", "48670", "48672", "48675", "48676", "48677", "48678", "48679", "48683", "48686", "48687", "48688", "48689", "48690", "48691", "48692", "48693", "48694", "48696", "48697", "48699", "48700", "48701", "48703", "48706", "48708", "48711", "48712", "48713", "48714", "48718", "48719", "48721", "48723", "48724", "48726", "48728", "48729", "48731", "48734", "48735", "48737", "48738", "48740", "48741", "48746", "48748", "48750", "48751", "48752", "48753", "48756", "48757", "48759", "48764", "48765", "48766", "48771", "48772", "48773", "48775", "48776", "48778", "48779", "48781", "48782", "48783", "48784", "48785", "48787", "48789", "48790", "48791", "48792", "48793", "48795", "48796", "48800", "48809", "48810", "48811", "48817", "48818", "48819", "48822", "48823", "48824", "48826", "48828", "48831", "48832", "48837", "48838", "48841", "48842", "48843", "48844", "48852", "48853", "48855", "48858", "48861", "48862", "48863", "48865", "48869", "48871", "48876", "48877", "48878", "48880", "48884", "48890", "48891", "48892", "48893", "48899", "48900", "48901", "48902", "48905", "48906", "48907", "48908", "48910", "48915", "48920", "48921", "48923", "48926", "48927", "48928", "48929", "48933", "48934", "48935", "48939", "48942", "48943", "48946", "48947", "48950", "48952", "48953", "48954", "48955", "48957", "48960", "48962", "48963", "48965", "48968", "48971", "48977", "48982", "48983", "48985", "48988", "48989", "48993", "48995", "48996", "48998", "49000", "49001", "49003", "49005", "49010", "49012", "49017", "49018", "49020", "49021", "49022", "49023", "49028", "49029", "49030", "49032", "49034", "49035", "49036", "49037", "49041", "49044", "49052", "49054", "49060", "49063", "49065", "49066", "49068", "49069", "49070", "49071", "49073", "49075", "49076", "49077", "49078", "49080", "49082", "49086", "49087", "49088", "49089", "49092", "49093", "49094", "49095", "49101", "49103", "49104", "49106", "49107", "49108", "49110", "49118", "49120", "49121", "49123", "49124", "49125", "49126", "49127", "49134", "49135", "49137", "49138", "49145", "49146", "49147", "49153", "49154", "49155", "49160", "49161", "49165", "49168", "49172", "49173", "49175", "49176", "49179", "49180", "49181", "49184", "49186", "49187", "49188", "49191", "49202", "49203", "49204", "49205", "49207", "49209", "49213", "49214", "49218", "49220", "49221", "49222", "49227", "49228", "49230", "49233", "49234", "49235", "49236", "49240", "49243", "49244", "49247", "49248", "49249", "49251", "49253", "49254", "49255", "49256", "49257", "49259", "49261", "49263", "49264", "49266", "49269", "49270", "49272", "49273", "49276", "49278", "49280", "49286", "49288", "49291", "49292", "49293", "49295", "49296", "49297", "49299", "49300", "49301", "49302", "49305", "49309", "49310", "49311", "49314", "49315", "49317", "49321", "49326", "49327", "49329", "49330", "49331", "49332", "49333", "49334", "49336", "49337", "49339", "49342", "49343", "49344", "49345", "49346", "49347", "49351", "49353", "49355", "49357", "49360", "49365", "49367", "49371", "49372", "49373", "49374", "49376", "49377", "49378", "49380", "49381", "49386", "49389", "49390", "49391", "49392", "49393", "49394", "49397", "49398", "49400", "49401", "49402", "49403", "49404", "49406", "49410", "49411", "49414", "49415", "49417", "49418", "49420", "49421", "49422", "49423", "49424", "49425", "49426", "49427", "49429", "49433", "49434", "49437", "49439", "49440", "49443", "49445", "49449", "49450", "49451", "49456", "49457", "49458", "49459", "49460", "49461", "49463", "49465", "49466", "49467", "49469", "49470", "49471", "49473", "49475", "49476", "49478", "49482", "49483", "49488", "49490", "49492", "49495", "49497", "49501", "49502", "49506", "49507", "49508", "49515", "49516", "49521", "49526", "49528", "49532", "49534", "49536", "49545", "49546", "49548", "49549", "49552", "49554", "49555", "49557", "49560", "49561", "49562", "49564", "49565", "49569", "49572", "49574", "49576", "49581", "49583", "49586", "49588", "49590", "49592", "49596", "49604", "49612", "49613", "49615", "49616", "49620", "49622", "49623", "49627", "49629", "49630", "49632", "49637", "49640", "49641", "49643", "49644", "49645", "49647", "49649", "49650", "49651", "49652", "49653", "49657", "49659", "49664", "49665", "49669", "49670", "49672", "49673", "49674", "49675", "49676", "49678", "49680", "49681", "49684", "49685", "49686", "49687", "49688", "49693", "49694", "49695", "49701", "49702", "49703", "49705", "49706", "49707", "49710", "49711", "49712", "49713", "49715", "49716", "49717", "49718", "49720", "49722", "49723", "49724", "49725", "49728", "49729", "49733", "49734", "49737", "49738", "49744", "49745", "49746", "49751", "49753", "49754", "49756", "49759", "49763", "49765", "49767", "49769", "49770", "49773", "49774", "49775", "49778", "49781", "49783", "49789", "49790", "49791", "49792", "49795", "49796", "49797", "49798", "49801", "49802", "49803", "49804", "49805", "49806", "49808", "49813", "49814", "49817", "49819", "49820", "49822", "49823", "49826", "49828", "49829", "49831", "49834", "49835", "49836", "49837", "49841", "49842", "49843", "49844", "49846", "49849", "49850", "49852", "49853", "49854", "49856", "49857", "49859", "49860", "49865", "49866", "49868", "49869", "49870", "49871", "49872", "49873", "49874", "49875", "49878", "49879", "49880", "49881", "49884", "49886", "49892", "49894", "49895", "49896", "49899", "49904", "49905", "49907", "49908", "49909", "49910", "49911", "49912", "49914", "49915", "49916", "49917", "49919", "49920", "49923", "49927", "49930", "49931", "49934", "49937", "49938", "49939", "49940", "49941", "49942", "49943", "49945", "49947", "49948", "49950", "49951", "49954", "49955", "49958", "49960", "49961", "49962", "49963", "49968", "49970", "49973", "49975", "49976", "49978", "49979", "49982", "49985", "49986", "49991", "49993", "49995", "49996", "49997", "49998", "49999"]]
+}
\ No newline at end of file
diff --git a/AutoDL-Projects/configs/nas-benchmark/cifar100-test-split.txt b/AutoDL-Projects/configs/nas-benchmark/cifar100-test-split.txt
new file mode 100644
index 0000000..d5f7165
--- /dev/null
+++ b/AutoDL-Projects/configs/nas-benchmark/cifar100-test-split.txt
@@ -0,0 +1,4 @@
+{
+ "xvalid" : ["int" , ["1", "3", "4", "5", "8", "10", "13", "14", "15", "16", "18", "19", "21", "22", "23", "27", "28", "30", "33", "36", "37", "39", "41", "44", "45", "47", "48", "49", "52", "54", "57", "58", "59", "60", "62", "64", "65", "66", "68", "73", "75", "76", "77", "78", "81", "82", "85", "86", "87", "93", "94", "96", "97", "102", "105", "106", "110", "111", "112", "114", "117", "118", "119", "122", "124", "128", "129", "131", "132", "133", "134", "137", "138", "139", "140", "144", "147", "148", "150", "151", "152", "153", "154", "156", "158", "162", "163", "164", "165", "167", "170", "173", "174", "175", "177", "179", "180", "182", "184", "185", "187", "191", "195", "203", "206", "208", "215", "216", "224", "226", "227", "230", "231", "232", "233", "234", "236", "237", "238", "241", "242", "245", "246", "249", "250", "251", "252", "254", "256", "257", "258", "259", "261", "262", "265", "267", "270", "272", "273", "275", "277", "278", "279", "282", "283", "285", "286", "289", "293", "294", "295", "296", "298", "302", "303", "305", "308", "310", "312", "313", "315", "316", "317", "318", "319", "324", "325", "326", "327", "328", "334", "335", "337", "339", "346", "347", "349", "350", "353", "354", "356", "357", "362", "363", "370", "372", "373", "374", "376", "377", "378", "381", "382", "383", "391", "392", "393", "394", "397", "399", "400", "402", "403", "404", "405", "407", "409", "410", "411", "412", "414", "416", "417", "419", "421", "423", "430", "433", "436", "438", "441", "442", "443", "444", "445", "446", "448", "449", "450", "452", "454", "457", "460", "461", "465", "466", "467", "468", "470", "471", "472", "474", "481", "485", "488", "496", "497", "498", "499", "500", "502", "505", "506", "508", "511", "512", "513", "514", "517", "518", "519", "520", "521", "524", "526", "527", "528", "530", "531", "532", "535", "539", "541", "547", "549", "551", "558", "559", "562", "563", "564", "567", "570", "583", "585", "586", "587", "588", "589", "591", "594", "596", "597", "598", "599", "600", "602", "603", "606", "608", "610", "611", "613", "618", "619", "620", "621", "622", "623", "624", "626", "628", "631", "633", "637", "639", "640", "641", "642", "643", "644", "645", "646", "648", "650", "655", "656", "657", "659", "664", "665", "667", "670", "672", "674", "675", "676", "677", "681", "684", "685", "687", "688", "689", "690", "692", "694", "695", "696", "698", "699", "700", "702", "704", "707", "708", "710", "712", "714", "715", "716", "717", "718", "720", "725", "727", "729", "735", "736", "737", "739", "740", "741", "743", "746", "748", "749", "750", "751", "752", "753", "758", "761", "769", "771", "773", "775", "776", "777", "778", "780", "781", "783", "786", "787", "789", "792", "793", "795", "797", "798", "799", "809", "811", "812", "813", "815", "817", "818", "819", "820", "821", "822", "823", "825", "826", "827", "828", "829", "832", "833", "834", "835", "838", "839", "840", "841", "843", "848", "851", "852", "854", "857", "862", "867", "868", "869", "871", "872", "874", "875", "877", "880", "883", "887", "888", "889", "892", "894", "896", "898", "899", "900", "904", "907", "910", "912", "913", "914", "915", "916", "917", "918", "919", "921", "922", "924", "927", "928", "932", "933", "935", "936", "937", "944", "947", "951", "959", "961", "962", "966", "970", "972", "974", "976", "979", "980", "983", "985", "986", "988", "993", "996", "997", "1001", "1002", "1006", "1007", "1009", "1011", "1012", "1013", "1014", "1015", "1016", "1017", "1018", "1021", "1022", "1024", "1025", "1026", "1027", "1028", "1029", "1034", "1038", "1039", "1040", "1041", "1044", "1045", "1046", "1047", "1051", "1052", "1054", "1055", "1056", "1057", "1058", "1059", "1062", "1064", "1067", "1069", "1070", "1071", "1077", "1078", "1080", "1081", "1083", "1084", "1088", "1089", "1090", "1094", "1095", "1096", "1098", "1100", "1104", "1108", "1110", "1111", "1117", "1118", "1120", "1121", "1122", "1123", "1124", "1129", "1135", "1136", "1139", "1140", "1142", "1144", "1148", "1150", "1152", "1156", "1157", "1159", "1161", "1162", "1164", "1166", "1167", "1168", "1170", "1171", "1172", "1174", "1176", "1177", "1178", "1185", "1186", "1187", "1188", "1189", "1190", "1191", "1194", "1196", "1203", "1208", "1209", "1210", "1211", "1212", "1213", "1214", "1221", "1223", "1224", "1229", "1231", "1237", "1239", "1240", "1241", "1242", "1243", "1244", "1245", "1247", "1250", "1254", "1257", "1259", "1263", "1269", "1272", "1273", "1275", "1276", "1277", "1280", "1281", "1282", "1285", "1288", "1289", "1290", "1292", "1293", "1294", "1295", "1296", "1297", "1298", "1300", "1303", "1307", "1309", "1311", "1312", "1313", "1315", "1316", "1317", "1321", "1324", "1327", "1328", "1329", "1330", "1331", "1332", "1334", "1335", "1336", "1340", "1341", "1342", "1343", "1345", "1347", "1349", "1351", "1352", "1353", "1354", "1356", "1361", "1363", "1364", "1365", "1367", "1368", "1369", "1371", "1372", "1375", "1376", "1380", "1382", "1385", "1390", "1392", "1393", "1394", "1395", "1396", "1399", "1401", "1402", "1403", "1405", "1406", "1408", "1413", "1415", "1416", "1418", "1422", "1423", "1424", "1425", "1426", "1428", "1430", "1431", "1433", "1435", "1437", "1439", "1440", "1441", "1443", "1445", "1446", "1447", "1453", "1457", "1458", "1462", "1463", "1464", "1465", "1466", "1467", "1472", "1473", "1475", "1476", "1478", "1479", "1480", "1482", "1483", "1484", "1485", "1489", "1490", "1491", "1492", "1493", "1496", "1502", "1505", "1506", "1508", "1509", "1513", "1514", "1515", "1518", "1521", "1523", "1524", "1528", "1535", "1541", "1544", "1545", "1546", "1549", "1550", "1553", "1555", "1556", "1559", "1560", "1562", "1563", "1564", "1565", "1567", "1568", "1569", "1571", "1572", "1573", "1576", "1579", "1582", "1586", "1587", "1589", "1592", "1593", "1596", "1597", "1603", "1605", "1606", "1611", "1612", "1616", "1619", "1621", "1630", "1632", "1633", "1634", "1635", "1636", "1639", "1641", "1642", "1643", "1648", "1649", "1650", "1651", "1653", "1654", "1656", "1659", "1660", "1662", "1664", "1667", "1668", "1672", "1673", "1675", "1677", "1678", "1681", "1683", "1687", "1690", "1693", "1695", "1697", "1698", "1699", "1701", "1704", "1706", "1707", "1713", "1714", "1716", "1719", "1720", "1721", "1722", "1728", "1729", "1730", "1734", "1736", "1737", "1739", "1740", "1743", "1746", "1753", "1754", "1755", "1758", "1762", "1765", "1766", "1767", "1768", "1775", "1777", "1779", "1782", "1783", "1784", "1785", "1789", "1790", "1795", "1800", "1801", "1803", "1804", "1810", "1811", "1814", "1816", "1817", "1820", "1821", "1826", "1828", "1834", "1835", "1837", "1843", "1844", "1845", "1846", "1847", "1848", "1851", "1856", "1859", "1860", "1862", "1863", "1866", "1869", "1872", "1875", "1876", "1879", "1882", "1883", "1884", "1885", "1887", "1888", "1889", "1890", "1893", "1896", "1898", "1900", "1902", "1903", "1904", "1912", "1913", "1914", "1915", "1916", "1917", "1919", "1920", "1921", "1923", "1924", "1933", "1935", "1936", "1942", "1943", "1944", "1946", "1947", "1949", "1950", "1954", "1956", "1958", "1959", "1960", "1961", "1967", "1969", "1971", "1973", "1975", "1976", "1977", "1982", "1983", "1985", "1987", "1989", "1993", "1995", "1996", "1997", "1998", "1999", "2003", "2004", "2007", "2008", "2009", "2010", "2011", "2012", "2014", "2016", "2020", "2023", "2024", "2026", "2030", "2031", "2032", "2033", "2034", "2038", "2039", "2041", "2043", "2044", "2046", "2048", "2049", "2050", "2051", "2052", "2054", "2055", "2058", "2059", "2060", "2061", "2062", "2064", "2066", "2067", "2070", "2071", "2072", "2076", "2078", "2080", "2085", "2086", "2087", "2088", "2089", "2091", "2094", "2097", "2098", "2100", "2101", "2104", "2105", "2107", "2108", "2109", "2110", "2111", "2114", "2118", "2119", "2120", "2126", "2127", "2130", "2134", "2137", "2140", "2141", "2146", "2150", "2151", "2152", "2154", "2155", "2156", "2158", "2160", "2161", "2162", "2164", "2165", "2170", "2171", "2172", "2176", "2177", "2178", "2180", "2182", "2185", "2188", "2189", "2190", "2193", "2197", "2199", "2200", "2201", "2202", "2203", "2205", "2206", "2209", "2212", "2213", "2216", "2219", "2220", "2222", "2225", "2226", "2228", "2229", "2231", "2234", "2238", "2240", "2243", "2244", "2245", "2248", "2249", "2251", "2252", "2253", "2254", "2255", "2260", "2261", "2262", "2265", "2266", "2268", "2271", "2274", "2275", "2276", "2277", "2278", "2281", "2283", "2284", "2287", "2291", "2292", "2295", "2297", "2301", "2302", "2304", "2308", "2309", "2311", "2313", "2315", "2318", "2321", "2322", "2325", "2328", "2329", "2330", "2331", "2332", "2333", "2334", "2335", "2336", "2337", "2339", "2340", "2343", "2344", "2346", "2347", "2348", "2350", "2351", "2354", "2356", "2360", "2363", "2364", "2365", "2370", "2373", "2374", "2376", "2377", "2378", "2380", "2383", "2385", "2388", "2390", "2395", "2396", "2399", "2400", "2402", "2403", "2404", "2409", "2411", "2413", "2414", "2415", "2416", "2417", "2421", "2424", "2425", "2427", "2428", "2429", "2438", "2439", "2441", "2444", "2445", "2447", "2448", "2449", "2450", "2452", "2453", "2454", "2456", "2457", "2458", "2459", "2461", "2466", "2467", "2468", "2472", "2473", "2475", "2476", "2477", "2479", "2482", "2483", "2486", "2490", "2493", "2495", "2496", "2497", "2499", "2500", "2501", "2506", "2507", "2508", "2511", "2517", "2519", "2523", "2531", "2532", "2533", "2534", "2536", "2537", "2541", "2542", "2545", "2550", "2553", "2554", "2557", "2559", "2560", "2561", "2565", "2567", "2568", "2569", "2574", "2577", "2579", "2580", "2581", "2582", "2586", "2587", "2590", "2593", "2594", "2597", "2598", "2600", "2602", "2603", "2604", "2606", "2609", "2610", "2611", "2612", "2613", "2614", "2615", "2616", "2619", "2623", "2628", "2629", "2630", "2631", "2632", "2635", "2637", "2639", "2644", "2645", "2646", "2647", "2650", "2651", "2652", "2653", "2660", "2661", "2662", "2663", "2664", "2666", "2668", "2669", "2673", "2674", "2677", "2678", "2681", "2682", "2683", "2686", "2687", "2690", "2691", "2692", "2693", "2694", "2696", "2697", "2700", "2702", "2703", "2704", "2705", "2706", "2707", "2708", "2709", "2710", "2715", "2716", "2717", "2721", "2723", "2724", "2725", "2726", "2728", "2730", "2731", "2732", "2733", "2734", "2735", "2736", "2737", "2738", "2739", "2740", "2742", "2743", "2745", "2746", "2753", "2759", "2761", "2762", "2770", "2772", "2774", "2776", "2779", "2781", "2782", "2787", "2788", "2789", "2790", "2791", "2795", "2796", "2797", "2799", "2802", "2807", "2808", "2810", "2812", "2813", "2814", "2815", "2816", "2818", "2819", "2824", "2825", "2826", "2833", "2834", "2835", "2837", "2838", "2839", "2840", "2841", "2845", "2847", "2848", "2850", "2851", "2858", "2859", "2866", "2867", "2868", "2869", "2873", "2874", "2876", "2877", "2878", "2879", "2880", "2883", "2884", "2885", "2886", "2887", "2889", "2890", "2891", "2892", "2894", "2895", "2900", "2901", "2903", "2905", "2909", "2912", "2913", "2916", "2918", "2919", "2920", "2921", "2922", "2923", "2927", "2928", "2929", "2932", "2934", "2935", "2936", "2940", "2941", "2944", "2945", "2948", "2949", "2951", "2952", "2953", "2954", "2956", "2959", "2960", "2961", "2965", "2966", "2967", "2969", "2972", "2974", "2975", "2976", "2977", "2980", "2982", "2985", "2987", "2988", "2989", "2990", "2993", "2995", "2996", "3001", "3002", "3005", "3006", "3007", "3010", "3011", "3012", "3018", "3019", "3020", "3022", "3023", "3027", "3028", "3034", "3036", "3037", "3041", "3042", "3043", "3044", "3046", "3047", "3048", "3050", "3052", "3054", "3056", "3058", "3059", "3060", "3063", "3068", "3070", "3073", "3075", "3076", "3078", "3083", "3085", "3089", "3090", "3094", "3095", "3098", "3100", "3101", "3102", "3103", "3108", "3112", "3113", "3116", "3118", "3119", "3123", "3124", "3126", "3128", "3131", "3133", "3136", "3137", "3138", "3140", "3145", "3152", "3154", "3155", "3162", "3163", "3164", "3165", "3168", "3170", "3172", "3173", "3174", "3176", "3177", "3178", "3179", "3180", "3181", "3184", "3190", "3192", "3194", "3196", "3197", "3198", "3202", "3203", "3206", "3208", "3209", "3212", "3213", "3215", "3216", "3217", "3219", "3222", "3224", "3226", "3227", "3229", "3230", "3232", "3234", "3235", "3236", "3238", "3239", "3245", "3248", "3249", "3251", "3256", "3257", "3259", "3261", "3262", "3264", "3265", "3267", "3270", "3271", "3276", "3277", "3278", "3279", "3280", "3282", "3285", "3289", "3295", "3299", "3300", "3302", "3305", "3306", "3307", "3308", "3309", "3314", "3315", "3317", "3319", "3320", "3321", "3323", "3326", "3330", "3331", "3333", "3334", "3338", "3340", "3343", "3347", "3348", "3351", "3353", "3354", "3355", "3359", "3361", "3362", "3366", "3367", "3368", "3370", "3372", "3373", "3374", "3375", "3376", "3377", "3378", "3379", "3382", "3383", "3384", "3385", "3389", "3393", "3397", "3398", "3401", "3403", "3406", "3408", "3409", "3411", "3413", "3417", "3419", "3420", "3421", "3422", "3424", "3426", "3428", "3429", "3430", "3432", "3434", "3437", "3438", "3439", "3440", "3442", "3448", "3455", "3456", "3458", "3462", "3463", "3464", "3469", "3470", "3471", "3479", "3482", "3485", "3487", "3488", "3491", "3492", "3494", "3495", "3497", "3498", "3500", "3502", "3504", "3506", "3511", "3512", "3514", "3515", "3516", "3519", "3520", "3522", "3524", "3525", "3526", "3527", "3528", "3529", "3530", "3531", "3532", "3537", "3539", "3540", "3541", "3542", "3546", "3550", "3552", "3553", "3554", "3555", "3559", "3560", "3561", "3563", "3565", "3567", "3568", "3571", "3572", "3573", "3579", "3580", "3585", "3588", "3589", "3590", "3591", "3592", "3594", "3595", "3597", "3598", "3601", "3603", "3608", "3609", "3611", "3613", "3618", "3620", "3621", "3623", "3625", "3630", "3633", "3634", "3635", "3636", "3638", "3639", "3640", "3646", "3647", "3649", "3651", "3652", "3653", "3656", "3657", "3658", "3659", "3660", "3662", "3663", "3664", "3671", "3672", "3673", "3675", "3676", "3677", "3679", "3680", "3681", "3683", "3684", "3686", "3687", "3688", "3690", "3693", "3700", "3702", "3703", "3704", "3706", "3709", "3711", "3716", "3720", "3722", "3723", "3725", "3726", "3727", "3728", "3733", "3735", "3737", "3738", "3740", "3743", "3744", "3745", "3746", "3747", "3748", "3749", "3750", "3752", "3753", "3754", "3755", "3756", "3757", "3758", "3760", "3761", "3762", "3763", "3769", "3770", "3773", "3776", "3779", "3780", "3781", "3785", "3788", "3789", "3791", "3795", "3796", "3803", "3804", "3806", "3807", "3808", "3809", "3810", "3811", "3812", "3818", "3819", "3822", "3823", "3826", "3828", "3830", "3835", "3837", "3840", "3843", "3844", "3845", "3849", "3850", "3852", "3854", "3856", "3858", "3859", "3861", "3862", "3863", "3870", "3872", "3873", "3879", "3880", "3883", "3888", "3889", "3890", "3892", "3894", "3895", "3896", "3898", "3900", "3901", "3902", "3903", "3905", "3906", "3907", "3908", "3909", "3910", "3912", "3914", "3916", "3918", "3921", "3922", "3924", "3926", "3928", "3929", "3930", "3934", "3935", "3936", "3938", "3940", "3941", "3942", "3944", "3945", "3948", "3950", "3951", "3954", "3955", "3956", "3961", "3962", "3963", "3966", "3968", "3969", "3970", "3971", "3972", "3973", "3979", "3980", "3982", "3983", "3985", "3987", "3998", "4000", "4002", "4003", "4006", "4009", "4010", "4011", "4020", "4021", "4025", "4026", "4027", "4028", "4029", "4032", "4034", "4036", "4040", "4046", "4048", "4058", "4063", "4064", "4065", "4067", "4069", "4071", "4074", "4076", "4085", "4086", "4089", "4090", "4093", "4095", "4096", "4099", "4100", "4101", "4102", "4106", "4108", "4112", "4113", "4121", "4125", "4126", "4129", "4132", "4133", "4134", "4135", "4136", "4137", "4138", "4143", "4145", "4146", "4147", "4148", "4149", "4151", "4152", "4153", "4156", "4158", "4160", "4164", "4166", "4167", "4168", "4169", "4171", "4172", "4173", "4179", "4182", "4183", "4184", "4185", "4188", "4189", "4190", "4191", "4192", "4193", "4195", "4196", "4197", "4198", "4199", "4202", "4203", "4206", "4207", "4214", "4215", "4219", "4223", "4225", "4226", "4227", "4234", "4236", "4240", "4241", "4242", "4246", "4249", "4250", "4251", "4253", "4254", "4255", "4256", "4259", "4261", "4264", "4265", "4266", "4267", "4268", "4270", "4271", "4272", "4274", "4275", "4276", "4277", "4278", "4282", "4283", "4285", "4286", "4287", "4288", "4289", "4290", "4291", "4294", "4296", "4300", "4301", "4305", "4306", "4308", "4309", "4312", "4314", "4315", "4318", "4320", "4322", "4323", "4324", "4325", "4327", "4329", "4331", "4332", "4333", "4335", "4337", "4338", "4342", "4343", "4344", "4346", "4347", "4349", "4350", "4351", "4354", "4355", "4358", "4359", "4362", "4363", "4364", "4366", "4369", "4371", "4372", "4373", "4374", "4375", "4376", "4379", "4381", "4386", "4388", "4390", "4391", "4392", "4394", "4398", "4399", "4400", "4402", "4403", "4405", "4406", "4408", "4409", "4410", "4411", "4412", "4413", "4414", "4416", "4423", "4425", "4426", "4427", "4429", "4431", "4432", "4434", "4436", "4438", "4439", "4440", "4441", "4445", "4449", "4451", "4454", "4455", "4456", "4457", "4459", "4460", "4461", "4463", "4466", "4467", "4474", "4476", "4477", "4481", "4482", "4486", "4493", "4495", "4498", "4500", "4502", "4503", "4504", "4506", "4509", "4510", "4512", "4513", "4516", "4517", "4518", "4519", "4521", "4522", "4524", "4525", "4527", "4530", "4535", "4536", "4540", "4544", "4547", "4552", "4556", "4557", "4560", "4562", "4572", "4574", "4576", "4577", "4578", "4580", "4581", "4583", "4585", "4587", "4588", "4592", "4594", "4595", "4603", "4609", "4610", "4614", "4615", "4616", "4617", "4621", "4622", "4623", "4624", "4626", "4627", "4628", "4633", "4634", "4635", "4636", "4639", "4640", "4642", "4646", "4649", "4650", "4651", "4653", "4654", "4656", "4657", "4660", "4662", "4665", "4666", "4667", "4668", "4671", "4673", "4674", "4675", "4676", "4677", "4678", "4679", "4680", "4681", "4683", "4684", "4686", "4687", "4688", "4689", "4691", "4696", "4697", "4700", "4701", "4702", "4703", "4704", "4705", "4708", "4711", "4718", "4720", "4721", "4722", "4724", "4725", "4726", "4730", "4732", "4734", "4738", "4739", "4740", "4741", "4744", "4746", "4747", "4749", "4751", "4753", "4756", "4758", "4759", "4760", "4768", "4769", "4770", "4772", "4773", "4774", "4776", "4777", "4779", "4780", "4784", "4787", "4788", "4789", "4790", "4792", "4794", "4795", "4799", "4800", "4801", "4802", "4803", "4804", "4806", "4807", "4809", "4811", "4814", "4816", "4817", "4820", "4822", "4823", "4825", "4826", "4827", "4830", "4831", "4832", "4834", "4835", "4837", "4840", "4842", "4844", "4845", "4846", "4847", "4849", "4850", "4852", "4857", "4861", "4863", "4868", "4869", "4870", "4871", "4872", "4873", "4875", "4881", "4885", "4888", "4889", "4891", "4893", "4897", "4900", "4901", "4905", "4907", "4910", "4912", "4913", "4916", "4917", "4918", "4919", "4920", "4922", "4924", "4925", "4928", "4929", "4930", "4931", "4932", "4934", "4935", "4939", "4942", "4943", "4944", "4945", "4946", "4947", "4950", "4953", "4954", "4955", "4957", "4958", "4960", "4965", "4967", "4971", "4972", "4973", "4974", "4975", "4976", "4977", "4978", "4980", "4984", "4985", "4986", "4988", "4990", "4993", "4997", "4998", "5003", "5004", "5005", "5006", "5008", "5010", "5012", "5013", "5015", "5021", "5022", "5024", "5026", "5028", "5031", "5034", "5039", "5041", "5042", "5043", "5044", "5048", "5051", "5055", "5056", "5057", "5058", "5060", "5064", "5065", "5067", "5071", "5072", "5073", "5074", "5077", "5080", "5081", "5083", "5084", "5086", "5090", "5092", "5094", "5096", "5097", "5099", "5100", "5101", "5104", "5105", "5106", "5110", "5112", "5113", "5114", "5116", "5117", "5120", "5121", "5122", "5125", "5129", "5131", "5133", "5134", "5137", "5140", "5141", "5142", "5143", "5144", "5145", "5146", "5147", "5148", "5149", "5153", "5154", "5155", "5158", "5159", "5161", "5164", "5166", "5168", "5170", "5171", "5175", "5177", "5178", "5180", "5181", "5185", "5187", "5189", "5190", "5192", "5195", "5197", "5200", "5201", "5202", "5203", "5204", "5206", "5207", "5213", "5214", "5215", "5216", "5224", "5225", "5228", "5229", "5230", "5232", "5233", "5236", "5238", "5239", "5242", "5243", "5244", "5247", "5248", "5253", "5254", "5255", "5265", "5269", "5272", "5273", "5274", "5275", "5279", "5280", "5281", "5286", "5287", "5291", "5292", "5293", "5294", "5295", "5296", "5297", "5298", "5299", "5300", "5301", "5306", "5307", "5311", "5315", "5316", "5318", "5320", "5321", "5322", "5323", "5326", "5332", "5333", "5334", "5337", "5338", "5341", "5342", "5344", "5346", "5349", "5350", "5352", "5353", "5354", "5358", "5360", "5361", "5362", "5364", "5365", "5369", "5371", "5372", "5376", "5378", "5379", "5380", "5384", "5385", "5388", "5389", "5390", "5391", "5392", "5395", "5396", "5397", "5399", "5400", "5401", "5404", "5407", "5408", "5409", "5410", "5416", "5418", "5419", "5422", "5426", "5427", "5429", "5431", "5433", "5434", "5435", "5439", "5442", "5443", "5444", "5445", "5446", "5448", "5452", "5454", "5455", "5456", "5457", "5458", "5460", "5461", "5464", "5468", "5469", "5472", "5476", "5479", "5482", "5485", "5486", "5489", "5490", "5496", "5498", "5500", "5501", "5504", "5506", "5507", "5509", "5513", "5514", "5516", "5518", "5519", "5520", "5521", "5523", "5525", "5528", "5529", "5533", "5534", "5537", "5539", "5540", "5541", "5543", "5544", "5546", "5547", "5550", "5551", "5555", "5556", "5558", "5559", "5560", "5561", "5562", "5564", "5566", "5567", "5569", "5570", "5571", "5574", "5575", "5579", "5581", "5582", "5583", "5584", "5591", "5592", "5593", "5594", "5595", "5597", "5598", "5599", "5601", "5604", "5607", "5608", "5609", "5613", "5616", "5617", "5618", "5619", "5620", "5621", "5622", "5623", "5625", "5626", "5627", "5629", "5630", "5634", "5637", "5639", "5641", "5643", "5644", "5645", "5649", "5650", "5653", "5655", "5656", "5657", "5659", "5662", "5670", "5671", "5672", "5675", "5677", "5681", "5682", "5685", "5686", "5687", "5688", "5690", "5691", "5693", "5694", "5695", "5696", "5699", "5701", "5703", "5704", "5705", "5707", "5712", "5714", "5715", "5717", "5718", "5719", "5720", "5723", "5724", "5726", "5727", "5729", "5730", "5731", "5732", "5733", "5734", "5735", "5736", "5740", "5745", "5746", "5748", "5750", "5751", "5752", "5754", "5757", "5758", "5759", "5761", "5763", "5769", "5775", "5777", "5779", "5780", "5781", "5785", "5788", "5789", "5791", "5796", "5797", "5799", "5802", "5808", "5809", "5810", "5811", "5812", "5813", "5816", "5817", "5819", "5825", "5827", "5828", "5831", "5833", "5834", "5839", "5840", "5848", "5849", "5851", "5853", "5855", "5856", "5859", "5865", "5867", "5871", "5872", "5875", "5878", "5880", "5881", "5885", "5888", "5889", "5891", "5893", "5894", "5898", "5901", "5903", "5907", "5908", "5911", "5913", "5914", "5916", "5917", "5921", "5922", "5923", "5924", "5925", "5930", "5931", "5936", "5938", "5939", "5941", "5944", "5945", "5946", "5947", "5948", "5951", "5953", "5954", "5955", "5957", "5959", "5964", "5966", "5967", "5968", "5971", "5973", "5977", "5978", "5981", "5983", "5990", "5991", "5994", "5996", "5997", "6002", "6006", "6010", "6011", "6013", "6015", "6021", "6023", "6024", "6025", "6027", "6028", "6031", "6032", "6033", "6035", "6037", "6038", "6039", "6040", "6041", "6043", "6046", "6047", "6048", "6050", "6051", "6055", "6056", "6058", "6059", "6060", "6061", "6063", "6066", "6068", "6069", "6072", "6073", "6074", "6075", "6076", "6077", "6079", "6082", "6085", "6086", "6087", "6088", "6089", "6090", "6092", "6094", "6095", "6097", "6099", "6100", "6102", "6104", "6105", "6107", "6111", "6114", "6115", "6116", "6117", "6118", "6120", "6121", "6123", "6124", "6125", "6126", "6127", "6128", "6129", "6132", "6133", "6134", "6135", "6138", "6140", "6142", "6144", "6147", "6153", "6158", "6159", "6160", "6161", "6162", "6173", "6175", "6176", "6177", "6179", "6182", "6183", "6187", "6188", "6189", "6191", "6193", "6194", "6197", "6198", "6200", "6201", "6202", "6203", "6205", "6206", "6209", "6211", "6213", "6214", "6216", "6218", "6220", "6222", "6224", "6226", "6229", "6230", "6231", "6232", "6233", "6240", "6241", "6243", "6244", "6245", "6247", "6249", "6250", "6251", "6252", "6253", "6254", "6256", "6258", "6260", "6261", "6264", "6265", "6266", "6268", "6269", "6272", "6275", "6276", "6277", "6283", "6284", "6285", "6288", "6289", "6290", "6293", "6295", "6300", "6301", "6302", "6304", "6306", "6307", "6308", "6309", "6310", "6311", "6312", "6316", "6317", "6319", "6320", "6322", "6323", "6325", "6326", "6327", "6330", "6333", "6334", "6336", "6338", "6339", "6340", "6341", "6342", "6349", "6350", "6351", "6354", "6356", "6357", "6358", "6359", "6360", "6364", "6365", "6366", "6373", "6374", "6375", "6376", "6377", "6378", "6379", "6380", "6383", "6385", "6387", "6389", "6390", "6391", "6392", "6395", "6400", "6401", "6403", "6405", "6406", "6407", "6410", "6411", "6414", "6415", "6417", "6418", "6419", "6422", "6423", "6426", "6427", "6428", "6429", "6432", "6434", "6436", "6438", "6439", "6440", "6441", "6442", "6444", "6447", "6449", "6452", "6453", "6454", "6458", "6461", "6463", "6464", "6465", "6467", "6469", "6470", "6476", "6477", "6478", "6489", "6490", "6493", "6494", "6495", "6496", "6497", "6500", "6501", "6502", "6503", "6506", "6508", "6509", "6511", "6513", "6515", "6519", "6521", "6522", "6524", "6526", "6528", "6533", "6536", "6539", "6540", "6546", "6547", "6549", "6550", "6552", "6554", "6559", "6560", "6561", "6562", "6564", "6567", "6568", "6571", "6572", "6573", "6574", "6576", "6577", "6578", "6579", "6580", "6585", "6586", "6589", "6590", "6591", "6596", "6599", "6600", "6601", "6602", "6603", "6605", "6606", "6608", "6609", "6610", "6612", "6616", "6617", "6619", "6621", "6624", "6625", "6627", "6628", "6629", "6634", "6637", "6638", "6641", "6648", "6654", "6655", "6656", "6658", "6659", "6663", "6664", "6665", "6668", "6669", "6670", "6671", "6672", "6674", "6675", "6676", "6680", "6681", "6683", "6686", "6688", "6689", "6691", "6692", "6693", "6694", "6695", "6696", "6698", "6699", "6700", "6702", "6703", "6704", "6705", "6706", "6708", "6709", "6710", "6711", "6713", "6715", "6718", "6719", "6720", "6721", "6722", "6723", "6724", "6728", "6729", "6730", "6731", "6733", "6738", "6739", "6742", "6744", "6745", "6747", "6748", "6749", "6750", "6753", "6754", "6757", "6759", "6760", "6761", "6762", "6764", "6766", "6768", "6770", "6772", "6774", "6777", "6778", "6779", "6780", "6783", "6785", "6786", "6790", "6792", "6793", "6794", "6797", "6799", "6801", "6802", "6805", "6806", "6808", "6810", "6811", "6817", "6818", "6820", "6824", "6825", "6826", "6827", "6829", "6832", "6834", "6836", "6838", "6839", "6840", "6841", "6842", "6843", "6844", "6845", "6846", "6849", "6853", "6854", "6856", "6858", "6860", "6861", "6863", "6864", "6865", "6866", "6870", "6874", "6875", "6880", "6881", "6882", "6883", "6884", "6885", "6889", "6894", "6901", "6904", "6905", "6907", "6908", "6909", "6911", "6912", "6914", "6916", "6917", "6918", "6923", "6927", "6928", "6931", "6934", "6935", "6936", "6937", "6940", "6941", "6942", "6944", "6949", "6950", "6952", "6954", "6956", "6957", "6958", "6960", "6963", "6965", "6966", "6967", "6968", "6971", "6972", "6973", "6975", "6976", "6977", "6982", "6984", "6985", "6987", "6988", "6990", "6994", "6995", "6997", "6999", "7001", "7005", "7008", "7009", "7012", "7014", "7019", "7020", "7021", "7023", "7024", "7025", "7028", "7029", "7031", "7033", "7035", "7037", "7042", "7043", "7044", "7047", "7048", "7050", "7059", "7060", "7061", "7063", "7064", "7069", "7071", "7072", "7075", "7077", "7078", "7079", "7080", "7081", "7082", "7084", "7085", "7086", "7088", "7093", "7096", "7098", "7099", "7101", "7104", "7106", "7107", "7110", "7113", "7115", "7116", "7119", "7123", "7135", "7137", "7139", "7140", "7141", "7142", "7145", "7146", "7147", "7152", "7156", "7158", "7159", "7161", "7162", "7165", "7171", "7176", "7179", "7180", "7183", "7185", "7186", "7187", "7188", "7189", "7190", "7192", "7193", "7194", "7195", "7198", "7201", "7204", "7206", "7209", "7210", "7211", "7216", "7218", "7220", "7221", "7223", "7226", "7227", "7229", "7230", "7232", "7233", "7235", "7236", "7240", "7242", "7246", "7247", "7253", "7255", "7256", "7257", "7258", "7259", "7260", "7264", "7269", "7272", "7274", "7276", "7277", "7279", "7281", "7282", "7283", "7284", "7287", "7288", "7289", "7290", "7293", "7295", "7297", "7299", "7301", "7303", "7304", "7305", "7306", "7310", "7311", "7312", "7313", "7315", "7316", "7320", "7321", "7324", "7328", "7329", "7330", "7332", "7333", "7334", "7335", "7340", "7343", "7345", "7346", "7348", "7349", "7352", "7354", "7355", "7356", "7358", "7359", "7360", "7362", "7365", "7367", "7369", "7373", "7377", "7380", "7384", "7386", "7388", "7390", "7391", "7392", "7398", "7400", "7402", "7403", "7404", "7406", "7407", "7408", "7409", "7411", "7412", "7413", "7415", "7416", "7417", "7418", "7420", "7422", "7424", "7425", "7428", "7429", "7430", "7431", "7433", "7434", "7438", "7440", "7441", "7444", "7448", "7451", "7452", "7458", "7459", "7460", "7461", "7462", "7463", "7464", "7465", "7467", "7468", "7471", "7472", "7473", "7474", "7476", "7478", "7481", "7484", "7485", "7486", "7487", "7490", "7491", "7492", "7497", "7498", "7500", "7502", "7503", "7504", "7505", "7507", "7510", "7512", "7513", "7516", "7517", "7518", "7519", "7521", "7522", "7524", "7526", "7528", "7530", "7531", "7532", "7538", "7539", "7540", "7543", "7546", "7550", "7551", "7552", "7553", "7554", "7556", "7557", "7562", "7563", "7564", "7565", "7566", "7568", "7570", "7571", "7572", "7573", "7574", "7577", "7582", "7583", "7585", "7586", "7588", "7589", "7590", "7592", "7593", "7595", "7597", "7600", "7604", "7605", "7607", "7611", "7612", "7614", "7617", "7620", "7622", "7623", "7624", "7626", "7628", "7629", "7631", "7633", "7634", "7636", "7637", "7638", "7639", "7641", "7642", "7643", "7646", "7647", "7648", "7652", "7653", "7654", "7655", "7658", "7661", "7662", "7664", "7666", "7667", "7668", "7671", "7673", "7674", "7677", "7679", "7682", "7684", "7685", "7686", "7687", "7689", "7690", "7691", "7692", "7693", "7694", "7695", "7699", "7701", "7702", "7707", "7712", "7713", "7714", "7718", "7719", "7720", "7723", "7725", "7726", "7727", "7728", "7729", "7730", "7732", "7736", "7741", "7744", "7749", "7750", "7751", "7753", "7754", "7756", "7759", "7761", "7763", "7764", "7767", "7770", "7772", "7774", "7776", "7783", "7784", "7785", "7786", "7787", "7789", "7791", "7795", "7802", "7805", "7807", "7810", "7811", "7812", "7813", "7814", "7817", "7818", "7820", "7821", "7822", "7823", "7824", "7826", "7829", "7834", "7837", "7838", "7840", "7841", "7842", "7844", "7845", "7846", "7850", "7851", "7852", "7853", "7854", "7856", "7857", "7859", "7860", "7862", "7863", "7864", "7865", "7867", "7868", "7871", "7872", "7876", "7880", "7881", "7882", "7883", "7887", "7889", "7890", "7893", "7896", "7898", "7902", "7903", "7904", "7906", "7907", "7909", "7911", "7912", "7913", "7916", "7917", "7918", "7920", "7921", "7924", "7925", "7928", "7929", "7930", "7931", "7933", "7937", "7940", "7942", "7944", "7945", "7951", "7952", "7954", "7958", "7960", "7963", "7969", "7970", "7973", "7974", "7978", "7983", "7984", "7985", "7986", "7987", "7989", "7990", "7992", "7997", "8001", "8002", "8004", "8008", "8009", "8010", "8011", "8012", "8013", "8016", "8017", "8018", "8019", "8020", "8022", "8023", "8027", "8028", "8029", "8032", "8034", "8035", "8036", "8037", "8038", "8040", "8041", "8043", "8046", "8047", "8048", "8049", "8050", "8052", "8057", "8061", "8062", "8063", "8064", "8066", "8067", "8069", "8072", "8073", "8076", "8077", "8078", "8079", "8080", "8082", "8085", "8088", "8089", "8091", "8092", "8093", "8099", "8100", "8101", "8105", "8107", "8116", "8120", "8121", "8123", "8126", "8129", "8132", "8136", "8137", "8138", "8141", "8142", "8144", "8145", "8151", "8152", "8153", "8154", "8156", "8158", "8159", "8167", "8168", "8170", "8171", "8172", "8175", "8179", "8180", "8181", "8182", "8184", "8185", "8186", "8187", "8188", "8190", "8192", "8193", "8194", "8195", "8197", "8199", "8200", "8201", "8204", "8205", "8206", "8207", "8208", "8209", "8212", "8213", "8214", "8215", "8224", "8226", "8228", "8230", "8232", "8235", "8239", "8240", "8241", "8243", "8246", "8247", "8249", "8251", "8253", "8254", "8260", "8262", "8267", "8268", "8269", "8271", "8274", "8275", "8276", "8280", "8281", "8283", "8286", "8287", "8291", "8293", "8295", "8296", "8297", "8302", "8304", "8305", "8308", "8309", "8310", "8312", "8314", "8316", "8317", "8319", "8320", "8322", "8323", "8324", "8327", "8329", "8330", "8331", "8332", "8334", "8335", "8338", "8341", "8342", "8343", "8345", "8350", "8351", "8352", "8353", "8354", "8360", "8361", "8362", "8363", "8366", "8367", "8369", "8372", "8375", "8376", "8377", "8382", "8383", "8385", "8386", "8387", "8388", "8392", "8394", "8396", "8397", "8398", "8400", "8401", "8405", "8410", "8414", "8415", "8416", "8419", "8424", "8426", "8427", "8428", "8430", "8431", "8432", "8434", "8435", "8436", "8437", "8438", "8441", "8442", "8444", "8445", "8449", "8450", "8452", "8456", "8457", "8459", "8460", "8461", "8465", "8466", "8467", "8468", "8470", "8471", "8479", "8482", "8483", "8484", "8485", "8486", "8487", "8489", "8490", "8492", "8493", "8495", "8497", "8498", "8500", "8502", "8503", "8504", "8506", "8507", "8509", "8511", "8513", "8514", "8519", "8522", "8525", "8526", "8529", "8531", "8534", "8536", "8537", "8540", "8544", "8545", "8546", "8547", "8548", "8550", "8552", "8554", "8556", "8564", "8572", "8575", "8577", "8578", "8579", "8581", "8583", "8585", "8592", "8593", "8594", "8595", "8600", "8604", "8605", "8607", "8608", "8609", "8612", "8613", "8614", "8617", "8619", "8623", "8625", "8629", "8631", "8633", "8635", "8637", "8638", "8641", "8642", "8647", "8648", "8649", "8652", "8654", "8655", "8656", "8657", "8659", "8660", "8661", "8664", "8665", "8666", "8668", "8672", "8673", "8674", "8675", "8677", "8682", "8683", "8684", "8686", "8687", "8688", "8689", "8691", "8697", "8699", "8701", "8702", "8704", "8705", "8707", "8708", "8709", "8710", "8712", "8713", "8715", "8719", "8726", "8730", "8731", "8734", "8736", "8737", "8743", "8745", "8750", "8755", "8757", "8758", "8759", "8764", "8766", "8767", "8769", "8770", "8771", "8773", "8774", "8777", "8778", "8779", "8780", "8784", "8785", "8786", "8787", "8788", "8794", "8795", "8797", "8799", "8804", "8806", "8808", "8809", "8811", "8813", "8814", "8817", "8818", "8819", "8821", "8822", "8824", "8828", "8829", "8830", "8833", "8834", "8835", "8836", "8839", "8841", "8842", "8845", "8846", "8847", "8848", "8849", "8850", "8852", "8854", "8855", "8856", "8859", "8861", "8862", "8864", "8866", "8873", "8875", "8876", "8877", "8879", "8882", "8886", "8889", "8890", "8891", "8894", "8897", "8898", "8902", "8903", "8904", "8908", "8913", "8915", "8917", "8918", "8920", "8922", "8923", "8927", "8928", "8929", "8930", "8931", "8934", "8938", "8944", "8945", "8947", "8948", "8951", "8952", "8954", "8955", "8957", "8958", "8959", "8961", "8963", "8964", "8965", "8967", "8969", "8971", "8972", "8973", "8974", "8976", "8978", "8981", "8982", "8985", "8986", "8989", "8990", "8991", "8994", "9002", "9003", "9006", "9009", "9010", "9012", "9015", "9017", "9019", "9020", "9021", "9022", "9023", "9024", "9026", "9027", "9028", "9032", "9038", "9039", "9040", "9043", "9047", "9051", "9052", "9053", "9056", "9057", "9060", "9061", "9064", "9066", "9068", "9069", "9074", "9075", "9076", "9077", "9078", "9079", "9083", "9084", "9085", "9093", "9094", "9095", "9096", "9097", "9102", "9103", "9104", "9105", "9107", "9109", "9110", "9113", "9115", "9116", "9118", "9119", "9120", "9122", "9123", "9125", "9126", "9127", "9128", "9130", "9133", "9134", "9139", "9140", "9142", "9145", "9147", "9148", "9152", "9153", "9156", "9158", "9159", "9160", "9163", "9168", "9169", "9171", "9174", "9177", "9182", "9183", "9184", "9186", "9187", "9188", "9192", "9193", "9194", "9195", "9197", "9198", "9200", "9202", "9203", "9206", "9207", "9208", "9210", "9211", "9213", "9215", "9216", "9218", "9219", "9222", "9225", "9226", "9231", "9233", "9234", "9235", "9236", "9237", "9238", "9240", "9243", "9245", "9246", "9249", "9250", "9252", "9253", "9255", "9257", "9258", "9259", "9261", "9270", "9271", "9275", "9276", "9277", "9280", "9286", "9289", "9291", "9293", "9296", "9297", "9298", "9299", "9302", "9305", "9307", "9308", "9309", "9311", "9312", "9313", "9317", "9319", "9322", "9323", "9324", "9326", "9329", "9330", "9331", "9332", "9333", "9335", "9338", "9340", "9341", "9342", "9346", "9347", "9349", "9351", "9352", "9355", "9357", "9359", "9361", "9362", "9364", "9365", "9366", "9367", "9369", "9370", "9371", "9374", "9375", "9379", "9381", "9383", "9386", "9388", "9390", "9393", "9394", "9395", "9398", "9402", "9403", "9404", "9406", "9407", "9408", "9411", "9413", "9414", "9415", "9417", "9420", "9422", "9424", "9428", "9430", "9433", "9434", "9435", "9437", "9443", "9447", "9448", "9450", "9452", "9453", "9456", "9457", "9459", "9460", "9461", "9463", "9466", "9467", "9469", "9470", "9471", "9472", "9473", "9474", "9475", "9477", "9479", "9482", "9488", "9491", "9494", "9498", "9499", "9500", "9501", "9505", "9507", "9509", "9511", "9514", "9516", "9517", "9518", "9520", "9521", "9522", "9525", "9526", "9532", "9533", "9535", "9537", "9539", "9540", "9543", "9544", "9545", "9547", "9548", "9549", "9551", "9552", "9554", "9555", "9556", "9557", "9559", "9560", "9561", "9563", "9565", "9566", "9567", "9571", "9574", "9576", "9578", "9579", "9580", "9581", "9582", "9583", "9585", "9586", "9589", "9590", "9592", "9594", "9595", "9596", "9597", "9598", "9599", "9601", "9602", "9603", "9608", "9610", "9612", "9614", "9616", "9617", "9618", "9620", "9623", "9624", "9628", "9630", "9632", "9637", "9638", "9640", "9645", "9646", "9647", "9648", "9652", "9655", "9657", "9658", "9659", "9660", "9662", "9663", "9667", "9668", "9677", "9678", "9681", "9682", "9683", "9685", "9688", "9689", "9691", "9693", "9695", "9696", "9698", "9699", "9701", "9707", "9708", "9709", "9710", "9713", "9716", "9721", "9724", "9725", "9726", "9727", "9733", "9736", "9738", "9739", "9743", "9744", "9747", "9750", "9752", "9754", "9758", "9760", "9761", "9763", "9765", "9766", "9767", "9770", "9772", "9775", "9776", "9777", "9780", "9782", "9783", "9786", "9787", "9790", "9793", "9796", "9799", "9800", "9801", "9802", "9803", "9806", "9808", "9809", "9813", "9814", "9815", "9816", "9817", "9819", "9820", "9821", "9822", "9823", "9826", "9827", "9828", "9830", "9831", "9834", "9837", "9839", "9843", "9850", "9855", "9856", "9860", "9862", "9863", "9865", "9867", "9868", "9869", "9870", "9871", "9876", "9877", "9883", "9884", "9887", "9890", "9892", "9893", "9895", "9898", "9904", "9905", "9907", "9910", "9913", "9915", "9917", "9922", "9924", "9925", "9926", "9927", "9928", "9929", "9930", "9931", "9932", "9935", "9937", "9939", "9941", "9942", "9943", "9945", "9946", "9947", "9949", "9950", "9952", "9953", "9954", "9955", "9959", "9962", "9964", "9965", "9968", "9969", "9970", "9971", "9974", "9975", "9978", "9979", "9980", "9984", "9985", "9986", "9987", "9989", "9992", "9996", "9997", "9999"]],
+ "xtest" : ["int" , ["0", "2", "6", "7", "9", "11", "12", "17", "20", "24", "25", "26", "29", "31", "32", "34", "35", "38", "40", "42", "43", "46", "50", "51", "53", "55", "56", "61", "63", "67", "69", "70", "71", "72", "74", "79", "80", "83", "84", "88", "89", "90", "91", "92", "95", "98", "99", "100", "101", "103", "104", "107", "108", "109", "113", "115", "116", "120", "121", "123", "125", "126", "127", "130", "135", "136", "141", "142", "143", "145", "146", "149", "155", "157", "159", "160", "161", "166", "168", "169", "171", "172", "176", "178", "181", "183", "186", "188", "189", "190", "192", "193", "194", "196", "197", "198", "199", "200", "201", "202", "204", "205", "207", "209", "210", "211", "212", "213", "214", "217", "218", "219", "220", "221", "222", "223", "225", "228", "229", "235", "239", "240", "243", "244", "247", "248", "253", "255", "260", "263", "264", "266", "268", "269", "271", "274", "276", "280", "281", "284", "287", "288", "290", "291", "292", "297", "299", "300", "301", "304", "306", "307", "309", "311", "314", "320", "321", "322", "323", "329", "330", "331", "332", "333", "336", "338", "340", "341", "342", "343", "344", "345", "348", "351", "352", "355", "358", "359", "360", "361", "364", "365", "366", "367", "368", "369", "371", "375", "379", "380", "384", "385", "386", "387", "388", "389", "390", "395", "396", "398", "401", "406", "408", "413", "415", "418", "420", "422", "424", "425", "426", "427", "428", "429", "431", "432", "434", "435", "437", "439", "440", "447", "451", "453", "455", "456", "458", "459", "462", "463", "464", "469", "473", "475", "476", "477", "478", "479", "480", "482", "483", "484", "486", "487", "489", "490", "491", "492", "493", "494", "495", "501", "503", "504", "507", "509", "510", "515", "516", "522", "523", "525", "529", "533", "534", "536", "537", "538", "540", "542", "543", "544", "545", "546", "548", "550", "552", "553", "554", "555", "556", "557", "560", "561", "565", "566", "568", "569", "571", "572", "573", "574", "575", "576", "577", "578", "579", "580", "581", "582", "584", "590", "592", "593", "595", "601", "604", "605", "607", "609", "612", "614", "615", "616", "617", "625", "627", "629", "630", "632", "634", "635", "636", "638", "647", "649", "651", "652", "653", "654", "658", "660", "661", "662", "663", "666", "668", "669", "671", "673", "678", "679", "680", "682", "683", "686", "691", "693", "697", "701", "703", "705", "706", "709", "711", "713", "719", "721", "722", "723", "724", "726", "728", "730", "731", "732", "733", "734", "738", "742", "744", "745", "747", "754", "755", "756", "757", "759", "760", "762", "763", "764", "765", "766", "767", "768", "770", "772", "774", "779", "782", "784", "785", "788", "790", "791", "794", "796", "800", "801", "802", "803", "804", "805", "806", "807", "808", "810", "814", "816", "824", "830", "831", "836", "837", "842", "844", "845", "846", "847", "849", "850", "853", "855", "856", "858", "859", "860", "861", "863", "864", "865", "866", "870", "873", "876", "878", "879", "881", "882", "884", "885", "886", "890", "891", "893", "895", "897", "901", "902", "903", "905", "906", "908", "909", "911", "920", "923", "925", "926", "929", "930", "931", "934", "938", "939", "940", "941", "942", "943", "945", "946", "948", "949", "950", "952", "953", "954", "955", "956", "957", "958", "960", "963", "964", "965", "967", "968", "969", "971", "973", "975", "977", "978", "981", "982", "984", "987", "989", "990", "991", "992", "994", "995", "998", "999", "1000", "1003", "1004", "1005", "1008", "1010", "1019", "1020", "1023", "1030", "1031", "1032", "1033", "1035", "1036", "1037", "1042", "1043", "1048", "1049", "1050", "1053", "1060", "1061", "1063", "1065", "1066", "1068", "1072", "1073", "1074", "1075", "1076", "1079", "1082", "1085", "1086", "1087", "1091", "1092", "1093", "1097", "1099", "1101", "1102", "1103", "1105", "1106", "1107", "1109", "1112", "1113", "1114", "1115", "1116", "1119", "1125", "1126", "1127", "1128", "1130", "1131", "1132", "1133", "1134", "1137", "1138", "1141", "1143", "1145", "1146", "1147", "1149", "1151", "1153", "1154", "1155", "1158", "1160", "1163", "1165", "1169", "1173", "1175", "1179", "1180", "1181", "1182", "1183", "1184", "1192", "1193", "1195", "1197", "1198", "1199", "1200", "1201", "1202", "1204", "1205", "1206", "1207", "1215", "1216", "1217", "1218", "1219", "1220", "1222", "1225", "1226", "1227", "1228", "1230", "1232", "1233", "1234", "1235", "1236", "1238", "1246", "1248", "1249", "1251", "1252", "1253", "1255", "1256", "1258", "1260", "1261", "1262", "1264", "1265", "1266", "1267", "1268", "1270", "1271", "1274", "1278", "1279", "1283", "1284", "1286", "1287", "1291", "1299", "1301", "1302", "1304", "1305", "1306", "1308", "1310", "1314", "1318", "1319", "1320", "1322", "1323", "1325", "1326", "1333", "1337", "1338", "1339", "1344", "1346", "1348", "1350", "1355", "1357", "1358", "1359", "1360", "1362", "1366", "1370", "1373", "1374", "1377", "1378", "1379", "1381", "1383", "1384", "1386", "1387", "1388", "1389", "1391", "1397", "1398", "1400", "1404", "1407", "1409", "1410", "1411", "1412", "1414", "1417", "1419", "1420", "1421", "1427", "1429", "1432", "1434", "1436", "1438", "1442", "1444", "1448", "1449", "1450", "1451", "1452", "1454", "1455", "1456", "1459", "1460", "1461", "1468", "1469", "1470", "1471", "1474", "1477", "1481", "1486", "1487", "1488", "1494", "1495", "1497", "1498", "1499", "1500", "1501", "1503", "1504", "1507", "1510", "1511", "1512", "1516", "1517", "1519", "1520", "1522", "1525", "1526", "1527", "1529", "1530", "1531", "1532", "1533", "1534", "1536", "1537", "1538", "1539", "1540", "1542", "1543", "1547", "1548", "1551", "1552", "1554", "1557", "1558", "1561", "1566", "1570", "1574", "1575", "1577", "1578", "1580", "1581", "1583", "1584", "1585", "1588", "1590", "1591", "1594", "1595", "1598", "1599", "1600", "1601", "1602", "1604", "1607", "1608", "1609", "1610", "1613", "1614", "1615", "1617", "1618", "1620", "1622", "1623", "1624", "1625", "1626", "1627", "1628", "1629", "1631", "1637", "1638", "1640", "1644", "1645", "1646", "1647", "1652", "1655", "1657", "1658", "1661", "1663", "1665", "1666", "1669", "1670", "1671", "1674", "1676", "1679", "1680", "1682", "1684", "1685", "1686", "1688", "1689", "1691", "1692", "1694", "1696", "1700", "1702", "1703", "1705", "1708", "1709", "1710", "1711", "1712", "1715", "1717", "1718", "1723", "1724", "1725", "1726", "1727", "1731", "1732", "1733", "1735", "1738", "1741", "1742", "1744", "1745", "1747", "1748", "1749", "1750", "1751", "1752", "1756", "1757", "1759", "1760", "1761", "1763", "1764", "1769", "1770", "1771", "1772", "1773", "1774", "1776", "1778", "1780", "1781", "1786", "1787", "1788", "1791", "1792", "1793", "1794", "1796", "1797", "1798", "1799", "1802", "1805", "1806", "1807", "1808", "1809", "1812", "1813", "1815", "1818", "1819", "1822", "1823", "1824", "1825", "1827", "1829", "1830", "1831", "1832", "1833", "1836", "1838", "1839", "1840", "1841", "1842", "1849", "1850", "1852", "1853", "1854", "1855", "1857", "1858", "1861", "1864", "1865", "1867", "1868", "1870", "1871", "1873", "1874", "1877", "1878", "1880", "1881", "1886", "1891", "1892", "1894", "1895", "1897", "1899", "1901", "1905", "1906", "1907", "1908", "1909", "1910", "1911", "1918", "1922", "1925", "1926", "1927", "1928", "1929", "1930", "1931", "1932", "1934", "1937", "1938", "1939", "1940", "1941", "1945", "1948", "1951", "1952", "1953", "1955", "1957", "1962", "1963", "1964", "1965", "1966", "1968", "1970", "1972", "1974", "1978", "1979", "1980", "1981", "1984", "1986", "1988", "1990", "1991", "1992", "1994", "2000", "2001", "2002", "2005", "2006", "2013", "2015", "2017", "2018", "2019", "2021", "2022", "2025", "2027", "2028", "2029", "2035", "2036", "2037", "2040", "2042", "2045", "2047", "2053", "2056", "2057", "2063", "2065", "2068", "2069", "2073", "2074", "2075", "2077", "2079", "2081", "2082", "2083", "2084", "2090", "2092", "2093", "2095", "2096", "2099", "2102", "2103", "2106", "2112", "2113", "2115", "2116", "2117", "2121", "2122", "2123", "2124", "2125", "2128", "2129", "2131", "2132", "2133", "2135", "2136", "2138", "2139", "2142", "2143", "2144", "2145", "2147", "2148", "2149", "2153", "2157", "2159", "2163", "2166", "2167", "2168", "2169", "2173", "2174", "2175", "2179", "2181", "2183", "2184", "2186", "2187", "2191", "2192", "2194", "2195", "2196", "2198", "2204", "2207", "2208", "2210", "2211", "2214", "2215", "2217", "2218", "2221", "2223", "2224", "2227", "2230", "2232", "2233", "2235", "2236", "2237", "2239", "2241", "2242", "2246", "2247", "2250", "2256", "2257", "2258", "2259", "2263", "2264", "2267", "2269", "2270", "2272", "2273", "2279", "2280", "2282", "2285", "2286", "2288", "2289", "2290", "2293", "2294", "2296", "2298", "2299", "2300", "2303", "2305", "2306", "2307", "2310", "2312", "2314", "2316", "2317", "2319", "2320", "2323", "2324", "2326", "2327", "2338", "2341", "2342", "2345", "2349", "2352", "2353", "2355", "2357", "2358", "2359", "2361", "2362", "2366", "2367", "2368", "2369", "2371", "2372", "2375", "2379", "2381", "2382", "2384", "2386", "2387", "2389", "2391", "2392", "2393", "2394", "2397", "2398", "2401", "2405", "2406", "2407", "2408", "2410", "2412", "2418", "2419", "2420", "2422", "2423", "2426", "2430", "2431", "2432", "2433", "2434", "2435", "2436", "2437", "2440", "2442", "2443", "2446", "2451", "2455", "2460", "2462", "2463", "2464", "2465", "2469", "2470", "2471", "2474", "2478", "2480", "2481", "2484", "2485", "2487", "2488", "2489", "2491", "2492", "2494", "2498", "2502", "2503", "2504", "2505", "2509", "2510", "2512", "2513", "2514", "2515", "2516", "2518", "2520", "2521", "2522", "2524", "2525", "2526", "2527", "2528", "2529", "2530", "2535", "2538", "2539", "2540", "2543", "2544", "2546", "2547", "2548", "2549", "2551", "2552", "2555", "2556", "2558", "2562", "2563", "2564", "2566", "2570", "2571", "2572", "2573", "2575", "2576", "2578", "2583", "2584", "2585", "2588", "2589", "2591", "2592", "2595", "2596", "2599", "2601", "2605", "2607", "2608", "2617", "2618", "2620", "2621", "2622", "2624", "2625", "2626", "2627", "2633", "2634", "2636", "2638", "2640", "2641", "2642", "2643", "2648", "2649", "2654", "2655", "2656", "2657", "2658", "2659", "2665", "2667", "2670", "2671", "2672", "2675", "2676", "2679", "2680", "2684", "2685", "2688", "2689", "2695", "2698", "2699", "2701", "2711", "2712", "2713", "2714", "2718", "2719", "2720", "2722", "2727", "2729", "2741", "2744", "2747", "2748", "2749", "2750", "2751", "2752", "2754", "2755", "2756", "2757", "2758", "2760", "2763", "2764", "2765", "2766", "2767", "2768", "2769", "2771", "2773", "2775", "2777", "2778", "2780", "2783", "2784", "2785", "2786", "2792", "2793", "2794", "2798", "2800", "2801", "2803", "2804", "2805", "2806", "2809", "2811", "2817", "2820", "2821", "2822", "2823", "2827", "2828", "2829", "2830", "2831", "2832", "2836", "2842", "2843", "2844", "2846", "2849", "2852", "2853", "2854", "2855", "2856", "2857", "2860", "2861", "2862", "2863", "2864", "2865", "2870", "2871", "2872", "2875", "2881", "2882", "2888", "2893", "2896", "2897", "2898", "2899", "2902", "2904", "2906", "2907", "2908", "2910", "2911", "2914", "2915", "2917", "2924", "2925", "2926", "2930", "2931", "2933", "2937", "2938", "2939", "2942", "2943", "2946", "2947", "2950", "2955", "2957", "2958", "2962", "2963", "2964", "2968", "2970", "2971", "2973", "2978", "2979", "2981", "2983", "2984", "2986", "2991", "2992", "2994", "2997", "2998", "2999", "3000", "3003", "3004", "3008", "3009", "3013", "3014", "3015", "3016", "3017", "3021", "3024", "3025", "3026", "3029", "3030", "3031", "3032", "3033", "3035", "3038", "3039", "3040", "3045", "3049", "3051", "3053", "3055", "3057", "3061", "3062", "3064", "3065", "3066", "3067", "3069", "3071", "3072", "3074", "3077", "3079", "3080", "3081", "3082", "3084", "3086", "3087", "3088", "3091", "3092", "3093", "3096", "3097", "3099", "3104", "3105", "3106", "3107", "3109", "3110", "3111", "3114", "3115", "3117", "3120", "3121", "3122", "3125", "3127", "3129", "3130", "3132", "3134", "3135", "3139", "3141", "3142", "3143", "3144", "3146", "3147", "3148", "3149", "3150", "3151", "3153", "3156", "3157", "3158", "3159", "3160", "3161", "3166", "3167", "3169", "3171", "3175", "3182", "3183", "3185", "3186", "3187", "3188", "3189", "3191", "3193", "3195", "3199", "3200", "3201", "3204", "3205", "3207", "3210", "3211", "3214", "3218", "3220", "3221", "3223", "3225", "3228", "3231", "3233", "3237", "3240", "3241", "3242", "3243", "3244", "3246", "3247", "3250", "3252", "3253", "3254", "3255", "3258", "3260", "3263", "3266", "3268", "3269", "3272", "3273", "3274", "3275", "3281", "3283", "3284", "3286", "3287", "3288", "3290", "3291", "3292", "3293", "3294", "3296", "3297", "3298", "3301", "3303", "3304", "3310", "3311", "3312", "3313", "3316", "3318", "3322", "3324", "3325", "3327", "3328", "3329", "3332", "3335", "3336", "3337", "3339", "3341", "3342", "3344", "3345", "3346", "3349", "3350", "3352", "3356", "3357", "3358", "3360", "3363", "3364", "3365", "3369", "3371", "3380", "3381", "3386", "3387", "3388", "3390", "3391", "3392", "3394", "3395", "3396", "3399", "3400", "3402", "3404", "3405", "3407", "3410", "3412", "3414", "3415", "3416", "3418", "3423", "3425", "3427", "3431", "3433", "3435", "3436", "3441", "3443", "3444", "3445", "3446", "3447", "3449", "3450", "3451", "3452", "3453", "3454", "3457", "3459", "3460", "3461", "3465", "3466", "3467", "3468", "3472", "3473", "3474", "3475", "3476", "3477", "3478", "3480", "3481", "3483", "3484", "3486", "3489", "3490", "3493", "3496", "3499", "3501", "3503", "3505", "3507", "3508", "3509", "3510", "3513", "3517", "3518", "3521", "3523", "3533", "3534", "3535", "3536", "3538", "3543", "3544", "3545", "3547", "3548", "3549", "3551", "3556", "3557", "3558", "3562", "3564", "3566", "3569", "3570", "3574", "3575", "3576", "3577", "3578", "3581", "3582", "3583", "3584", "3586", "3587", "3593", "3596", "3599", "3600", "3602", "3604", "3605", "3606", "3607", "3610", "3612", "3614", "3615", "3616", "3617", "3619", "3622", "3624", "3626", "3627", "3628", "3629", "3631", "3632", "3637", "3641", "3642", "3643", "3644", "3645", "3648", "3650", "3654", "3655", "3661", "3665", "3666", "3667", "3668", "3669", "3670", "3674", "3678", "3682", "3685", "3689", "3691", "3692", "3694", "3695", "3696", "3697", "3698", "3699", "3701", "3705", "3707", "3708", "3710", "3712", "3713", "3714", "3715", "3717", "3718", "3719", "3721", "3724", "3729", "3730", "3731", "3732", "3734", "3736", "3739", "3741", "3742", "3751", "3759", "3764", "3765", "3766", "3767", "3768", "3771", "3772", "3774", "3775", "3777", "3778", "3782", "3783", "3784", "3786", "3787", "3790", "3792", "3793", "3794", "3797", "3798", "3799", "3800", "3801", "3802", "3805", "3813", "3814", "3815", "3816", "3817", "3820", "3821", "3824", "3825", "3827", "3829", "3831", "3832", "3833", "3834", "3836", "3838", "3839", "3841", "3842", "3846", "3847", "3848", "3851", "3853", "3855", "3857", "3860", "3864", "3865", "3866", "3867", "3868", "3869", "3871", "3874", "3875", "3876", "3877", "3878", "3881", "3882", "3884", "3885", "3886", "3887", "3891", "3893", "3897", "3899", "3904", "3911", "3913", "3915", "3917", "3919", "3920", "3923", "3925", "3927", "3931", "3932", "3933", "3937", "3939", "3943", "3946", "3947", "3949", "3952", "3953", "3957", "3958", "3959", "3960", "3964", "3965", "3967", "3974", "3975", "3976", "3977", "3978", "3981", "3984", "3986", "3988", "3989", "3990", "3991", "3992", "3993", "3994", "3995", "3996", "3997", "3999", "4001", "4004", "4005", "4007", "4008", "4012", "4013", "4014", "4015", "4016", "4017", "4018", "4019", "4022", "4023", "4024", "4030", "4031", "4033", "4035", "4037", "4038", "4039", "4041", "4042", "4043", "4044", "4045", "4047", "4049", "4050", "4051", "4052", "4053", "4054", "4055", "4056", "4057", "4059", "4060", "4061", "4062", "4066", "4068", "4070", "4072", "4073", "4075", "4077", "4078", "4079", "4080", "4081", "4082", "4083", "4084", "4087", "4088", "4091", "4092", "4094", "4097", "4098", "4103", "4104", "4105", "4107", "4109", "4110", "4111", "4114", "4115", "4116", "4117", "4118", "4119", "4120", "4122", "4123", "4124", "4127", "4128", "4130", "4131", "4139", "4140", "4141", "4142", "4144", "4150", "4154", "4155", "4157", "4159", "4161", "4162", "4163", "4165", "4170", "4174", "4175", "4176", "4177", "4178", "4180", "4181", "4186", "4187", "4194", "4200", "4201", "4204", "4205", "4208", "4209", "4210", "4211", "4212", "4213", "4216", "4217", "4218", "4220", "4221", "4222", "4224", "4228", "4229", "4230", "4231", "4232", "4233", "4235", "4237", "4238", "4239", "4243", "4244", "4245", "4247", "4248", "4252", "4257", "4258", "4260", "4262", "4263", "4269", "4273", "4279", "4280", "4281", "4284", "4292", "4293", "4295", "4297", "4298", "4299", "4302", "4303", "4304", "4307", "4310", "4311", "4313", "4316", "4317", "4319", "4321", "4326", "4328", "4330", "4334", "4336", "4339", "4340", "4341", "4345", "4348", "4352", "4353", "4356", "4357", "4360", "4361", "4365", "4367", "4368", "4370", "4377", "4378", "4380", "4382", "4383", "4384", "4385", "4387", "4389", "4393", "4395", "4396", "4397", "4401", "4404", "4407", "4415", "4417", "4418", "4419", "4420", "4421", "4422", "4424", "4428", "4430", "4433", "4435", "4437", "4442", "4443", "4444", "4446", "4447", "4448", "4450", "4452", "4453", "4458", "4462", "4464", "4465", "4468", "4469", "4470", "4471", "4472", "4473", "4475", "4478", "4479", "4480", "4483", "4484", "4485", "4487", "4488", "4489", "4490", "4491", "4492", "4494", "4496", "4497", "4499", "4501", "4505", "4507", "4508", "4511", "4514", "4515", "4520", "4523", "4526", "4528", "4529", "4531", "4532", "4533", "4534", "4537", "4538", "4539", "4541", "4542", "4543", "4545", "4546", "4548", "4549", "4550", "4551", "4553", "4554", "4555", "4558", "4559", "4561", "4563", "4564", "4565", "4566", "4567", "4568", "4569", "4570", "4571", "4573", "4575", "4579", "4582", "4584", "4586", "4589", "4590", "4591", "4593", "4596", "4597", "4598", "4599", "4600", "4601", "4602", "4604", "4605", "4606", "4607", "4608", "4611", "4612", "4613", "4618", "4619", "4620", "4625", "4629", "4630", "4631", "4632", "4637", "4638", "4641", "4643", "4644", "4645", "4647", "4648", "4652", "4655", "4658", "4659", "4661", "4663", "4664", "4669", "4670", "4672", "4682", "4685", "4690", "4692", "4693", "4694", "4695", "4698", "4699", "4706", "4707", "4709", "4710", "4712", "4713", "4714", "4715", "4716", "4717", "4719", "4723", "4727", "4728", "4729", "4731", "4733", "4735", "4736", "4737", "4742", "4743", "4745", "4748", "4750", "4752", "4754", "4755", "4757", "4761", "4762", "4763", "4764", "4765", "4766", "4767", "4771", "4775", "4778", "4781", "4782", "4783", "4785", "4786", "4791", "4793", "4796", "4797", "4798", "4805", "4808", "4810", "4812", "4813", "4815", "4818", "4819", "4821", "4824", "4828", "4829", "4833", "4836", "4838", "4839", "4841", "4843", "4848", "4851", "4853", "4854", "4855", "4856", "4858", "4859", "4860", "4862", "4864", "4865", "4866", "4867", "4874", "4876", "4877", "4878", "4879", "4880", "4882", "4883", "4884", "4886", "4887", "4890", "4892", "4894", "4895", "4896", "4898", "4899", "4902", "4903", "4904", "4906", "4908", "4909", "4911", "4914", "4915", "4921", "4923", "4926", "4927", "4933", "4936", "4937", "4938", "4940", "4941", "4948", "4949", "4951", "4952", "4956", "4959", "4961", "4962", "4963", "4964", "4966", "4968", "4969", "4970", "4979", "4981", "4982", "4983", "4987", "4989", "4991", "4992", "4994", "4995", "4996", "4999", "5000", "5001", "5002", "5007", "5009", "5011", "5014", "5016", "5017", "5018", "5019", "5020", "5023", "5025", "5027", "5029", "5030", "5032", "5033", "5035", "5036", "5037", "5038", "5040", "5045", "5046", "5047", "5049", "5050", "5052", "5053", "5054", "5059", "5061", "5062", "5063", "5066", "5068", "5069", "5070", "5075", "5076", "5078", "5079", "5082", "5085", "5087", "5088", "5089", "5091", "5093", "5095", "5098", "5102", "5103", "5107", "5108", "5109", "5111", "5115", "5118", "5119", "5123", "5124", "5126", "5127", "5128", "5130", "5132", "5135", "5136", "5138", "5139", "5150", "5151", "5152", "5156", "5157", "5160", "5162", "5163", "5165", "5167", "5169", "5172", "5173", "5174", "5176", "5179", "5182", "5183", "5184", "5186", "5188", "5191", "5193", "5194", "5196", "5198", "5199", "5205", "5208", "5209", "5210", "5211", "5212", "5217", "5218", "5219", "5220", "5221", "5222", "5223", "5226", "5227", "5231", "5234", "5235", "5237", "5240", "5241", "5245", "5246", "5249", "5250", "5251", "5252", "5256", "5257", "5258", "5259", "5260", "5261", "5262", "5263", "5264", "5266", "5267", "5268", "5270", "5271", "5276", "5277", "5278", "5282", "5283", "5284", "5285", "5288", "5289", "5290", "5302", "5303", "5304", "5305", "5308", "5309", "5310", "5312", "5313", "5314", "5317", "5319", "5324", "5325", "5327", "5328", "5329", "5330", "5331", "5335", "5336", "5339", "5340", "5343", "5345", "5347", "5348", "5351", "5355", "5356", "5357", "5359", "5363", "5366", "5367", "5368", "5370", "5373", "5374", "5375", "5377", "5381", "5382", "5383", "5386", "5387", "5393", "5394", "5398", "5402", "5403", "5405", "5406", "5411", "5412", "5413", "5414", "5415", "5417", "5420", "5421", "5423", "5424", "5425", "5428", "5430", "5432", "5436", "5437", "5438", "5440", "5441", "5447", "5449", "5450", "5451", "5453", "5459", "5462", "5463", "5465", "5466", "5467", "5470", "5471", "5473", "5474", "5475", "5477", "5478", "5480", "5481", "5483", "5484", "5487", "5488", "5491", "5492", "5493", "5494", "5495", "5497", "5499", "5502", "5503", "5505", "5508", "5510", "5511", "5512", "5515", "5517", "5522", "5524", "5526", "5527", "5530", "5531", "5532", "5535", "5536", "5538", "5542", "5545", "5548", "5549", "5552", "5553", "5554", "5557", "5563", "5565", "5568", "5572", "5573", "5576", "5577", "5578", "5580", "5585", "5586", "5587", "5588", "5589", "5590", "5596", "5600", "5602", "5603", "5605", "5606", "5610", "5611", "5612", "5614", "5615", "5624", "5628", "5631", "5632", "5633", "5635", "5636", "5638", "5640", "5642", "5646", "5647", "5648", "5651", "5652", "5654", "5658", "5660", "5661", "5663", "5664", "5665", "5666", "5667", "5668", "5669", "5673", "5674", "5676", "5678", "5679", "5680", "5683", "5684", "5689", "5692", "5697", "5698", "5700", "5702", "5706", "5708", "5709", "5710", "5711", "5713", "5716", "5721", "5722", "5725", "5728", "5737", "5738", "5739", "5741", "5742", "5743", "5744", "5747", "5749", "5753", "5755", "5756", "5760", "5762", "5764", "5765", "5766", "5767", "5768", "5770", "5771", "5772", "5773", "5774", "5776", "5778", "5782", "5783", "5784", "5786", "5787", "5790", "5792", "5793", "5794", "5795", "5798", "5800", "5801", "5803", "5804", "5805", "5806", "5807", "5814", "5815", "5818", "5820", "5821", "5822", "5823", "5824", "5826", "5829", "5830", "5832", "5835", "5836", "5837", "5838", "5841", "5842", "5843", "5844", "5845", "5846", "5847", "5850", "5852", "5854", "5857", "5858", "5860", "5861", "5862", "5863", "5864", "5866", "5868", "5869", "5870", "5873", "5874", "5876", "5877", "5879", "5882", "5883", "5884", "5886", "5887", "5890", "5892", "5895", "5896", "5897", "5899", "5900", "5902", "5904", "5905", "5906", "5909", "5910", "5912", "5915", "5918", "5919", "5920", "5926", "5927", "5928", "5929", "5932", "5933", "5934", "5935", "5937", "5940", "5942", "5943", "5949", "5950", "5952", "5956", "5958", "5960", "5961", "5962", "5963", "5965", "5969", "5970", "5972", "5974", "5975", "5976", "5979", "5980", "5982", "5984", "5985", "5986", "5987", "5988", "5989", "5992", "5993", "5995", "5998", "5999", "6000", "6001", "6003", "6004", "6005", "6007", "6008", "6009", "6012", "6014", "6016", "6017", "6018", "6019", "6020", "6022", "6026", "6029", "6030", "6034", "6036", "6042", "6044", "6045", "6049", "6052", "6053", "6054", "6057", "6062", "6064", "6065", "6067", "6070", "6071", "6078", "6080", "6081", "6083", "6084", "6091", "6093", "6096", "6098", "6101", "6103", "6106", "6108", "6109", "6110", "6112", "6113", "6119", "6122", "6130", "6131", "6136", "6137", "6139", "6141", "6143", "6145", "6146", "6148", "6149", "6150", "6151", "6152", "6154", "6155", "6156", "6157", "6163", "6164", "6165", "6166", "6167", "6168", "6169", "6170", "6171", "6172", "6174", "6178", "6180", "6181", "6184", "6185", "6186", "6190", "6192", "6195", "6196", "6199", "6204", "6207", "6208", "6210", "6212", "6215", "6217", "6219", "6221", "6223", "6225", "6227", "6228", "6234", "6235", "6236", "6237", "6238", "6239", "6242", "6246", "6248", "6255", "6257", "6259", "6262", "6263", "6267", "6270", "6271", "6273", "6274", "6278", "6279", "6280", "6281", "6282", "6286", "6287", "6291", "6292", "6294", "6296", "6297", "6298", "6299", "6303", "6305", "6313", "6314", "6315", "6318", "6321", "6324", "6328", "6329", "6331", "6332", "6335", "6337", "6343", "6344", "6345", "6346", "6347", "6348", "6352", "6353", "6355", "6361", "6362", "6363", "6367", "6368", "6369", "6370", "6371", "6372", "6381", "6382", "6384", "6386", "6388", "6393", "6394", "6396", "6397", "6398", "6399", "6402", "6404", "6408", "6409", "6412", "6413", "6416", "6420", "6421", "6424", "6425", "6430", "6431", "6433", "6435", "6437", "6443", "6445", "6446", "6448", "6450", "6451", "6455", "6456", "6457", "6459", "6460", "6462", "6466", "6468", "6471", "6472", "6473", "6474", "6475", "6479", "6480", "6481", "6482", "6483", "6484", "6485", "6486", "6487", "6488", "6491", "6492", "6498", "6499", "6504", "6505", "6507", "6510", "6512", "6514", "6516", "6517", "6518", "6520", "6523", "6525", "6527", "6529", "6530", "6531", "6532", "6534", "6535", "6537", "6538", "6541", "6542", "6543", "6544", "6545", "6548", "6551", "6553", "6555", "6556", "6557", "6558", "6563", "6565", "6566", "6569", "6570", "6575", "6581", "6582", "6583", "6584", "6587", "6588", "6592", "6593", "6594", "6595", "6597", "6598", "6604", "6607", "6611", "6613", "6614", "6615", "6618", "6620", "6622", "6623", "6626", "6630", "6631", "6632", "6633", "6635", "6636", "6639", "6640", "6642", "6643", "6644", "6645", "6646", "6647", "6649", "6650", "6651", "6652", "6653", "6657", "6660", "6661", "6662", "6666", "6667", "6673", "6677", "6678", "6679", "6682", "6684", "6685", "6687", "6690", "6697", "6701", "6707", "6712", "6714", "6716", "6717", "6725", "6726", "6727", "6732", "6734", "6735", "6736", "6737", "6740", "6741", "6743", "6746", "6751", "6752", "6755", "6756", "6758", "6763", "6765", "6767", "6769", "6771", "6773", "6775", "6776", "6781", "6782", "6784", "6787", "6788", "6789", "6791", "6795", "6796", "6798", "6800", "6803", "6804", "6807", "6809", "6812", "6813", "6814", "6815", "6816", "6819", "6821", "6822", "6823", "6828", "6830", "6831", "6833", "6835", "6837", "6847", "6848", "6850", "6851", "6852", "6855", "6857", "6859", "6862", "6867", "6868", "6869", "6871", "6872", "6873", "6876", "6877", "6878", "6879", "6886", "6887", "6888", "6890", "6891", "6892", "6893", "6895", "6896", "6897", "6898", "6899", "6900", "6902", "6903", "6906", "6910", "6913", "6915", "6919", "6920", "6921", "6922", "6924", "6925", "6926", "6929", "6930", "6932", "6933", "6938", "6939", "6943", "6945", "6946", "6947", "6948", "6951", "6953", "6955", "6959", "6961", "6962", "6964", "6969", "6970", "6974", "6978", "6979", "6980", "6981", "6983", "6986", "6989", "6991", "6992", "6993", "6996", "6998", "7000", "7002", "7003", "7004", "7006", "7007", "7010", "7011", "7013", "7015", "7016", "7017", "7018", "7022", "7026", "7027", "7030", "7032", "7034", "7036", "7038", "7039", "7040", "7041", "7045", "7046", "7049", "7051", "7052", "7053", "7054", "7055", "7056", "7057", "7058", "7062", "7065", "7066", "7067", "7068", "7070", "7073", "7074", "7076", "7083", "7087", "7089", "7090", "7091", "7092", "7094", "7095", "7097", "7100", "7102", "7103", "7105", "7108", "7109", "7111", "7112", "7114", "7117", "7118", "7120", "7121", "7122", "7124", "7125", "7126", "7127", "7128", "7129", "7130", "7131", "7132", "7133", "7134", "7136", "7138", "7143", "7144", "7148", "7149", "7150", "7151", "7153", "7154", "7155", "7157", "7160", "7163", "7164", "7166", "7167", "7168", "7169", "7170", "7172", "7173", "7174", "7175", "7177", "7178", "7181", "7182", "7184", "7191", "7196", "7197", "7199", "7200", "7202", "7203", "7205", "7207", "7208", "7212", "7213", "7214", "7215", "7217", "7219", "7222", "7224", "7225", "7228", "7231", "7234", "7237", "7238", "7239", "7241", "7243", "7244", "7245", "7248", "7249", "7250", "7251", "7252", "7254", "7261", "7262", "7263", "7265", "7266", "7267", "7268", "7270", "7271", "7273", "7275", "7278", "7280", "7285", "7286", "7291", "7292", "7294", "7296", "7298", "7300", "7302", "7307", "7308", "7309", "7314", "7317", "7318", "7319", "7322", "7323", "7325", "7326", "7327", "7331", "7336", "7337", "7338", "7339", "7341", "7342", "7344", "7347", "7350", "7351", "7353", "7357", "7361", "7363", "7364", "7366", "7368", "7370", "7371", "7372", "7374", "7375", "7376", "7378", "7379", "7381", "7382", "7383", "7385", "7387", "7389", "7393", "7394", "7395", "7396", "7397", "7399", "7401", "7405", "7410", "7414", "7419", "7421", "7423", "7426", "7427", "7432", "7435", "7436", "7437", "7439", "7442", "7443", "7445", "7446", "7447", "7449", "7450", "7453", "7454", "7455", "7456", "7457", "7466", "7469", "7470", "7475", "7477", "7479", "7480", "7482", "7483", "7488", "7489", "7493", "7494", "7495", "7496", "7499", "7501", "7506", "7508", "7509", "7511", "7514", "7515", "7520", "7523", "7525", "7527", "7529", "7533", "7534", "7535", "7536", "7537", "7541", "7542", "7544", "7545", "7547", "7548", "7549", "7555", "7558", "7559", "7560", "7561", "7567", "7569", "7575", "7576", "7578", "7579", "7580", "7581", "7584", "7587", "7591", "7594", "7596", "7598", "7599", "7601", "7602", "7603", "7606", "7608", "7609", "7610", "7613", "7615", "7616", "7618", "7619", "7621", "7625", "7627", "7630", "7632", "7635", "7640", "7644", "7645", "7649", "7650", "7651", "7656", "7657", "7659", "7660", "7663", "7665", "7669", "7670", "7672", "7675", "7676", "7678", "7680", "7681", "7683", "7688", "7696", "7697", "7698", "7700", "7703", "7704", "7705", "7706", "7708", "7709", "7710", "7711", "7715", "7716", "7717", "7721", "7722", "7724", "7731", "7733", "7734", "7735", "7737", "7738", "7739", "7740", "7742", "7743", "7745", "7746", "7747", "7748", "7752", "7755", "7757", "7758", "7760", "7762", "7765", "7766", "7768", "7769", "7771", "7773", "7775", "7777", "7778", "7779", "7780", "7781", "7782", "7788", "7790", "7792", "7793", "7794", "7796", "7797", "7798", "7799", "7800", "7801", "7803", "7804", "7806", "7808", "7809", "7815", "7816", "7819", "7825", "7827", "7828", "7830", "7831", "7832", "7833", "7835", "7836", "7839", "7843", "7847", "7848", "7849", "7855", "7858", "7861", "7866", "7869", "7870", "7873", "7874", "7875", "7877", "7878", "7879", "7884", "7885", "7886", "7888", "7891", "7892", "7894", "7895", "7897", "7899", "7900", "7901", "7905", "7908", "7910", "7914", "7915", "7919", "7922", "7923", "7926", "7927", "7932", "7934", "7935", "7936", "7938", "7939", "7941", "7943", "7946", "7947", "7948", "7949", "7950", "7953", "7955", "7956", "7957", "7959", "7961", "7962", "7964", "7965", "7966", "7967", "7968", "7971", "7972", "7975", "7976", "7977", "7979", "7980", "7981", "7982", "7988", "7991", "7993", "7994", "7995", "7996", "7998", "7999", "8000", "8003", "8005", "8006", "8007", "8014", "8015", "8021", "8024", "8025", "8026", "8030", "8031", "8033", "8039", "8042", "8044", "8045", "8051", "8053", "8054", "8055", "8056", "8058", "8059", "8060", "8065", "8068", "8070", "8071", "8074", "8075", "8081", "8083", "8084", "8086", "8087", "8090", "8094", "8095", "8096", "8097", "8098", "8102", "8103", "8104", "8106", "8108", "8109", "8110", "8111", "8112", "8113", "8114", "8115", "8117", "8118", "8119", "8122", "8124", "8125", "8127", "8128", "8130", "8131", "8133", "8134", "8135", "8139", "8140", "8143", "8146", "8147", "8148", "8149", "8150", "8155", "8157", "8160", "8161", "8162", "8163", "8164", "8165", "8166", "8169", "8173", "8174", "8176", "8177", "8178", "8183", "8189", "8191", "8196", "8198", "8202", "8203", "8210", "8211", "8216", "8217", "8218", "8219", "8220", "8221", "8222", "8223", "8225", "8227", "8229", "8231", "8233", "8234", "8236", "8237", "8238", "8242", "8244", "8245", "8248", "8250", "8252", "8255", "8256", "8257", "8258", "8259", "8261", "8263", "8264", "8265", "8266", "8270", "8272", "8273", "8277", "8278", "8279", "8282", "8284", "8285", "8288", "8289", "8290", "8292", "8294", "8298", "8299", "8300", "8301", "8303", "8306", "8307", "8311", "8313", "8315", "8318", "8321", "8325", "8326", "8328", "8333", "8336", "8337", "8339", "8340", "8344", "8346", "8347", "8348", "8349", "8355", "8356", "8357", "8358", "8359", "8364", "8365", "8368", "8370", "8371", "8373", "8374", "8378", "8379", "8380", "8381", "8384", "8389", "8390", "8391", "8393", "8395", "8399", "8402", "8403", "8404", "8406", "8407", "8408", "8409", "8411", "8412", "8413", "8417", "8418", "8420", "8421", "8422", "8423", "8425", "8429", "8433", "8439", "8440", "8443", "8446", "8447", "8448", "8451", "8453", "8454", "8455", "8458", "8462", "8463", "8464", "8469", "8472", "8473", "8474", "8475", "8476", "8477", "8478", "8480", "8481", "8488", "8491", "8494", "8496", "8499", "8501", "8505", "8508", "8510", "8512", "8515", "8516", "8517", "8518", "8520", "8521", "8523", "8524", "8527", "8528", "8530", "8532", "8533", "8535", "8538", "8539", "8541", "8542", "8543", "8549", "8551", "8553", "8555", "8557", "8558", "8559", "8560", "8561", "8562", "8563", "8565", "8566", "8567", "8568", "8569", "8570", "8571", "8573", "8574", "8576", "8580", "8582", "8584", "8586", "8587", "8588", "8589", "8590", "8591", "8596", "8597", "8598", "8599", "8601", "8602", "8603", "8606", "8610", "8611", "8615", "8616", "8618", "8620", "8621", "8622", "8624", "8626", "8627", "8628", "8630", "8632", "8634", "8636", "8639", "8640", "8643", "8644", "8645", "8646", "8650", "8651", "8653", "8658", "8662", "8663", "8667", "8669", "8670", "8671", "8676", "8678", "8679", "8680", "8681", "8685", "8690", "8692", "8693", "8694", "8695", "8696", "8698", "8700", "8703", "8706", "8711", "8714", "8716", "8717", "8718", "8720", "8721", "8722", "8723", "8724", "8725", "8727", "8728", "8729", "8732", "8733", "8735", "8738", "8739", "8740", "8741", "8742", "8744", "8746", "8747", "8748", "8749", "8751", "8752", "8753", "8754", "8756", "8760", "8761", "8762", "8763", "8765", "8768", "8772", "8775", "8776", "8781", "8782", "8783", "8789", "8790", "8791", "8792", "8793", "8796", "8798", "8800", "8801", "8802", "8803", "8805", "8807", "8810", "8812", "8815", "8816", "8820", "8823", "8825", "8826", "8827", "8831", "8832", "8837", "8838", "8840", "8843", "8844", "8851", "8853", "8857", "8858", "8860", "8863", "8865", "8867", "8868", "8869", "8870", "8871", "8872", "8874", "8878", "8880", "8881", "8883", "8884", "8885", "8887", "8888", "8892", "8893", "8895", "8896", "8899", "8900", "8901", "8905", "8906", "8907", "8909", "8910", "8911", "8912", "8914", "8916", "8919", "8921", "8924", "8925", "8926", "8932", "8933", "8935", "8936", "8937", "8939", "8940", "8941", "8942", "8943", "8946", "8949", "8950", "8953", "8956", "8960", "8962", "8966", "8968", "8970", "8975", "8977", "8979", "8980", "8983", "8984", "8987", "8988", "8992", "8993", "8995", "8996", "8997", "8998", "8999", "9000", "9001", "9004", "9005", "9007", "9008", "9011", "9013", "9014", "9016", "9018", "9025", "9029", "9030", "9031", "9033", "9034", "9035", "9036", "9037", "9041", "9042", "9044", "9045", "9046", "9048", "9049", "9050", "9054", "9055", "9058", "9059", "9062", "9063", "9065", "9067", "9070", "9071", "9072", "9073", "9080", "9081", "9082", "9086", "9087", "9088", "9089", "9090", "9091", "9092", "9098", "9099", "9100", "9101", "9106", "9108", "9111", "9112", "9114", "9117", "9121", "9124", "9129", "9131", "9132", "9135", "9136", "9137", "9138", "9141", "9143", "9144", "9146", "9149", "9150", "9151", "9154", "9155", "9157", "9161", "9162", "9164", "9165", "9166", "9167", "9170", "9172", "9173", "9175", "9176", "9178", "9179", "9180", "9181", "9185", "9189", "9190", "9191", "9196", "9199", "9201", "9204", "9205", "9209", "9212", "9214", "9217", "9220", "9221", "9223", "9224", "9227", "9228", "9229", "9230", "9232", "9239", "9241", "9242", "9244", "9247", "9248", "9251", "9254", "9256", "9260", "9262", "9263", "9264", "9265", "9266", "9267", "9268", "9269", "9272", "9273", "9274", "9278", "9279", "9281", "9282", "9283", "9284", "9285", "9287", "9288", "9290", "9292", "9294", "9295", "9300", "9301", "9303", "9304", "9306", "9310", "9314", "9315", "9316", "9318", "9320", "9321", "9325", "9327", "9328", "9334", "9336", "9337", "9339", "9343", "9344", "9345", "9348", "9350", "9353", "9354", "9356", "9358", "9360", "9363", "9368", "9372", "9373", "9376", "9377", "9378", "9380", "9382", "9384", "9385", "9387", "9389", "9391", "9392", "9396", "9397", "9399", "9400", "9401", "9405", "9409", "9410", "9412", "9416", "9418", "9419", "9421", "9423", "9425", "9426", "9427", "9429", "9431", "9432", "9436", "9438", "9439", "9440", "9441", "9442", "9444", "9445", "9446", "9449", "9451", "9454", "9455", "9458", "9462", "9464", "9465", "9468", "9476", "9478", "9480", "9481", "9483", "9484", "9485", "9486", "9487", "9489", "9490", "9492", "9493", "9495", "9496", "9497", "9502", "9503", "9504", "9506", "9508", "9510", "9512", "9513", "9515", "9519", "9523", "9524", "9527", "9528", "9529", "9530", "9531", "9534", "9536", "9538", "9541", "9542", "9546", "9550", "9553", "9558", "9562", "9564", "9568", "9569", "9570", "9572", "9573", "9575", "9577", "9584", "9587", "9588", "9591", "9593", "9600", "9604", "9605", "9606", "9607", "9609", "9611", "9613", "9615", "9619", "9621", "9622", "9625", "9626", "9627", "9629", "9631", "9633", "9634", "9635", "9636", "9639", "9641", "9642", "9643", "9644", "9649", "9650", "9651", "9653", "9654", "9656", "9661", "9664", "9665", "9666", "9669", "9670", "9671", "9672", "9673", "9674", "9675", "9676", "9679", "9680", "9684", "9686", "9687", "9690", "9692", "9694", "9697", "9700", "9702", "9703", "9704", "9705", "9706", "9711", "9712", "9714", "9715", "9717", "9718", "9719", "9720", "9722", "9723", "9728", "9729", "9730", "9731", "9732", "9734", "9735", "9737", "9740", "9741", "9742", "9745", "9746", "9748", "9749", "9751", "9753", "9755", "9756", "9757", "9759", "9762", "9764", "9768", "9769", "9771", "9773", "9774", "9778", "9779", "9781", "9784", "9785", "9788", "9789", "9791", "9792", "9794", "9795", "9797", "9798", "9804", "9805", "9807", "9810", "9811", "9812", "9818", "9824", "9825", "9829", "9832", "9833", "9835", "9836", "9838", "9840", "9841", "9842", "9844", "9845", "9846", "9847", "9848", "9849", "9851", "9852", "9853", "9854", "9857", "9858", "9859", "9861", "9864", "9866", "9872", "9873", "9874", "9875", "9878", "9879", "9880", "9881", "9882", "9885", "9886", "9888", "9889", "9891", "9894", "9896", "9897", "9899", "9900", "9901", "9902", "9903", "9906", "9908", "9909", "9911", "9912", "9914", "9916", "9918", "9919", "9920", "9921", "9923", "9933", "9934", "9936", "9938", "9940", "9944", "9948", "9951", "9956", "9957", "9958", "9960", "9961", "9963", "9966", "9967", "9972", "9973", "9976", "9977", "9981", "9982", "9983", "9988", "9990", "9991", "9993", "9994", "9995", "9998"]]
+}
\ No newline at end of file
diff --git a/AutoDL-Projects/configs/nas-benchmark/hyper-opts/01E.config b/AutoDL-Projects/configs/nas-benchmark/hyper-opts/01E.config
new file mode 100644
index 0000000..24a7fcd
--- /dev/null
+++ b/AutoDL-Projects/configs/nas-benchmark/hyper-opts/01E.config
@@ -0,0 +1,13 @@
+{
+ "scheduler": ["str", "cos"],
+ "eta_min" : ["float", "0.0"],
+ "epochs" : ["int", "1"],
+ "warmup" : ["int", "0"],
+ "optim" : ["str", "SGD"],
+ "LR" : ["float", "0.1"],
+ "decay" : ["float", "0.0005"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "1"],
+ "criterion": ["str", "Softmax"],
+ "batch_size": ["int", "256"]
+}
diff --git a/AutoDL-Projects/configs/nas-benchmark/hyper-opts/12E.config b/AutoDL-Projects/configs/nas-benchmark/hyper-opts/12E.config
new file mode 100644
index 0000000..7733e07
--- /dev/null
+++ b/AutoDL-Projects/configs/nas-benchmark/hyper-opts/12E.config
@@ -0,0 +1,13 @@
+{
+ "scheduler": ["str", "cos"],
+ "eta_min" : ["float", "0.0"],
+ "epochs" : ["int", "12"],
+ "warmup" : ["int", "0"],
+ "optim" : ["str", "SGD"],
+ "LR" : ["float", "0.1"],
+ "decay" : ["float", "0.0005"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "1"],
+ "criterion": ["str", "Softmax"],
+ "batch_size": ["int", "256"]
+}
\ No newline at end of file
diff --git a/AutoDL-Projects/configs/nas-benchmark/hyper-opts/200E.config b/AutoDL-Projects/configs/nas-benchmark/hyper-opts/200E.config
new file mode 100644
index 0000000..b681784
--- /dev/null
+++ b/AutoDL-Projects/configs/nas-benchmark/hyper-opts/200E.config
@@ -0,0 +1,13 @@
+{
+ "scheduler": ["str", "cos"],
+ "eta_min" : ["float", "0.0"],
+ "epochs" : ["int", "200"],
+ "warmup" : ["int", "0"],
+ "optim" : ["str", "SGD"],
+ "LR" : ["float", "0.1"],
+ "decay" : ["float", "0.0005"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "1"],
+ "criterion": ["str", "Softmax"],
+ "batch_size": ["int", "256"]
+}
diff --git a/AutoDL-Projects/configs/nas-benchmark/hyper-opts/90E.config b/AutoDL-Projects/configs/nas-benchmark/hyper-opts/90E.config
new file mode 100644
index 0000000..499af38
--- /dev/null
+++ b/AutoDL-Projects/configs/nas-benchmark/hyper-opts/90E.config
@@ -0,0 +1,13 @@
+{
+ "scheduler": ["str", "cos"],
+ "eta_min" : ["float", "0.0"],
+ "epochs" : ["int", "90"],
+ "warmup" : ["int", "0"],
+ "optim" : ["str", "SGD"],
+ "LR" : ["float", "0.1"],
+ "decay" : ["float", "0.0005"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "1"],
+ "criterion": ["str", "Softmax"],
+ "batch_size": ["int", "256"]
+}
diff --git a/AutoDL-Projects/configs/nas-benchmark/imagenet-16-120-test-split.txt b/AutoDL-Projects/configs/nas-benchmark/imagenet-16-120-test-split.txt
new file mode 100644
index 0000000..44e9d24
--- /dev/null
+++ b/AutoDL-Projects/configs/nas-benchmark/imagenet-16-120-test-split.txt
@@ -0,0 +1,4 @@
+{
+ "xvalid" : ["int" , ["1", "2", "3", "6", "7", "8", "9", "12", "16", "18", "19", "26", "27", "28", "29", "32", "34", "35", "36", "37", "38", "40", "41", "43", "45", "46", "48", "50", "51", "53", "54", "56", "62", "66", "67", "68", "71", "72", "74", "75", "76", "77", "78", "79", "80", "82", "85", "86", "89", "90", "91", "92", "94", "96", "97", "98", "99", "100", "101", "103", "106", "111", "112", "114", "116", "117", "118", "120", "121", "124", "129", "130", "131", "133", "135", "137", "138", "140", "142", "143", "145", "146", "147", "148", "150", "154", "161", "162", "163", "164", "165", "168", "169", "170", "171", "173", "174", "176", "177", "178", "179", "182", "183", "184", "185", "186", "188", "189", "192", "193", "194", "198", "202", "203", "204", "210", "211", "216", "221", "226", "229", "231", "234", "237", "249", "250", "251", "252", "253", "254", "258", "259", "262", "263", "264", "266", "267", "268", "269", "273", "274", "275", "276", "279", "280", "281", "286", "289", "290", "294", "295", "297", "299", "301", "302", "303", "304", "305", "306", "307", "310", "312", "316", "318", "320", "323", "324", "328", "329", "331", "332", "334", "337", "338", "339", "340", "344", "346", "350", "351", "352", "353", "355", "356", "359", "360", "362", "365", "366", "367", "369", "370", "372", "375", "376", "385", "387", "389", "390", "391", "393", "396", "397", "398", "400", "401", "402", "403", "405", "407", "410", "413", "415", "416", "423", "427", "429", "431", "437", "438", "439", "440", "442", "444", "447", "448", "451", "456", "458", "462", "464", "465", "466", "467", "468", "469", "471", "479", "481", "490", "491", "496", "497", "498", "500", "501", "503", "504", "505", "507", "508", "510", "513", "514", "515", "516", "517", "519", "521", "522", "523", "526", "527", "529", "530", "533", "536", "538", "539", "544", "550", "551", "553", "555", "556", "560", "562", "564", "566", "567", "568", "570", "575", "576", "579", "583", "585", "587", "593", "595", "597", "602", "603", "604", "605", "607", "610", "615", "616", "618", "619", "620", "622", "623", "625", "631", "632", "634", "635", "636", "637", "638", "640", "643", "650", "652", "655", "656", "657", "658", "660", "661", "662", "667", "668", "672", "674", "676", "677", "679", "685", "686", "688", "689", "690", "691", "692", "694", "695", "696", "698", "699", "700", "708", "710", "712", "713", "716", "717", "720", "721", "722", "723", "724", "727", "728", "729", "731", "733", "734", "735", "738", "739", "740", "744", "746", "748", "752", "754", "756", "758", "759", "760", "763", "766", "767", "768", "770", "772", "775", "779", "781", "783", "784", "785", "786", "790", "791", "793", "794", "798", "800", "807", "811", "814", "815", "817", "821", "823", "824", "826", "828", "829", "830", "831", "833", "841", "843", "845", "847", "848", "850", "851", "852", "856", "858", "863", "864", "866", "868", "870", "871", "873", "876", "877", "879", "880", "882", "883", "884", "887", "891", "892", "893", "894", "897", "899", "901", "904", "905", "906", "907", "908", "910", "914", "917", "921", "922", "925", "926", "928", "930", "933", "934", "935", "937", "938", "939", "941", "942", "944", "945", "946", "948", "949", "951", "952", "954", "956", "957", "959", "963", "965", "966", "967", "968", "970", "971", "972", "976", "979", "980", "981", "983", "984", "986", "988", "991", "996", "997", "998", "1000", "1004", "1008", "1016", "1017", "1020", "1024", "1025", "1026", "1027", "1028", "1029", "1030", "1032", "1034", "1037", "1039", "1040", "1043", "1044", "1045", "1047", "1048", "1049", "1052", "1055", "1056", "1062", "1063", "1069", "1070", "1071", "1075", "1076", "1079", "1080", "1083", "1085", "1088", "1089", "1095", "1097", "1098", "1099", "1101", "1104", "1106", "1107", "1108", "1109", "1112", "1115", "1118", "1121", "1122", "1126", "1134", "1136", "1139", "1140", "1143", "1145", "1148", "1150", "1151", "1158", "1160", "1163", "1164", "1169", "1173", "1174", "1176", "1177", "1178", "1179", "1181", "1182", "1183", "1185", "1186", "1189", "1191", "1193", "1194", "1197", "1198", "1204", "1211", "1216", "1217", "1218", "1219", "1224", "1226", "1227", "1228", "1230", "1234", "1235", "1241", "1242", "1243", "1246", "1249", "1250", "1251", "1253", "1256", "1257", "1258", "1259", "1260", "1262", "1263", "1265", "1266", "1267", "1268", "1272", "1273", "1276", "1277", "1280", "1285", "1287", "1288", "1289", "1290", "1298", "1300", "1301", "1303", "1305", "1308", "1310", "1311", "1312", "1314", "1316", "1317", "1320", "1324", "1325", "1327", "1328", "1331", "1334", "1338", "1341", "1343", "1344", "1347", "1348", "1351", "1356", "1357", "1361", "1362", "1363", "1364", "1366", "1368", "1371", "1373", "1377", "1379", "1380", "1381", "1382", "1383", "1385", "1386", "1387", "1389", "1392", "1394", "1395", "1396", "1397", "1401", "1403", "1404", "1405", "1406", "1407", "1408", "1409", "1410", "1413", "1416", "1419", "1420", "1421", "1422", "1423", "1428", "1430", "1432", "1433", "1436", "1440", "1442", "1446", "1451", "1453", "1456", "1457", "1458", "1460", "1464", "1465", "1468", "1469", "1473", "1476", "1477", "1484", "1485", "1490", "1497", "1498", "1501", "1504", "1505", "1506", "1507", "1509", "1511", "1516", "1517", "1518", "1519", "1520", "1523", "1526", "1528", "1532", "1533", "1536", "1537", "1542", "1543", "1547", "1548", "1552", "1553", "1554", "1556", "1557", "1558", "1559", "1560", "1561", "1562", "1563", "1564", "1565", "1568", "1570", "1571", "1573", "1574", "1576", "1578", "1579", "1582", "1584", "1585", "1586", "1588", "1589", "1590", "1593", "1595", "1596", "1598", "1600", "1602", "1604", "1606", "1607", "1608", "1610", "1613", "1616", "1617", "1618", "1619", "1620", "1621", "1626", "1627", "1628", "1630", "1631", "1635", "1636", "1638", "1640", "1641", "1643", "1647", "1648", "1650", "1654", "1657", "1658", "1661", "1664", "1666", "1667", "1668", "1669", "1670", "1671", "1673", "1676", "1680", "1681", "1682", "1683", "1685", "1687", "1688", "1689", "1691", "1692", "1693", "1695", "1696", "1698", "1700", "1701", "1703", "1704", "1705", "1707", "1710", "1712", "1714", "1716", "1717", "1718", "1719", "1720", "1721", "1723", "1724", "1727", "1728", "1731", "1733", "1734", "1735", "1736", "1737", "1738", "1740", "1742", "1747", "1748", "1749", "1751", "1752", "1753", "1754", "1755", "1756", "1758", "1760", "1764", "1769", "1771", "1772", "1773", "1774", "1776", "1777", "1781", "1782", "1784", "1785", "1789", "1790", "1794", "1795", "1796", "1800", "1802", "1803", "1805", "1807", "1808", "1809", "1813", "1817", "1818", "1820", "1827", "1828", "1829", "1830", "1835", "1836", "1838", "1844", "1845", "1846", "1847", "1850", "1851", "1853", "1857", "1858", "1859", "1862", "1863", "1865", "1866", "1868", "1869", "1872", "1874", "1875", "1876", "1877", "1880", "1886", "1887", "1892", "1898", "1901", "1902", "1903", "1904", "1906", "1907", "1909", "1911", "1914", "1917", "1921", "1923", "1924", "1925", "1926", "1927", "1928", "1929", "1934", "1935", "1937", "1941", "1942", "1947", "1948", "1950", "1953", "1954", "1955", "1956", "1959", "1960", "1962", "1963", "1965", "1966", "1970", "1971", "1972", "1974", "1975", "1976", "1977", "1981", "1982", "1983", "1986", "1987", "1992", "1993", "1994", "2002", "2004", "2005", "2011", "2012", "2013", "2015", "2021", "2022", "2023", "2026", "2030", "2031", "2032", "2033", "2034", "2035", "2036", "2038", "2039", "2040", "2041", "2042", "2043", "2044", "2046", "2048", "2049", "2051", "2052", "2055", "2059", "2060", "2066", "2067", "2070", "2071", "2074", "2075", "2077", "2079", "2082", "2084", "2086", "2089", "2091", "2092", "2093", "2097", "2098", "2100", "2101", "2103", "2104", "2109", "2111", "2114", "2115", "2116", "2118", "2119", "2123", "2125", "2126", "2127", "2136", "2137", "2138", "2142", "2143", "2145", "2146", "2147", "2153", "2154", "2164", "2165", "2166", "2170", "2171", "2172", "2176", "2177", "2179", "2183", "2184", "2185", "2186", "2187", "2189", "2190", "2191", "2194", "2196", "2200", "2201", "2205", "2212", "2213", "2214", "2215", "2217", "2219", "2221", "2223", "2224", "2229", "2230", "2232", "2234", "2238", "2239", "2240", "2241", "2242", "2243", "2245", "2247", "2248", "2249", "2250", "2252", "2253", "2257", "2258", "2261", "2262", "2263", "2265", "2269", "2271", "2272", "2275", "2278", "2280", "2284", "2285", "2286", "2289", "2293", "2298", "2299", "2300", "2301", "2304", "2305", "2306", "2307", "2311", "2313", "2318", "2322", "2323", "2324", "2329", "2330", "2331", "2332", "2334", "2336", "2338", "2339", "2340", "2341", "2342", "2348", "2355", "2357", "2358", "2359", "2361", "2362", "2363", "2364", "2365", "2370", "2371", "2373", "2377", "2378", "2383", "2385", "2388", "2389", "2392", "2393", "2394", "2395", "2399", "2400", "2401", "2402", "2403", "2404", "2405", "2407", "2408", "2409", "2411", "2412", "2413", "2415", "2417", "2419", "2422", "2423", "2424", "2425", "2426", "2427", "2428", "2430", "2431", "2432", "2436", "2437", "2438", "2439", "2441", "2447", "2449", "2452", "2453", "2455", "2456", "2458", "2459", "2462", "2463", "2464", "2471", "2472", "2473", "2475", "2479", "2481", "2487", "2488", "2492", "2494", "2496", "2502", "2504", "2510", "2511", "2515", "2516", "2517", "2519", "2520", "2521", "2522", "2523", "2524", "2526", "2527", "2528", "2531", "2532", "2533", "2535", "2540", "2542", "2544", "2548", "2551", "2553", "2554", "2555", "2558", "2561", "2564", "2569", "2571", "2573", "2574", "2576", "2577", "2578", "2583", "2588", "2589", "2591", "2593", "2596", "2597", "2598", "2600", "2604", "2605", "2608", "2609", "2613", "2614", "2615", "2618", "2621", "2623", "2625", "2627", "2629", "2631", "2636", "2638", "2639", "2642", "2645", "2646", "2647", "2651", "2655", "2661", "2662", "2664", "2665", "2666", "2667", "2670", "2673", "2674", "2675", "2682", "2683", "2690", "2691", "2692", "2694", "2699", "2700", "2703", "2705", "2708", "2710", "2711", "2713", "2716", "2717", "2718", "2719", "2720", "2726", "2729", "2731", "2732", "2733", "2734", "2736", "2739", "2740", "2742", "2743", "2744", "2745", "2747", "2748", "2750", "2751", "2752", "2755", "2756", "2757", "2758", "2759", "2760", "2761", "2764", "2765", "2766", "2768", "2770", "2773", "2777", "2778", "2781", "2782", "2783", "2784", "2787", "2788", "2789", "2791", "2792", "2793", "2794", "2795", "2796", "2797", "2799", "2801", "2802", "2804", "2805", "2806", "2807", "2809", "2810", "2812", "2813", "2815", "2816", "2817", "2818", "2820", "2822", "2825", "2827", "2829", "2830", "2831", "2838", "2839", "2841", "2842", "2848", "2851", "2854", "2856", "2858", "2859", "2860", "2861", "2862", "2864", "2866", "2867", "2868", "2869", "2870", "2874", "2877", "2878", "2881", "2882", "2883", "2884", "2885", "2886", "2887", "2889", "2892", "2893", "2894", "2898", "2899", "2900", "2904", "2905", "2906", "2908", "2910", "2911", "2912", "2913", "2918", "2922", "2923", "2924", "2925", "2927", "2930", "2931", "2932", "2933", "2938", "2939", "2940", "2941", "2943", "2944", "2945", "2946", "2949", "2950", "2951", "2952", "2954", "2955", "2956", "2957", "2958", "2959", "2960", "2962", "2963", "2964", "2966", "2967", "2970", "2975", "2976", "2984", "2985", "2986", "2987", "2988", "2989", "2992", "2993", "2994", "2996", "2997", "2998", "3001", "3002", "3003", "3005", "3008", "3011", "3012", "3013", "3014", "3016", "3021", "3022", "3023", "3024", "3027", "3029", "3030", "3031", "3033", "3035", "3036", "3037", "3039", "3040", "3041", "3042", "3047", "3049", "3050", "3054", "3056", "3058", "3059", "3063", "3064", "3066", "3068", "3069", "3071", "3072", "3074", "3075", "3076", "3077", "3078", "3079", "3081", "3082", "3086", "3087", "3088", "3093", "3094", "3096", "3101", "3103", "3104", "3107", "3108", "3116", "3117", "3118", "3122", "3127", "3129", "3135", "3137", "3141", "3142", "3148", "3149", "3151", "3154", "3156", "3157", "3158", "3159", "3163", "3166", "3169", "3171", "3172", "3173", "3175", "3176", "3180", "3182", "3186", "3188", "3189", "3191", "3193", "3194", "3199", "3201", "3206", "3207", "3208", "3210", "3211", "3213", "3216", "3219", "3220", "3222", "3223", "3226", "3227", "3229", "3230", "3232", "3233", "3235", "3239", "3240", "3241", "3242", "3243", "3244", "3246", "3247", "3248", "3249", "3250", "3252", "3253", "3255", "3263", "3264", "3266", "3268", "3269", "3270", "3272", "3273", "3274", "3275", "3276", "3277", "3278", "3279", "3283", "3284", "3285", "3286", "3291", "3294", "3295", "3296", "3300", "3301", "3303", "3305", "3308", "3309", "3311", "3313", "3314", "3316", "3317", "3318", "3320", "3321", "3322", "3323", "3325", "3326", "3327", "3328", "3329", "3332", "3333", "3335", "3337", "3338", "3341", "3343", "3349", "3350", "3353", "3355", "3356", "3359", "3361", "3362", "3364", "3365", "3367", "3369", "3370", "3373", "3376", "3378", "3380", "3382", "3383", "3385", "3386", "3387", "3389", "3392", "3396", "3397", "3399", "3400", "3405", "3406", "3407", "3408", "3412", "3415", "3418", "3423", "3424", "3427", "3428", "3429", "3431", "3435", "3438", "3441", "3442", "3443", "3444", "3446", "3447", "3448", "3450", "3451", "3454", "3455", "3457", "3458", "3459", "3461", "3463", "3465", "3466", "3467", "3468", "3469", "3470", "3472", "3473", "3476", "3479", "3481", "3483", "3486", "3489", "3493", "3494", "3495", "3496", "3497", "3498", "3502", "3503", "3505", "3506", "3507", "3509", "3510", "3513", "3514", "3516", "3518", "3522", "3525", "3526", "3528", "3530", "3531", "3533", "3536", "3537", "3539", "3540", "3546", "3550", "3551", "3554", "3555", "3556", "3567", "3569", "3570", "3571", "3572", "3574", "3580", "3581", "3582", "3585", "3587", "3588", "3591", "3595", "3596", "3598", "3599", "3604", "3606", "3608", "3609", "3612", "3613", "3615", "3616", "3618", "3619", "3622", "3623", "3624", "3626", "3629", "3636", "3640", "3641", "3643", "3644", "3647", "3649", "3651", "3652", "3653", "3657", "3658", "3660", "3663", "3664", "3667", "3673", "3676", "3677", "3678", "3680", "3682", "3683", "3685", "3686", "3687", "3688", "3690", "3692", "3694", "3695", "3696", "3698", "3699", "3701", "3703", "3706", "3708", "3709", "3710", "3711", "3713", "3716", "3717", "3718", "3719", "3723", "3726", "3728", "3729", "3730", "3731", "3735", "3736", "3738", "3739", "3742", "3743", "3745", "3746", "3748", "3749", "3750", "3753", "3755", "3758", "3759", "3760", "3761", "3762", "3763", "3765", "3766", "3773", "3774", "3776", "3778", "3779", "3780", "3781", "3783", "3784", "3787", "3788", "3789", "3790", "3791", "3792", "3797", "3799", "3800", "3804", "3806", "3808", "3809", "3810", "3812", "3819", "3820", "3822", "3824", "3825", "3827", "3828", "3829", "3830", "3831", "3832", "3835", "3836", "3837", "3839", "3840", "3841", "3843", "3844", "3851", "3852", "3853", "3854", "3855", "3859", "3862", "3863", "3864", "3865", "3867", "3870", "3871", "3872", "3874", "3875", "3877", "3879", "3880", "3883", "3886", "3887", "3891", "3892", "3893", "3896", "3899", "3901", "3903", "3906", "3908", "3909", "3910", "3912", "3913", "3917", "3918", "3919", "3920", "3922", "3923", "3925", "3927", "3928", "3929", "3932", "3933", "3936", "3937", "3938", "3939", "3941", "3942", "3943", "3944", "3945", "3949", "3950", "3951", "3952", "3956", "3957", "3958", "3959", "3960", "3964", "3965", "3971", "3973", "3974", "3978", "3980", "3981", "3983", "3987", "3988", "3991", "3992", "3995", "3996", "3997", "4000", "4001", "4003", "4004", "4005", "4009", "4012", "4017", "4019", "4020", "4027", "4029", "4032", "4033", "4037", "4039", "4041", "4042", "4044", "4045", "4046", "4048", "4050", "4052", "4055", "4057", "4058", "4059", "4061", "4062", "4063", "4065", "4067", "4069", "4072", "4073", "4074", "4075", "4076", "4078", "4079", "4081", "4083", "4085", "4087", "4090", "4093", "4094", "4096", "4097", "4100", "4103", "4104", "4109", "4110", "4116", "4117", "4118", "4119", "4123", "4125", "4127", "4129", "4130", "4131", "4134", "4136", "4139", "4146", "4148", "4151", "4152", "4153", "4154", "4155", "4156", "4158", "4162", "4163", "4164", "4165", "4167", "4172", "4179", "4181", "4182", "4184", "4185", "4186", "4187", "4190", "4194", "4196", "4198", "4199", "4202", "4203", "4205", "4207", "4209", "4211", "4213", "4215", "4216", "4217", "4218", "4223", "4226", "4228", "4229", "4230", "4233", "4235", "4236", "4239", "4240", "4241", "4242", "4243", "4246", "4248", "4249", "4250", "4252", "4255", "4256", "4259", "4260", "4263", "4264", "4265", "4266", "4268", "4271", "4273", "4276", "4277", "4278", "4280", "4281", "4284", "4290", "4291", "4292", "4294", "4295", "4296", "4297", "4298", "4299", "4300", "4301", "4304", "4305", "4307", "4308", "4309", "4310", "4311", "4312", "4313", "4314", "4316", "4318", "4319", "4320", "4321", "4322", "4324", "4325", "4326", "4327", "4328", "4331", "4332", "4342", "4343", "4344", "4345", "4347", "4349", "4353", "4354", "4355", "4358", "4359", "4361", "4362", "4365", "4367", "4370", "4374", "4376", "4380", "4381", "4382", "4385", "4386", "4387", "4389", "4395", "4396", "4398", "4401", "4403", "4404", "4405", "4408", "4409", "4411", "4414", "4415", "4418", "4422", "4424", "4425", "4427", "4428", "4429", "4430", "4439", "4441", "4450", "4455", "4460", "4464", "4467", "4473", "4475", "4480", "4481", "4484", "4485", "4486", "4488", "4489", "4490", "4493", "4495", "4496", "4497", "4499", "4502", "4504", "4508", "4512", "4516", "4517", "4520", "4524", "4525", "4526", "4527", "4528", "4529", "4530", "4531", "4532", "4533", "4534", "4535", "4537", "4541", "4542", "4546", "4548", "4549", "4552", "4554", "4555", "4557", "4558", "4560", "4564", "4566", "4569", "4570", "4576", "4581", "4582", "4583", "4584", "4585", "4586", "4588", "4589", "4590", "4594", "4597", "4599", "4600", "4602", "4605", "4608", "4610", "4611", "4615", "4617", "4619", "4620", "4621", "4623", "4625", "4626", "4627", "4628", "4629", "4630", "4633", "4634", "4635", "4636", "4638", "4639", "4640", "4641", "4642", "4644", "4646", "4648", "4652", "4653", "4655", "4656", "4659", "4660", "4661", "4663", "4664", "4665", "4669", "4671", "4673", "4677", "4678", "4681", "4682", "4683", "4688", "4691", "4692", "4694", "4695", "4696", "4698", "4699", "4702", "4707", "4712", "4713", "4714", "4716", "4717", "4721", "4722", "4723", "4725", "4726", "4727", "4729", "4730", "4731", "4733", "4734", "4735", "4739", "4740", "4742", "4745", "4747", "4750", "4752", "4753", "4757", "4759", "4763", "4768", "4769", "4771", "4774", "4775", "4778", "4779", "4780", "4782", "4785", "4786", "4788", "4789", "4790", "4791", "4794", "4795", "4797", "4799", "4802", "4803", "4804", "4806", "4809", "4811", "4812", "4814", "4817", "4819", "4820", "4821", "4822", "4823", "4824", "4826", "4827", "4829", "4831", "4833", "4838", "4840", "4841", "4845", "4846", "4847", "4850", "4851", "4852", "4856", "4858", "4861", "4862", "4868", "4869", "4870", "4871", "4873", "4874", "4878", "4881", "4882", "4883", "4884", "4885", "4886", "4888", "4889", "4891", "4892", "4893", "4894", "4895", "4896", "4899", "4902", "4904", "4905", "4906", "4908", "4910", "4912", "4915", "4916", "4919", "4922", "4924", "4927", "4928", "4929", "4930", "4932", "4934", "4935", "4936", "4938", "4939", "4941", "4943", "4944", "4945", "4946", "4947", "4948", "4951", "4952", "4953", "4954", "4955", "4957", "4959", "4960", "4964", "4965", "4968", "4971", "4973", "4976", "4977", "4978", "4979", "4980", "4981", "4982", "4984", "4986", "4991", "4994", "4998", "4999", "5002", "5007", "5008", "5009", "5010", "5011", "5012", "5015", "5020", "5021", "5024", "5025", "5026", "5027", "5029", "5030", "5031", "5033", "5034", "5037", "5039", "5040", "5041", "5043", "5045", "5048", "5049", "5050", "5051", "5052", "5053", "5054", "5055", "5061", "5064", "5065", "5066", "5069", "5070", "5072", "5073", "5075", "5077", "5078", "5079", "5082", "5083", "5085", "5086", "5087", "5089", "5092", "5093", "5094", "5095", "5096", "5097", "5098", "5101", "5106", "5111", "5112", "5113", "5114", "5115", "5122", "5123", "5124", "5127", "5128", "5131", "5133", "5135", "5136", "5137", "5138", "5139", "5141", "5142", "5146", "5147", "5151", "5152", "5154", "5156", "5157", "5159", "5161", "5163", "5164", "5165", "5167", "5168", "5169", "5170", "5172", "5174", "5175", "5176", "5178", "5179", "5181", "5182", "5184", "5185", "5186", "5187", "5188", "5189", "5190", "5192", "5195", "5196", "5198", "5199", "5200", "5202", "5208", "5210", "5211", "5213", "5216", "5218", "5219", "5221", "5222", "5223", "5228", "5229", "5231", "5233", "5236", "5238", "5240", "5241", "5242", "5243", "5244", "5245", "5247", "5248", "5249", "5250", "5251", "5252", "5253", "5255", "5256", "5258", "5261", "5262", "5263", "5264", "5265", "5268", "5272", "5273", "5275", "5276", "5277", "5278", "5279", "5280", "5281", "5283", "5285", "5287", "5289", "5290", "5291", "5292", "5293", "5297", "5301", "5302", "5309", "5311", "5313", "5314", "5316", "5318", "5319", "5320", "5327", "5328", "5329", "5332", "5337", "5338", "5342", "5344", "5345", "5347", "5348", "5351", "5356", "5357", "5362", "5363", "5364", "5366", "5367", "5368", "5369", "5371", "5372", "5373", "5376", "5378", "5379", "5380", "5381", "5382", "5385", "5393", "5401", "5403", "5404", "5405", "5410", "5412", "5415", "5417", "5418", "5424", "5426", "5427", "5428", "5429", "5430", "5432", "5435", "5437", "5439", "5440", "5443", "5445", "5446", "5448", "5451", "5454", "5456", "5458", "5459", "5461", "5462", "5466", "5467", "5469", "5470", "5472", "5474", "5477", "5482", "5483", "5486", "5488", "5492", "5493", "5496", "5500", "5501", "5510", "5512", "5515", "5516", "5521", "5524", "5525", "5526", "5527", "5529", "5530", "5531", "5532", "5533", "5534", "5542", "5543", "5544", "5556", "5557", "5558", "5561", "5562", "5563", "5566", "5568", "5569", "5570", "5572", "5573", "5574", "5575", "5578", "5582", "5583", "5585", "5586", "5588", "5589", "5591", "5593", "5594", "5595", "5596", "5597", "5601", "5602", "5603", "5606", "5607", "5609", "5610", "5611", "5614", "5617", "5619", "5622", "5623", "5624", "5626", "5627", "5629", "5631", "5634", "5635", "5636", "5637", "5640", "5641", "5648", "5651", "5652", "5653", "5656", "5657", "5658", "5661", "5663", "5671", "5672", "5674", "5675", "5676", "5677", "5682", "5683", "5684", "5686", "5687", "5692", "5693", "5694", "5696", "5697", "5699", "5702", "5704", "5709", "5710", "5711", "5714", "5715", "5717", "5718", "5721", "5722", "5724", "5728", "5729", "5730", "5733", "5734", "5739", "5740", "5741", "5742", "5745", "5746", "5747", "5749", "5753", "5756", "5758", "5760", "5761", "5763", "5770", "5771", "5772", "5773", "5775", "5779", "5780", "5781", "5783", "5786", "5787", "5790", "5791", "5794", "5796", "5797", "5798", "5799", "5800", "5801", "5803", "5804", "5806", "5807", "5813", "5816", "5820", "5822", "5823", "5824", "5825", "5826", "5827", "5828", "5829", "5831", "5840", "5842", "5843", "5845", "5850", "5851", "5852", "5854", "5859", "5860", "5861", "5864", "5867", "5869", "5872", "5873", "5875", "5876", "5877", "5878", "5879", "5881", "5882", "5884", "5885", "5886", "5888", "5889", "5891", "5893", "5899", "5900", "5906", "5907", "5908", "5909", "5910", "5911", "5912", "5916", "5922", "5924", "5925", "5932", "5934", "5935", "5936", "5938", "5940", "5942", "5945", "5950", "5951", "5954", "5955", "5958", "5959", "5960", "5963", "5964", "5966", "5968", "5970", "5972", "5973", "5975", "5976", "5977", "5978", "5979", "5980", "5982", "5984", "5985", "5987", "5988", "5991", "5993", "5994", "5997", "5998", "5999"]],
+ "xtest" : ["int" , ["0", "4", "5", "10", "11", "13", "14", "15", "17", "20", "21", "22", "23", "24", "25", "30", "31", "33", "39", "42", "44", "47", "49", "52", "55", "57", "58", "59", "60", "61", "63", "64", "65", "69", "70", "73", "81", "83", "84", "87", "88", "93", "95", "102", "104", "105", "107", "108", "109", "110", "113", "115", "119", "122", "123", "125", "126", "127", "128", "132", "134", "136", "139", "141", "144", "149", "151", "152", "153", "155", "156", "157", "158", "159", "160", "166", "167", "172", "175", "180", "181", "187", "190", "191", "195", "196", "197", "199", "200", "201", "205", "206", "207", "208", "209", "212", "213", "214", "215", "217", "218", "219", "220", "222", "223", "224", "225", "227", "228", "230", "232", "233", "235", "236", "238", "239", "240", "241", "242", "243", "244", "245", "246", "247", "248", "255", "256", "257", "260", "261", "265", "270", "271", "272", "277", "278", "282", "283", "284", "285", "287", "288", "291", "292", "293", "296", "298", "300", "308", "309", "311", "313", "314", "315", "317", "319", "321", "322", "325", "326", "327", "330", "333", "335", "336", "341", "342", "343", "345", "347", "348", "349", "354", "357", "358", "361", "363", "364", "368", "371", "373", "374", "377", "378", "379", "380", "381", "382", "383", "384", "386", "388", "392", "394", "395", "399", "404", "406", "408", "409", "411", "412", "414", "417", "418", "419", "420", "421", "422", "424", "425", "426", "428", "430", "432", "433", "434", "435", "436", "441", "443", "445", "446", "449", "450", "452", "453", "454", "455", "457", "459", "460", "461", "463", "470", "472", "473", "474", "475", "476", "477", "478", "480", "482", "483", "484", "485", "486", "487", "488", "489", "492", "493", "494", "495", "499", "502", "506", "509", "511", "512", "518", "520", "524", "525", "528", "531", "532", "534", "535", "537", "540", "541", "542", "543", "545", "546", "547", "548", "549", "552", "554", "557", "558", "559", "561", "563", "565", "569", "571", "572", "573", "574", "577", "578", "580", "581", "582", "584", "586", "588", "589", "590", "591", "592", "594", "596", "598", "599", "600", "601", "606", "608", "609", "611", "612", "613", "614", "617", "621", "624", "626", "627", "628", "629", "630", "633", "639", "641", "642", "644", "645", "646", "647", "648", "649", "651", "653", "654", "659", "663", "664", "665", "666", "669", "670", "671", "673", "675", "678", "680", "681", "682", "683", "684", "687", "693", "697", "701", "702", "703", "704", "705", "706", "707", "709", "711", "714", "715", "718", "719", "725", "726", "730", "732", "736", "737", "741", "742", "743", "745", "747", "749", "750", "751", "753", "755", "757", "761", "762", "764", "765", "769", "771", "773", "774", "776", "777", "778", "780", "782", "787", "788", "789", "792", "795", "796", "797", "799", "801", "802", "803", "804", "805", "806", "808", "809", "810", "812", "813", "816", "818", "819", "820", "822", "825", "827", "832", "834", "835", "836", "837", "838", "839", "840", "842", "844", "846", "849", "853", "854", "855", "857", "859", "860", "861", "862", "865", "867", "869", "872", "874", "875", "878", "881", "885", "886", "888", "889", "890", "895", "896", "898", "900", "902", "903", "909", "911", "912", "913", "915", "916", "918", "919", "920", "923", "924", "927", "929", "931", "932", "936", "940", "943", "947", "950", "953", "955", "958", "960", "961", "962", "964", "969", "973", "974", "975", "977", "978", "982", "985", "987", "989", "990", "992", "993", "994", "995", "999", "1001", "1002", "1003", "1005", "1006", "1007", "1009", "1010", "1011", "1012", "1013", "1014", "1015", "1018", "1019", "1021", "1022", "1023", "1031", "1033", "1035", "1036", "1038", "1041", "1042", "1046", "1050", "1051", "1053", "1054", "1057", "1058", "1059", "1060", "1061", "1064", "1065", "1066", "1067", "1068", "1072", "1073", "1074", "1077", "1078", "1081", "1082", "1084", "1086", "1087", "1090", "1091", "1092", "1093", "1094", "1096", "1100", "1102", "1103", "1105", "1110", "1111", "1113", "1114", "1116", "1117", "1119", "1120", "1123", "1124", "1125", "1127", "1128", "1129", "1130", "1131", "1132", "1133", "1135", "1137", "1138", "1141", "1142", "1144", "1146", "1147", "1149", "1152", "1153", "1154", "1155", "1156", "1157", "1159", "1161", "1162", "1165", "1166", "1167", "1168", "1170", "1171", "1172", "1175", "1180", "1184", "1187", "1188", "1190", "1192", "1195", "1196", "1199", "1200", "1201", "1202", "1203", "1205", "1206", "1207", "1208", "1209", "1210", "1212", "1213", "1214", "1215", "1220", "1221", "1222", "1223", "1225", "1229", "1231", "1232", "1233", "1236", "1237", "1238", "1239", "1240", "1244", "1245", "1247", "1248", "1252", "1254", "1255", "1261", "1264", "1269", "1270", "1271", "1274", "1275", "1278", "1279", "1281", "1282", "1283", "1284", "1286", "1291", "1292", "1293", "1294", "1295", "1296", "1297", "1299", "1302", "1304", "1306", "1307", "1309", "1313", "1315", "1318", "1319", "1321", "1322", "1323", "1326", "1329", "1330", "1332", "1333", "1335", "1336", "1337", "1339", "1340", "1342", "1345", "1346", "1349", "1350", "1352", "1353", "1354", "1355", "1358", "1359", "1360", "1365", "1367", "1369", "1370", "1372", "1374", "1375", "1376", "1378", "1384", "1388", "1390", "1391", "1393", "1398", "1399", "1400", "1402", "1411", "1412", "1414", "1415", "1417", "1418", "1424", "1425", "1426", "1427", "1429", "1431", "1434", "1435", "1437", "1438", "1439", "1441", "1443", "1444", "1445", "1447", "1448", "1449", "1450", "1452", "1454", "1455", "1459", "1461", "1462", "1463", "1466", "1467", "1470", "1471", "1472", "1474", "1475", "1478", "1479", "1480", "1481", "1482", "1483", "1486", "1487", "1488", "1489", "1491", "1492", "1493", "1494", "1495", "1496", "1499", "1500", "1502", "1503", "1508", "1510", "1512", "1513", "1514", "1515", "1521", "1522", "1524", "1525", "1527", "1529", "1530", "1531", "1534", "1535", "1538", "1539", "1540", "1541", "1544", "1545", "1546", "1549", "1550", "1551", "1555", "1566", "1567", "1569", "1572", "1575", "1577", "1580", "1581", "1583", "1587", "1591", "1592", "1594", "1597", "1599", "1601", "1603", "1605", "1609", "1611", "1612", "1614", "1615", "1622", "1623", "1624", "1625", "1629", "1632", "1633", "1634", "1637", "1639", "1642", "1644", "1645", "1646", "1649", "1651", "1652", "1653", "1655", "1656", "1659", "1660", "1662", "1663", "1665", "1672", "1674", "1675", "1677", "1678", "1679", "1684", "1686", "1690", "1694", "1697", "1699", "1702", "1706", "1708", "1709", "1711", "1713", "1715", "1722", "1725", "1726", "1729", "1730", "1732", "1739", "1741", "1743", "1744", "1745", "1746", "1750", "1757", "1759", "1761", "1762", "1763", "1765", "1766", "1767", "1768", "1770", "1775", "1778", "1779", "1780", "1783", "1786", "1787", "1788", "1791", "1792", "1793", "1797", "1798", "1799", "1801", "1804", "1806", "1810", "1811", "1812", "1814", "1815", "1816", "1819", "1821", "1822", "1823", "1824", "1825", "1826", "1831", "1832", "1833", "1834", "1837", "1839", "1840", "1841", "1842", "1843", "1848", "1849", "1852", "1854", "1855", "1856", "1860", "1861", "1864", "1867", "1870", "1871", "1873", "1878", "1879", "1881", "1882", "1883", "1884", "1885", "1888", "1889", "1890", "1891", "1893", "1894", "1895", "1896", "1897", "1899", "1900", "1905", "1908", "1910", "1912", "1913", "1915", "1916", "1918", "1919", "1920", "1922", "1930", "1931", "1932", "1933", "1936", "1938", "1939", "1940", "1943", "1944", "1945", "1946", "1949", "1951", "1952", "1957", "1958", "1961", "1964", "1967", "1968", "1969", "1973", "1978", "1979", "1980", "1984", "1985", "1988", "1989", "1990", "1991", "1995", "1996", "1997", "1998", "1999", "2000", "2001", "2003", "2006", "2007", "2008", "2009", "2010", "2014", "2016", "2017", "2018", "2019", "2020", "2024", "2025", "2027", "2028", "2029", "2037", "2045", "2047", "2050", "2053", "2054", "2056", "2057", "2058", "2061", "2062", "2063", "2064", "2065", "2068", "2069", "2072", "2073", "2076", "2078", "2080", "2081", "2083", "2085", "2087", "2088", "2090", "2094", "2095", "2096", "2099", "2102", "2105", "2106", "2107", "2108", "2110", "2112", "2113", "2117", "2120", "2121", "2122", "2124", "2128", "2129", "2130", "2131", "2132", "2133", "2134", "2135", "2139", "2140", "2141", "2144", "2148", "2149", "2150", "2151", "2152", "2155", "2156", "2157", "2158", "2159", "2160", "2161", "2162", "2163", "2167", "2168", "2169", "2173", "2174", "2175", "2178", "2180", "2181", "2182", "2188", "2192", "2193", "2195", "2197", "2198", "2199", "2202", "2203", "2204", "2206", "2207", "2208", "2209", "2210", "2211", "2216", "2218", "2220", "2222", "2225", "2226", "2227", "2228", "2231", "2233", "2235", "2236", "2237", "2244", "2246", "2251", "2254", "2255", "2256", "2259", "2260", "2264", "2266", "2267", "2268", "2270", "2273", "2274", "2276", "2277", "2279", "2281", "2282", "2283", "2287", "2288", "2290", "2291", "2292", "2294", "2295", "2296", "2297", "2302", "2303", "2308", "2309", "2310", "2312", "2314", "2315", "2316", "2317", "2319", "2320", "2321", "2325", "2326", "2327", "2328", "2333", "2335", "2337", "2343", "2344", "2345", "2346", "2347", "2349", "2350", "2351", "2352", "2353", "2354", "2356", "2360", "2366", "2367", "2368", "2369", "2372", "2374", "2375", "2376", "2379", "2380", "2381", "2382", "2384", "2386", "2387", "2390", "2391", "2396", "2397", "2398", "2406", "2410", "2414", "2416", "2418", "2420", "2421", "2429", "2433", "2434", "2435", "2440", "2442", "2443", "2444", "2445", "2446", "2448", "2450", "2451", "2454", "2457", "2460", "2461", "2465", "2466", "2467", "2468", "2469", "2470", "2474", "2476", "2477", "2478", "2480", "2482", "2483", "2484", "2485", "2486", "2489", "2490", "2491", "2493", "2495", "2497", "2498", "2499", "2500", "2501", "2503", "2505", "2506", "2507", "2508", "2509", "2512", "2513", "2514", "2518", "2525", "2529", "2530", "2534", "2536", "2537", "2538", "2539", "2541", "2543", "2545", "2546", "2547", "2549", "2550", "2552", "2556", "2557", "2559", "2560", "2562", "2563", "2565", "2566", "2567", "2568", "2570", "2572", "2575", "2579", "2580", "2581", "2582", "2584", "2585", "2586", "2587", "2590", "2592", "2594", "2595", "2599", "2601", "2602", "2603", "2606", "2607", "2610", "2611", "2612", "2616", "2617", "2619", "2620", "2622", "2624", "2626", "2628", "2630", "2632", "2633", "2634", "2635", "2637", "2640", "2641", "2643", "2644", "2648", "2649", "2650", "2652", "2653", "2654", "2656", "2657", "2658", "2659", "2660", "2663", "2668", "2669", "2671", "2672", "2676", "2677", "2678", "2679", "2680", "2681", "2684", "2685", "2686", "2687", "2688", "2689", "2693", "2695", "2696", "2697", "2698", "2701", "2702", "2704", "2706", "2707", "2709", "2712", "2714", "2715", "2721", "2722", "2723", "2724", "2725", "2727", "2728", "2730", "2735", "2737", "2738", "2741", "2746", "2749", "2753", "2754", "2762", "2763", "2767", "2769", "2771", "2772", "2774", "2775", "2776", "2779", "2780", "2785", "2786", "2790", "2798", "2800", "2803", "2808", "2811", "2814", "2819", "2821", "2823", "2824", "2826", "2828", "2832", "2833", "2834", "2835", "2836", "2837", "2840", "2843", "2844", "2845", "2846", "2847", "2849", "2850", "2852", "2853", "2855", "2857", "2863", "2865", "2871", "2872", "2873", "2875", "2876", "2879", "2880", "2888", "2890", "2891", "2895", "2896", "2897", "2901", "2902", "2903", "2907", "2909", "2914", "2915", "2916", "2917", "2919", "2920", "2921", "2926", "2928", "2929", "2934", "2935", "2936", "2937", "2942", "2947", "2948", "2953", "2961", "2965", "2968", "2969", "2971", "2972", "2973", "2974", "2977", "2978", "2979", "2980", "2981", "2982", "2983", "2990", "2991", "2995", "2999", "3000", "3004", "3006", "3007", "3009", "3010", "3015", "3017", "3018", "3019", "3020", "3025", "3026", "3028", "3032", "3034", "3038", "3043", "3044", "3045", "3046", "3048", "3051", "3052", "3053", "3055", "3057", "3060", "3061", "3062", "3065", "3067", "3070", "3073", "3080", "3083", "3084", "3085", "3089", "3090", "3091", "3092", "3095", "3097", "3098", "3099", "3100", "3102", "3105", "3106", "3109", "3110", "3111", "3112", "3113", "3114", "3115", "3119", "3120", "3121", "3123", "3124", "3125", "3126", "3128", "3130", "3131", "3132", "3133", "3134", "3136", "3138", "3139", "3140", "3143", "3144", "3145", "3146", "3147", "3150", "3152", "3153", "3155", "3160", "3161", "3162", "3164", "3165", "3167", "3168", "3170", "3174", "3177", "3178", "3179", "3181", "3183", "3184", "3185", "3187", "3190", "3192", "3195", "3196", "3197", "3198", "3200", "3202", "3203", "3204", "3205", "3209", "3212", "3214", "3215", "3217", "3218", "3221", "3224", "3225", "3228", "3231", "3234", "3236", "3237", "3238", "3245", "3251", "3254", "3256", "3257", "3258", "3259", "3260", "3261", "3262", "3265", "3267", "3271", "3280", "3281", "3282", "3287", "3288", "3289", "3290", "3292", "3293", "3297", "3298", "3299", "3302", "3304", "3306", "3307", "3310", "3312", "3315", "3319", "3324", "3330", "3331", "3334", "3336", "3339", "3340", "3342", "3344", "3345", "3346", "3347", "3348", "3351", "3352", "3354", "3357", "3358", "3360", "3363", "3366", "3368", "3371", "3372", "3374", "3375", "3377", "3379", "3381", "3384", "3388", "3390", "3391", "3393", "3394", "3395", "3398", "3401", "3402", "3403", "3404", "3409", "3410", "3411", "3413", "3414", "3416", "3417", "3419", "3420", "3421", "3422", "3425", "3426", "3430", "3432", "3433", "3434", "3436", "3437", "3439", "3440", "3445", "3449", "3452", "3453", "3456", "3460", "3462", "3464", "3471", "3474", "3475", "3477", "3478", "3480", "3482", "3484", "3485", "3487", "3488", "3490", "3491", "3492", "3499", "3500", "3501", "3504", "3508", "3511", "3512", "3515", "3517", "3519", "3520", "3521", "3523", "3524", "3527", "3529", "3532", "3534", "3535", "3538", "3541", "3542", "3543", "3544", "3545", "3547", "3548", "3549", "3552", "3553", "3557", "3558", "3559", "3560", "3561", "3562", "3563", "3564", "3565", "3566", "3568", "3573", "3575", "3576", "3577", "3578", "3579", "3583", "3584", "3586", "3589", "3590", "3592", "3593", "3594", "3597", "3600", "3601", "3602", "3603", "3605", "3607", "3610", "3611", "3614", "3617", "3620", "3621", "3625", "3627", "3628", "3630", "3631", "3632", "3633", "3634", "3635", "3637", "3638", "3639", "3642", "3645", "3646", "3648", "3650", "3654", "3655", "3656", "3659", "3661", "3662", "3665", "3666", "3668", "3669", "3670", "3671", "3672", "3674", "3675", "3679", "3681", "3684", "3689", "3691", "3693", "3697", "3700", "3702", "3704", "3705", "3707", "3712", "3714", "3715", "3720", "3721", "3722", "3724", "3725", "3727", "3732", "3733", "3734", "3737", "3740", "3741", "3744", "3747", "3751", "3752", "3754", "3756", "3757", "3764", "3767", "3768", "3769", "3770", "3771", "3772", "3775", "3777", "3782", "3785", "3786", "3793", "3794", "3795", "3796", "3798", "3801", "3802", "3803", "3805", "3807", "3811", "3813", "3814", "3815", "3816", "3817", "3818", "3821", "3823", "3826", "3833", "3834", "3838", "3842", "3845", "3846", "3847", "3848", "3849", "3850", "3856", "3857", "3858", "3860", "3861", "3866", "3868", "3869", "3873", "3876", "3878", "3881", "3882", "3884", "3885", "3888", "3889", "3890", "3894", "3895", "3897", "3898", "3900", "3902", "3904", "3905", "3907", "3911", "3914", "3915", "3916", "3921", "3924", "3926", "3930", "3931", "3934", "3935", "3940", "3946", "3947", "3948", "3953", "3954", "3955", "3961", "3962", "3963", "3966", "3967", "3968", "3969", "3970", "3972", "3975", "3976", "3977", "3979", "3982", "3984", "3985", "3986", "3989", "3990", "3993", "3994", "3998", "3999", "4002", "4006", "4007", "4008", "4010", "4011", "4013", "4014", "4015", "4016", "4018", "4021", "4022", "4023", "4024", "4025", "4026", "4028", "4030", "4031", "4034", "4035", "4036", "4038", "4040", "4043", "4047", "4049", "4051", "4053", "4054", "4056", "4060", "4064", "4066", "4068", "4070", "4071", "4077", "4080", "4082", "4084", "4086", "4088", "4089", "4091", "4092", "4095", "4098", "4099", "4101", "4102", "4105", "4106", "4107", "4108", "4111", "4112", "4113", "4114", "4115", "4120", "4121", "4122", "4124", "4126", "4128", "4132", "4133", "4135", "4137", "4138", "4140", "4141", "4142", "4143", "4144", "4145", "4147", "4149", "4150", "4157", "4159", "4160", "4161", "4166", "4168", "4169", "4170", "4171", "4173", "4174", "4175", "4176", "4177", "4178", "4180", "4183", "4188", "4189", "4191", "4192", "4193", "4195", "4197", "4200", "4201", "4204", "4206", "4208", "4210", "4212", "4214", "4219", "4220", "4221", "4222", "4224", "4225", "4227", "4231", "4232", "4234", "4237", "4238", "4244", "4245", "4247", "4251", "4253", "4254", "4257", "4258", "4261", "4262", "4267", "4269", "4270", "4272", "4274", "4275", "4279", "4282", "4283", "4285", "4286", "4287", "4288", "4289", "4293", "4302", "4303", "4306", "4315", "4317", "4323", "4329", "4330", "4333", "4334", "4335", "4336", "4337", "4338", "4339", "4340", "4341", "4346", "4348", "4350", "4351", "4352", "4356", "4357", "4360", "4363", "4364", "4366", "4368", "4369", "4371", "4372", "4373", "4375", "4377", "4378", "4379", "4383", "4384", "4388", "4390", "4391", "4392", "4393", "4394", "4397", "4399", "4400", "4402", "4406", "4407", "4410", "4412", "4413", "4416", "4417", "4419", "4420", "4421", "4423", "4426", "4431", "4432", "4433", "4434", "4435", "4436", "4437", "4438", "4440", "4442", "4443", "4444", "4445", "4446", "4447", "4448", "4449", "4451", "4452", "4453", "4454", "4456", "4457", "4458", "4459", "4461", "4462", "4463", "4465", "4466", "4468", "4469", "4470", "4471", "4472", "4474", "4476", "4477", "4478", "4479", "4482", "4483", "4487", "4491", "4492", "4494", "4498", "4500", "4501", "4503", "4505", "4506", "4507", "4509", "4510", "4511", "4513", "4514", "4515", "4518", "4519", "4521", "4522", "4523", "4536", "4538", "4539", "4540", "4543", "4544", "4545", "4547", "4550", "4551", "4553", "4556", "4559", "4561", "4562", "4563", "4565", "4567", "4568", "4571", "4572", "4573", "4574", "4575", "4577", "4578", "4579", "4580", "4587", "4591", "4592", "4593", "4595", "4596", "4598", "4601", "4603", "4604", "4606", "4607", "4609", "4612", "4613", "4614", "4616", "4618", "4622", "4624", "4631", "4632", "4637", "4643", "4645", "4647", "4649", "4650", "4651", "4654", "4657", "4658", "4662", "4666", "4667", "4668", "4670", "4672", "4674", "4675", "4676", "4679", "4680", "4684", "4685", "4686", "4687", "4689", "4690", "4693", "4697", "4700", "4701", "4703", "4704", "4705", "4706", "4708", "4709", "4710", "4711", "4715", "4718", "4719", "4720", "4724", "4728", "4732", "4736", "4737", "4738", "4741", "4743", "4744", "4746", "4748", "4749", "4751", "4754", "4755", "4756", "4758", "4760", "4761", "4762", "4764", "4765", "4766", "4767", "4770", "4772", "4773", "4776", "4777", "4781", "4783", "4784", "4787", "4792", "4793", "4796", "4798", "4800", "4801", "4805", "4807", "4808", "4810", "4813", "4815", "4816", "4818", "4825", "4828", "4830", "4832", "4834", "4835", "4836", "4837", "4839", "4842", "4843", "4844", "4848", "4849", "4853", "4854", "4855", "4857", "4859", "4860", "4863", "4864", "4865", "4866", "4867", "4872", "4875", "4876", "4877", "4879", "4880", "4887", "4890", "4897", "4898", "4900", "4901", "4903", "4907", "4909", "4911", "4913", "4914", "4917", "4918", "4920", "4921", "4923", "4925", "4926", "4931", "4933", "4937", "4940", "4942", "4949", "4950", "4956", "4958", "4961", "4962", "4963", "4966", "4967", "4969", "4970", "4972", "4974", "4975", "4983", "4985", "4987", "4988", "4989", "4990", "4992", "4993", "4995", "4996", "4997", "5000", "5001", "5003", "5004", "5005", "5006", "5013", "5014", "5016", "5017", "5018", "5019", "5022", "5023", "5028", "5032", "5035", "5036", "5038", "5042", "5044", "5046", "5047", "5056", "5057", "5058", "5059", "5060", "5062", "5063", "5067", "5068", "5071", "5074", "5076", "5080", "5081", "5084", "5088", "5090", "5091", "5099", "5100", "5102", "5103", "5104", "5105", "5107", "5108", "5109", "5110", "5116", "5117", "5118", "5119", "5120", "5121", "5125", "5126", "5129", "5130", "5132", "5134", "5140", "5143", "5144", "5145", "5148", "5149", "5150", "5153", "5155", "5158", "5160", "5162", "5166", "5171", "5173", "5177", "5180", "5183", "5191", "5193", "5194", "5197", "5201", "5203", "5204", "5205", "5206", "5207", "5209", "5212", "5214", "5215", "5217", "5220", "5224", "5225", "5226", "5227", "5230", "5232", "5234", "5235", "5237", "5239", "5246", "5254", "5257", "5259", "5260", "5266", "5267", "5269", "5270", "5271", "5274", "5282", "5284", "5286", "5288", "5294", "5295", "5296", "5298", "5299", "5300", "5303", "5304", "5305", "5306", "5307", "5308", "5310", "5312", "5315", "5317", "5321", "5322", "5323", "5324", "5325", "5326", "5330", "5331", "5333", "5334", "5335", "5336", "5339", "5340", "5341", "5343", "5346", "5349", "5350", "5352", "5353", "5354", "5355", "5358", "5359", "5360", "5361", "5365", "5370", "5374", "5375", "5377", "5383", "5384", "5386", "5387", "5388", "5389", "5390", "5391", "5392", "5394", "5395", "5396", "5397", "5398", "5399", "5400", "5402", "5406", "5407", "5408", "5409", "5411", "5413", "5414", "5416", "5419", "5420", "5421", "5422", "5423", "5425", "5431", "5433", "5434", "5436", "5438", "5441", "5442", "5444", "5447", "5449", "5450", "5452", "5453", "5455", "5457", "5460", "5463", "5464", "5465", "5468", "5471", "5473", "5475", "5476", "5478", "5479", "5480", "5481", "5484", "5485", "5487", "5489", "5490", "5491", "5494", "5495", "5497", "5498", "5499", "5502", "5503", "5504", "5505", "5506", "5507", "5508", "5509", "5511", "5513", "5514", "5517", "5518", "5519", "5520", "5522", "5523", "5528", "5535", "5536", "5537", "5538", "5539", "5540", "5541", "5545", "5546", "5547", "5548", "5549", "5550", "5551", "5552", "5553", "5554", "5555", "5559", "5560", "5564", "5565", "5567", "5571", "5576", "5577", "5579", "5580", "5581", "5584", "5587", "5590", "5592", "5598", "5599", "5600", "5604", "5605", "5608", "5612", "5613", "5615", "5616", "5618", "5620", "5621", "5625", "5628", "5630", "5632", "5633", "5638", "5639", "5642", "5643", "5644", "5645", "5646", "5647", "5649", "5650", "5654", "5655", "5659", "5660", "5662", "5664", "5665", "5666", "5667", "5668", "5669", "5670", "5673", "5678", "5679", "5680", "5681", "5685", "5688", "5689", "5690", "5691", "5695", "5698", "5700", "5701", "5703", "5705", "5706", "5707", "5708", "5712", "5713", "5716", "5719", "5720", "5723", "5725", "5726", "5727", "5731", "5732", "5735", "5736", "5737", "5738", "5743", "5744", "5748", "5750", "5751", "5752", "5754", "5755", "5757", "5759", "5762", "5764", "5765", "5766", "5767", "5768", "5769", "5774", "5776", "5777", "5778", "5782", "5784", "5785", "5788", "5789", "5792", "5793", "5795", "5802", "5805", "5808", "5809", "5810", "5811", "5812", "5814", "5815", "5817", "5818", "5819", "5821", "5830", "5832", "5833", "5834", "5835", "5836", "5837", "5838", "5839", "5841", "5844", "5846", "5847", "5848", "5849", "5853", "5855", "5856", "5857", "5858", "5862", "5863", "5865", "5866", "5868", "5870", "5871", "5874", "5880", "5883", "5887", "5890", "5892", "5894", "5895", "5896", "5897", "5898", "5901", "5902", "5903", "5904", "5905", "5913", "5914", "5915", "5917", "5918", "5919", "5920", "5921", "5923", "5926", "5927", "5928", "5929", "5930", "5931", "5933", "5937", "5939", "5941", "5943", "5944", "5946", "5947", "5948", "5949", "5952", "5953", "5956", "5957", "5961", "5962", "5965", "5967", "5969", "5971", "5974", "5981", "5983", "5986", "5989", "5990", "5992", "5995", "5996"]]
+}
\ No newline at end of file
diff --git a/AutoDL-Projects/configs/opts/CIFAR-E300-W5-L1-COS.config b/AutoDL-Projects/configs/opts/CIFAR-E300-W5-L1-COS.config
new file mode 100644
index 0000000..7c0504d
--- /dev/null
+++ b/AutoDL-Projects/configs/opts/CIFAR-E300-W5-L1-COS.config
@@ -0,0 +1,13 @@
+{
+ "scheduler": ["str", "cos"],
+ "eta_min" : ["float", "0.0"],
+ "epochs" : ["int", "300"],
+ "warmup" : ["int", "5"],
+ "optim" : ["str", "SGD"],
+ "LR" : ["float", "0.1"],
+ "decay" : ["float", "0.0005"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "1"],
+ "criterion": ["str", "Softmax"],
+ "auxiliary": ["float", "-1"]
+}
diff --git a/AutoDL-Projects/configs/opts/CIFAR-E300-W5-L4-COS.config b/AutoDL-Projects/configs/opts/CIFAR-E300-W5-L4-COS.config
new file mode 100644
index 0000000..c505ccf
--- /dev/null
+++ b/AutoDL-Projects/configs/opts/CIFAR-E300-W5-L4-COS.config
@@ -0,0 +1,12 @@
+{
+ "scheduler": ["str", "cos"],
+ "eta_min" : ["float", "0.0"],
+ "epochs" : ["int", "300"],
+ "warmup" : ["int", "5"],
+ "optim" : ["str", "SGD"],
+ "LR" : ["float", "0.4"],
+ "decay" : ["float", "0.0005"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "1"],
+ "criterion": ["str", "Softmax"]
+}
diff --git a/AutoDL-Projects/configs/opts/CIFAR-E600-W5-L1-COS.config b/AutoDL-Projects/configs/opts/CIFAR-E600-W5-L1-COS.config
new file mode 100644
index 0000000..a3ce90a
--- /dev/null
+++ b/AutoDL-Projects/configs/opts/CIFAR-E600-W5-L1-COS.config
@@ -0,0 +1,12 @@
+{
+ "scheduler": ["str", "cos"],
+ "eta_min" : ["float", "0.0"],
+ "epochs" : ["int", "600"],
+ "warmup" : ["int", "5"],
+ "optim" : ["str", "SGD"],
+ "LR" : ["float", "0.1"],
+ "decay" : ["float", "0.0005"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "1"],
+ "criterion": ["str", "Softmax"]
+}
diff --git a/AutoDL-Projects/configs/opts/CIFAR-Fast-Random.config b/AutoDL-Projects/configs/opts/CIFAR-Fast-Random.config
new file mode 100644
index 0000000..9513040
--- /dev/null
+++ b/AutoDL-Projects/configs/opts/CIFAR-Fast-Random.config
@@ -0,0 +1,13 @@
+{
+ "scheduler": ["str", "cos"],
+ "eta_min" : ["float", "0.0"],
+ "epochs" : ["int", "100"],
+ "warmup" : ["int", "5"],
+ "optim" : ["str", "SGD"],
+ "LR" : ["float", "0.1"],
+ "decay" : ["float", "0.0005"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "1"],
+ "criterion": ["str", "Softmax"],
+ "auxiliary": ["float", "-1"]
+}
diff --git a/AutoDL-Projects/configs/opts/CIFAR-Slow-Random.config b/AutoDL-Projects/configs/opts/CIFAR-Slow-Random.config
new file mode 100644
index 0000000..7c0504d
--- /dev/null
+++ b/AutoDL-Projects/configs/opts/CIFAR-Slow-Random.config
@@ -0,0 +1,13 @@
+{
+ "scheduler": ["str", "cos"],
+ "eta_min" : ["float", "0.0"],
+ "epochs" : ["int", "300"],
+ "warmup" : ["int", "5"],
+ "optim" : ["str", "SGD"],
+ "LR" : ["float", "0.1"],
+ "decay" : ["float", "0.0005"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "1"],
+ "criterion": ["str", "Softmax"],
+ "auxiliary": ["float", "-1"]
+}
diff --git a/AutoDL-Projects/configs/opts/Com-Paddle-NAS.config b/AutoDL-Projects/configs/opts/Com-Paddle-NAS.config
new file mode 100644
index 0000000..be1f932
--- /dev/null
+++ b/AutoDL-Projects/configs/opts/Com-Paddle-NAS.config
@@ -0,0 +1,13 @@
+{
+ "scheduler": ["str", "cos"],
+ "eta_min" : ["float", "0.0"],
+ "epochs" : ["int", "595"],
+ "warmup" : ["int", "5"],
+ "optim" : ["str", "SGD"],
+ "LR" : ["float", "0.025"],
+ "decay" : ["float", "0.0005"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "1"],
+ "criterion": ["str", "Softmax"],
+ "auxiliary": ["float", "0.4"]
+}
diff --git a/AutoDL-Projects/configs/opts/Com-Paddle-RES.config b/AutoDL-Projects/configs/opts/Com-Paddle-RES.config
new file mode 100644
index 0000000..21bccbe
--- /dev/null
+++ b/AutoDL-Projects/configs/opts/Com-Paddle-RES.config
@@ -0,0 +1,13 @@
+{
+ "scheduler": ["str", "cos"],
+ "eta_min" : ["float", "0.0"],
+ "epochs" : ["int", "300"],
+ "warmup" : ["int", "5"] ,
+ "optim" : ["str", "SGD"],
+ "LR" : ["float", "0.1"],
+ "decay" : ["float", "0.0005"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool" , "1"] ,
+ "criterion": ["str" , "Softmax"],
+ "auxiliary": ["float", "-1"]
+}
diff --git a/AutoDL-Projects/configs/opts/ImageNet-E120-Cos-Smooth.config b/AutoDL-Projects/configs/opts/ImageNet-E120-Cos-Smooth.config
new file mode 100644
index 0000000..0047364
--- /dev/null
+++ b/AutoDL-Projects/configs/opts/ImageNet-E120-Cos-Smooth.config
@@ -0,0 +1,14 @@
+{
+ "scheduler": ["str", "cos"],
+ "eta_min" : ["float", "0.0"],
+ "epochs" : ["int", "120"],
+ "warmup" : ["int", "5"],
+ "optim" : ["str", "SGD"],
+ "LR" : ["float", "0.1"],
+ "decay" : ["float", "0.0001"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "1"],
+ "criterion": ["str", "SmoothSoftmax"],
+ "label_smooth": ["float", 0.1],
+ "auxiliary": ["float", "-1"]
+}
diff --git a/AutoDL-Projects/configs/opts/ImageNet-E120-Cos-Soft.config b/AutoDL-Projects/configs/opts/ImageNet-E120-Cos-Soft.config
new file mode 100644
index 0000000..702085c
--- /dev/null
+++ b/AutoDL-Projects/configs/opts/ImageNet-E120-Cos-Soft.config
@@ -0,0 +1,13 @@
+{
+ "scheduler": ["str", "cos"],
+ "eta_min" : ["float", "0.0"],
+ "epochs" : ["int", "120"],
+ "warmup" : ["int", "5"],
+ "optim" : ["str", "SGD"],
+ "LR" : ["float", "0.1"],
+ "decay" : ["float", "0.0001"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "1"],
+ "criterion": ["str", "Softmax"],
+ "auxiliary": ["float", "-1"]
+}
diff --git a/AutoDL-Projects/configs/opts/ImageNet-E120-Step-Soft.config b/AutoDL-Projects/configs/opts/ImageNet-E120-Step-Soft.config
new file mode 100644
index 0000000..fe4a7f6
--- /dev/null
+++ b/AutoDL-Projects/configs/opts/ImageNet-E120-Step-Soft.config
@@ -0,0 +1,14 @@
+{
+ "scheduler": ["str", "multistep"],
+ "epochs" : ["int", "120"],
+ "warmup" : ["int", "5"],
+ "optim" : ["str", "SGD"],
+ "LR" : ["float", "0.1"],
+ "milestones":["int", [30, 60, 90]],
+ "gammas" : ["float", [0.1, 0.1, 0.1]],
+ "decay" : ["float", "0.0001"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "1"],
+ "criterion": ["str", "Softmax"],
+ "auxiliary": ["float", "-1"]
+}
diff --git a/AutoDL-Projects/configs/opts/NAS-CIFAR-V2.config b/AutoDL-Projects/configs/opts/NAS-CIFAR-V2.config
new file mode 100644
index 0000000..502d5a4
--- /dev/null
+++ b/AutoDL-Projects/configs/opts/NAS-CIFAR-V2.config
@@ -0,0 +1,13 @@
+{
+ "scheduler": ["str", "cos"],
+ "eta_min" : ["float", "0.0"],
+ "epochs" : ["int", "595"],
+ "warmup" : ["int", "5"],
+ "optim" : ["str", "SGD"],
+ "LR" : ["float", "0.025"],
+ "decay" : ["float", "0.0003"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "1"],
+ "criterion": ["str", "Softmax"],
+ "auxiliary": ["float", "0.4"]
+}
diff --git a/AutoDL-Projects/configs/opts/NAS-CIFAR.config b/AutoDL-Projects/configs/opts/NAS-CIFAR.config
new file mode 100644
index 0000000..4b81c1b
--- /dev/null
+++ b/AutoDL-Projects/configs/opts/NAS-CIFAR.config
@@ -0,0 +1,13 @@
+{
+ "scheduler": ["str", "cos"],
+ "eta_min" : ["float", "0.0"],
+ "epochs" : ["int", "295"],
+ "warmup" : ["int", "5"],
+ "optim" : ["str", "SGD"],
+ "LR" : ["float", "0.025"],
+ "decay" : ["float", "0.0005"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "1"],
+ "criterion": ["str", "Softmax"],
+ "auxiliary": ["float", "0.4"]
+}
diff --git a/AutoDL-Projects/configs/opts/NAS-IMAGENET.config b/AutoDL-Projects/configs/opts/NAS-IMAGENET.config
new file mode 100644
index 0000000..e862254
--- /dev/null
+++ b/AutoDL-Projects/configs/opts/NAS-IMAGENET.config
@@ -0,0 +1,14 @@
+{
+ "scheduler": ["str", "cos"],
+ "eta_min" : ["float", "0.0"],
+ "epochs" : ["int", "245"],
+ "warmup" : ["int", "5"],
+ "optim" : ["str", "SGD"],
+ "LR" : ["float", "0.1"],
+ "decay" : ["float", "0.00003"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "1"],
+ "criterion": ["str", "SmoothSoftmax"],
+ "label_smooth": ["float", 0.1],
+ "auxiliary" : ["float", "0.4"]
+}
diff --git a/AutoDL-Projects/configs/qlib/workflow_config_TabNet_Alpha360.yaml b/AutoDL-Projects/configs/qlib/workflow_config_TabNet_Alpha360.yaml
new file mode 100644
index 0000000..3e63892
--- /dev/null
+++ b/AutoDL-Projects/configs/qlib/workflow_config_TabNet_Alpha360.yaml
@@ -0,0 +1,78 @@
+qlib_init:
+ provider_uri: "~/.qlib/qlib_data/cn_data"
+ region: cn
+market: &market all
+benchmark: &benchmark SH000300
+data_handler_config: &data_handler_config
+ start_time: 2008-01-01
+ end_time: 2020-08-01
+ fit_start_time: 2008-01-01
+ fit_end_time: 2014-12-31
+ instruments: *market
+ infer_processors:
+ - class: RobustZScoreNorm
+ kwargs:
+ fields_group: feature
+ clip_outlier: true
+ - class: Fillna
+ kwargs:
+ fields_group: feature
+ learn_processors:
+ - class: DropnaLabel
+ - class: CSRankNorm
+ kwargs:
+ fields_group: label
+ label: ["Ref($close, -2) / Ref($close, -1) - 1"]
+port_analysis_config: &port_analysis_config
+ strategy:
+ class: TopkDropoutStrategy
+ module_path: qlib.contrib.strategy.strategy
+ kwargs:
+ topk: 50
+ n_drop: 5
+ backtest:
+ verbose: False
+ limit_threshold: 0.095
+ account: 100000000
+ benchmark: *benchmark
+ deal_price: close
+ open_cost: 0.0005
+ close_cost: 0.0015
+ min_cost: 5
+task:
+ model:
+ class: TabnetModel
+ module_path: qlib.contrib.model.pytorch_tabnet
+ kwargs:
+ d_feat: 360
+ pretrain: True
+ dataset:
+ class: DatasetH
+ module_path: qlib.data.dataset
+ kwargs:
+ handler:
+ class: Alpha360
+ module_path: qlib.contrib.data.handler
+ kwargs: *data_handler_config
+ segments:
+ pretrain: [2008-01-01, 2014-12-31]
+ pretrain_validation: [2015-01-01, 2016-12-31]
+ train: [2008-01-01, 2014-12-31]
+ valid: [2015-01-01, 2016-12-31]
+ test: [2017-01-01, 2020-08-01]
+ record:
+ - class: SignalRecord
+ module_path: qlib.workflow.record_temp
+ kwargs: {}
+ - class: SignalMseRecord
+ module_path: qlib.contrib.workflow.record_temp
+ kwargs: {}
+ - class: SigAnaRecord
+ module_path: qlib.workflow.record_temp
+ kwargs:
+ ana_long_short: False
+ ann_scaler: 252
+ - class: PortAnaRecord
+ module_path: qlib.workflow.record_temp
+ kwargs:
+ config: *port_analysis_config
diff --git a/AutoDL-Projects/configs/qlib/workflow_config_alstm_Alpha360.yaml b/AutoDL-Projects/configs/qlib/workflow_config_alstm_Alpha360.yaml
new file mode 100644
index 0000000..58e8163
--- /dev/null
+++ b/AutoDL-Projects/configs/qlib/workflow_config_alstm_Alpha360.yaml
@@ -0,0 +1,86 @@
+qlib_init:
+ provider_uri: "~/.qlib/qlib_data/cn_data"
+ region: cn
+market: &market all
+benchmark: &benchmark SH000300
+data_handler_config: &data_handler_config
+ start_time: 2008-01-01
+ end_time: 2020-08-01
+ fit_start_time: 2008-01-01
+ fit_end_time: 2014-12-31
+ instruments: *market
+ infer_processors:
+ - class: RobustZScoreNorm
+ kwargs:
+ fields_group: feature
+ clip_outlier: true
+ - class: Fillna
+ kwargs:
+ fields_group: feature
+ learn_processors:
+ - class: DropnaLabel
+ - class: CSRankNorm
+ kwargs:
+ fields_group: label
+ label: ["Ref($close, -2) / Ref($close, -1) - 1"]
+port_analysis_config: &port_analysis_config
+ strategy:
+ class: TopkDropoutStrategy
+ module_path: qlib.contrib.strategy.strategy
+ kwargs:
+ topk: 50
+ n_drop: 5
+ backtest:
+ verbose: False
+ limit_threshold: 0.095
+ account: 100000000
+ benchmark: *benchmark
+ deal_price: close
+ open_cost: 0.0005
+ close_cost: 0.0015
+ min_cost: 5
+task:
+ model:
+ class: ALSTM
+ module_path: qlib.contrib.model.pytorch_alstm
+ kwargs:
+ d_feat: 6
+ hidden_size: 64
+ num_layers: 2
+ dropout: 0.0
+ n_epochs: 200
+ lr: 1e-3
+ early_stop: 20
+ batch_size: 800
+ metric: loss
+ loss: mse
+ GPU: 0
+ rnn_type: GRU
+ dataset:
+ class: DatasetH
+ module_path: qlib.data.dataset
+ kwargs:
+ handler:
+ class: Alpha360
+ module_path: qlib.contrib.data.handler
+ kwargs: *data_handler_config
+ segments:
+ train: [2008-01-01, 2014-12-31]
+ valid: [2015-01-01, 2016-12-31]
+ test: [2017-01-01, 2020-08-01]
+ record:
+ - class: SignalRecord
+ module_path: qlib.workflow.record_temp
+ kwargs: {}
+ - class: SignalMseRecord
+ module_path: qlib.contrib.workflow.record_temp
+ kwargs: {}
+ - class: SigAnaRecord
+ module_path: qlib.workflow.record_temp
+ kwargs:
+ ana_long_short: False
+ ann_scaler: 252
+ - class: PortAnaRecord
+ module_path: qlib.workflow.record_temp
+ kwargs:
+ config: *port_analysis_config
diff --git a/AutoDL-Projects/configs/qlib/workflow_config_doubleensemble_Alpha360.yaml b/AutoDL-Projects/configs/qlib/workflow_config_doubleensemble_Alpha360.yaml
new file mode 100644
index 0000000..a28f7bc
--- /dev/null
+++ b/AutoDL-Projects/configs/qlib/workflow_config_doubleensemble_Alpha360.yaml
@@ -0,0 +1,100 @@
+qlib_init:
+ provider_uri: "~/.qlib/qlib_data/cn_data"
+ region: cn
+market: &market all
+benchmark: &benchmark SH000300
+data_handler_config: &data_handler_config
+ start_time: 2008-01-01
+ end_time: 2020-08-01
+ fit_start_time: 2008-01-01
+ fit_end_time: 2014-12-31
+ instruments: *market
+ infer_processors: []
+ learn_processors:
+ - class: DropnaLabel
+ - class: CSRankNorm
+ kwargs:
+ fields_group: label
+ label: ["Ref($close, -2) / Ref($close, -1) - 1"]
+port_analysis_config: &port_analysis_config
+ strategy:
+ class: TopkDropoutStrategy
+ module_path: qlib.contrib.strategy.strategy
+ kwargs:
+ topk: 50
+ n_drop: 5
+ backtest:
+ verbose: False
+ limit_threshold: 0.095
+ account: 100000000
+ benchmark: *benchmark
+ deal_price: close
+ open_cost: 0.0005
+ close_cost: 0.0015
+ min_cost: 5
+task:
+ model:
+ class: DEnsembleModel
+ module_path: qlib.contrib.model.double_ensemble
+ kwargs:
+ base_model: "gbm"
+ loss: mse
+ num_models: 6
+ enable_sr: True
+ enable_fs: True
+ alpha1: 1
+ alpha2: 1
+ bins_sr: 10
+ bins_fs: 5
+ decay: 0.5
+ sample_ratios:
+ - 0.8
+ - 0.7
+ - 0.6
+ - 0.5
+ - 0.4
+ sub_weights:
+ - 1
+ - 0.2
+ - 0.2
+ - 0.2
+ - 0.2
+ - 0.2
+ epochs: 136
+ colsample_bytree: 0.8879
+ learning_rate: 0.0421
+ subsample: 0.8789
+ lambda_l1: 205.6999
+ lambda_l2: 580.9768
+ max_depth: 8
+ num_leaves: 210
+ num_threads: 20
+ verbosity: -1
+ dataset:
+ class: DatasetH
+ module_path: qlib.data.dataset
+ kwargs:
+ handler:
+ class: Alpha360
+ module_path: qlib.contrib.data.handler
+ kwargs: *data_handler_config
+ segments:
+ train: [2008-01-01, 2014-12-31]
+ valid: [2015-01-01, 2016-12-31]
+ test: [2017-01-01, 2020-08-01]
+ record:
+ - class: SignalRecord
+ module_path: qlib.workflow.record_temp
+ kwargs: {}
+ - class: SignalMseRecord
+ module_path: qlib.contrib.workflow.record_temp
+ kwargs: {}
+ - class: SigAnaRecord
+ module_path: qlib.workflow.record_temp
+ kwargs:
+ ana_long_short: False
+ ann_scaler: 252
+ - class: PortAnaRecord
+ module_path: qlib.workflow.record_temp
+ kwargs:
+ config: *port_analysis_config
diff --git a/AutoDL-Projects/configs/qlib/workflow_config_gru_Alpha360.yaml b/AutoDL-Projects/configs/qlib/workflow_config_gru_Alpha360.yaml
new file mode 100644
index 0000000..d6a7d25
--- /dev/null
+++ b/AutoDL-Projects/configs/qlib/workflow_config_gru_Alpha360.yaml
@@ -0,0 +1,85 @@
+qlib_init:
+ provider_uri: "~/.qlib/qlib_data/cn_data"
+ region: cn
+market: &market all
+benchmark: &benchmark SH000300
+data_handler_config: &data_handler_config
+ start_time: 2008-01-01
+ end_time: 2020-08-01
+ fit_start_time: 2008-01-01
+ fit_end_time: 2014-12-31
+ instruments: *market
+ infer_processors:
+ - class: RobustZScoreNorm
+ kwargs:
+ fields_group: feature
+ clip_outlier: true
+ - class: Fillna
+ kwargs:
+ fields_group: feature
+ learn_processors:
+ - class: DropnaLabel
+ - class: CSRankNorm
+ kwargs:
+ fields_group: label
+ label: ["Ref($close, -2) / Ref($close, -1) - 1"]
+port_analysis_config: &port_analysis_config
+ strategy:
+ class: TopkDropoutStrategy
+ module_path: qlib.contrib.strategy.strategy
+ kwargs:
+ topk: 50
+ n_drop: 5
+ backtest:
+ verbose: False
+ limit_threshold: 0.095
+ account: 100000000
+ benchmark: *benchmark
+ deal_price: close
+ open_cost: 0.0005
+ close_cost: 0.0015
+ min_cost: 5
+task:
+ model:
+ class: GRU
+ module_path: qlib.contrib.model.pytorch_gru
+ kwargs:
+ d_feat: 6
+ hidden_size: 64
+ num_layers: 2
+ dropout: 0.0
+ n_epochs: 200
+ lr: 1e-3
+ early_stop: 20
+ batch_size: 800
+ metric: loss
+ loss: mse
+ GPU: 0
+ dataset:
+ class: DatasetH
+ module_path: qlib.data.dataset
+ kwargs:
+ handler:
+ class: Alpha360
+ module_path: qlib.contrib.data.handler
+ kwargs: *data_handler_config
+ segments:
+ train: [2008-01-01, 2014-12-31]
+ valid: [2015-01-01, 2016-12-31]
+ test: [2017-01-01, 2020-08-01]
+ record:
+ - class: SignalRecord
+ module_path: qlib.workflow.record_temp
+ kwargs: {}
+ - class: SignalMseRecord
+ module_path: qlib.contrib.workflow.record_temp
+ kwargs: {}
+ - class: SigAnaRecord
+ module_path: qlib.workflow.record_temp
+ kwargs:
+ ana_long_short: False
+ ann_scaler: 252
+ - class: PortAnaRecord
+ module_path: qlib.workflow.record_temp
+ kwargs:
+ config: *port_analysis_config
diff --git a/AutoDL-Projects/configs/qlib/workflow_config_lightgbm_Alpha360.yaml b/AutoDL-Projects/configs/qlib/workflow_config_lightgbm_Alpha360.yaml
new file mode 100644
index 0000000..4816ae2
--- /dev/null
+++ b/AutoDL-Projects/configs/qlib/workflow_config_lightgbm_Alpha360.yaml
@@ -0,0 +1,83 @@
+qlib_init:
+ provider_uri: "~/.qlib/qlib_data/cn_data"
+ region: cn
+market: &market all
+benchmark: &benchmark SH000300
+data_handler_config: &data_handler_config
+ start_time: 2008-01-01
+ end_time: 2020-08-01
+ fit_start_time: 2008-01-01
+ fit_end_time: 2014-12-31
+ instruments: *market
+ infer_processors:
+ - class: RobustZScoreNorm
+ kwargs:
+ fields_group: feature
+ clip_outlier: true
+ - class: Fillna
+ kwargs:
+ fields_group: feature
+ learn_processors:
+ - class: DropnaLabel
+ - class: CSRankNorm
+ kwargs:
+ fields_group: label
+ label: ["Ref($close, -2) / Ref($close, -1) - 1"]
+port_analysis_config: &port_analysis_config
+ strategy:
+ class: TopkDropoutStrategy
+ module_path: qlib.contrib.strategy.strategy
+ kwargs:
+ topk: 50
+ n_drop: 5
+ backtest:
+ verbose: False
+ limit_threshold: 0.095
+ account: 100000000
+ benchmark: *benchmark
+ deal_price: close
+ open_cost: 0.0005
+ close_cost: 0.0015
+ min_cost: 5
+task:
+ model:
+ class: LGBModel
+ module_path: qlib.contrib.model.gbdt
+ kwargs:
+ loss: mse
+ colsample_bytree: 0.8879
+ learning_rate: 0.0421
+ subsample: 0.8789
+ lambda_l1: 205.6999
+ lambda_l2: 580.9768
+ max_depth: 8
+ num_leaves: 210
+ num_threads: 20
+ dataset:
+ class: DatasetH
+ module_path: qlib.data.dataset
+ kwargs:
+ handler:
+ class: Alpha360
+ module_path: qlib.contrib.data.handler
+ kwargs: *data_handler_config
+ segments:
+ train: [2008-01-01, 2014-12-31]
+ valid: [2015-01-01, 2016-12-31]
+ test: [2017-01-01, 2020-08-01]
+ record:
+ - class: SignalRecord
+ module_path: qlib.workflow.record_temp
+ kwargs: {}
+ - class: SignalMseRecord
+ module_path: qlib.contrib.workflow.record_temp
+ kwargs: {}
+ - class: SigAnaRecord
+ module_path: qlib.workflow.record_temp
+ kwargs:
+ ana_long_short: False
+ ann_scaler: 252
+ - class: PortAnaRecord
+ module_path: qlib.workflow.record_temp
+ kwargs:
+ config: *port_analysis_config
diff --git a/AutoDL-Projects/configs/qlib/workflow_config_lstm_Alpha360.yaml b/AutoDL-Projects/configs/qlib/workflow_config_lstm_Alpha360.yaml
new file mode 100644
index 0000000..fb37fb4
--- /dev/null
+++ b/AutoDL-Projects/configs/qlib/workflow_config_lstm_Alpha360.yaml
@@ -0,0 +1,85 @@
+qlib_init:
+ provider_uri: "~/.qlib/qlib_data/cn_data"
+ region: cn
+market: &market all
+benchmark: &benchmark SH000300
+data_handler_config: &data_handler_config
+ start_time: 2008-01-01
+ end_time: 2020-08-01
+ fit_start_time: 2008-01-01
+ fit_end_time: 2014-12-31
+ instruments: *market
+ infer_processors:
+ - class: RobustZScoreNorm
+ kwargs:
+ fields_group: feature
+ clip_outlier: true
+ - class: Fillna
+ kwargs:
+ fields_group: feature
+ learn_processors:
+ - class: DropnaLabel
+ - class: CSRankNorm
+ kwargs:
+ fields_group: label
+ label: ["Ref($close, -2) / Ref($close, -1) - 1"]
+port_analysis_config: &port_analysis_config
+ strategy:
+ class: TopkDropoutStrategy
+ module_path: qlib.contrib.strategy.strategy
+ kwargs:
+ topk: 50
+ n_drop: 5
+ backtest:
+ verbose: False
+ limit_threshold: 0.095
+ account: 100000000
+ benchmark: *benchmark
+ deal_price: close
+ open_cost: 0.0005
+ close_cost: 0.0015
+ min_cost: 5
+task:
+ model:
+ class: LSTM
+ module_path: qlib.contrib.model.pytorch_lstm
+ kwargs:
+ d_feat: 6
+ hidden_size: 64
+ num_layers: 2
+ dropout: 0.0
+ n_epochs: 200
+ lr: 1e-3
+ early_stop: 20
+ batch_size: 800
+ metric: loss
+ loss: mse
+ GPU: 0
+ dataset:
+ class: DatasetH
+ module_path: qlib.data.dataset
+ kwargs:
+ handler:
+ class: Alpha360
+ module_path: qlib.contrib.data.handler
+ kwargs: *data_handler_config
+ segments:
+ train: [2008-01-01, 2014-12-31]
+ valid: [2015-01-01, 2016-12-31]
+ test: [2017-01-01, 2020-08-01]
+ record:
+ - class: SignalRecord
+ module_path: qlib.workflow.record_temp
+ kwargs: {}
+ - class: SignalMseRecord
+ module_path: qlib.contrib.workflow.record_temp
+ kwargs: {}
+ - class: SigAnaRecord
+ module_path: qlib.workflow.record_temp
+ kwargs:
+ ana_long_short: False
+ ann_scaler: 252
+ - class: PortAnaRecord
+ module_path: qlib.workflow.record_temp
+ kwargs:
+ config: *port_analysis_config
diff --git a/AutoDL-Projects/configs/qlib/workflow_config_mlp_Alpha360.yaml b/AutoDL-Projects/configs/qlib/workflow_config_mlp_Alpha360.yaml
new file mode 100644
index 0000000..9d505d0
--- /dev/null
+++ b/AutoDL-Projects/configs/qlib/workflow_config_mlp_Alpha360.yaml
@@ -0,0 +1,85 @@
+qlib_init:
+ provider_uri: "~/.qlib/qlib_data/cn_data"
+ region: cn
+market: &market all
+benchmark: &benchmark SH000300
+data_handler_config: &data_handler_config
+ start_time: 2008-01-01
+ end_time: 2020-08-01
+ fit_start_time: 2008-01-01
+ fit_end_time: 2014-12-31
+ instruments: *market
+ infer_processors:
+ - class: RobustZScoreNorm
+ kwargs:
+ fields_group: feature
+ clip_outlier: true
+ - class: Fillna
+ kwargs:
+ fields_group: feature
+ learn_processors:
+ - class: DropnaLabel
+ - class: CSRankNorm
+ kwargs:
+ fields_group: label
+ label: ["Ref($close, -2) / Ref($close, -1) - 1"]
+
+port_analysis_config: &port_analysis_config
+ strategy:
+ class: TopkDropoutStrategy
+ module_path: qlib.contrib.strategy.strategy
+ kwargs:
+ topk: 50
+ n_drop: 5
+ backtest:
+ verbose: False
+ limit_threshold: 0.095
+ account: 100000000
+ benchmark: *benchmark
+ deal_price: close
+ open_cost: 0.0005
+ close_cost: 0.0015
+ min_cost: 5
+task:
+ model:
+ class: DNNModelPytorch
+ module_path: qlib.contrib.model.pytorch_nn
+ kwargs:
+ loss: mse
+ input_dim: 360
+ output_dim: 1
+ lr: 0.002
+ lr_decay: 0.96
+ lr_decay_steps: 100
+ optimizer: adam
+ max_steps: 8000
+ batch_size: 4096
+ GPU: 0
+ dataset:
+ class: DatasetH
+ module_path: qlib.data.dataset
+ kwargs:
+ handler:
+ class: Alpha360
+ module_path: qlib.contrib.data.handler
+ kwargs: *data_handler_config
+ segments:
+ train: [2008-01-01, 2014-12-31]
+ valid: [2015-01-01, 2016-12-31]
+ test: [2017-01-01, 2020-08-01]
+ record:
+ - class: SignalRecord
+ module_path: qlib.workflow.record_temp
+ kwargs: {}
+ - class: SignalMseRecord
+ module_path: qlib.contrib.workflow.record_temp
+ kwargs: {}
+ - class: SigAnaRecord
+ module_path: qlib.workflow.record_temp
+ kwargs:
+ ana_long_short: False
+ ann_scaler: 252
+ - class: PortAnaRecord
+ module_path: qlib.workflow.record_temp
+ kwargs:
+ config: *port_analysis_config
diff --git a/AutoDL-Projects/configs/qlib/workflow_config_naive_v1_Alpha360.yaml b/AutoDL-Projects/configs/qlib/workflow_config_naive_v1_Alpha360.yaml
new file mode 100644
index 0000000..47414d6
--- /dev/null
+++ b/AutoDL-Projects/configs/qlib/workflow_config_naive_v1_Alpha360.yaml
@@ -0,0 +1,64 @@
+qlib_init:
+ provider_uri: "~/.qlib/qlib_data/cn_data"
+ region: cn
+market: &market all
+benchmark: &benchmark SH000300
+data_handler_config: &data_handler_config
+ start_time: 2008-01-01
+ end_time: 2020-08-01
+ fit_start_time: 2008-01-01
+ fit_end_time: 2014-12-31
+ instruments: *market
+ infer_processors: []
+ learn_processors: []
+ label: ["Ref($close, -2) / Ref($close, -1) - 1"]
+port_analysis_config: &port_analysis_config
+ strategy:
+ class: TopkDropoutStrategy
+ module_path: qlib.contrib.strategy.strategy
+ kwargs:
+ topk: 50
+ n_drop: 5
+ backtest:
+ verbose: False
+ limit_threshold: 0.095
+ account: 100000000
+ benchmark: *benchmark
+ deal_price: close
+ open_cost: 0.0005
+ close_cost: 0.0015
+ min_cost: 5
+task:
+ model:
+ class: NAIVE_V1
+ module_path: trade_models.naive_v1_model
+ kwargs:
+ d_feat: 6
+ dataset:
+ class: DatasetH
+ module_path: qlib.data.dataset
+ kwargs:
+ handler:
+ class: Alpha360
+ module_path: qlib.contrib.data.handler
+ kwargs: *data_handler_config
+ segments:
+ train: [2008-01-01, 2014-12-31]
+ valid: [2015-01-01, 2016-12-31]
+ test: [2017-01-01, 2020-08-01]
+ record:
+ - class: SignalRecord
+ module_path: qlib.workflow.record_temp
+ kwargs: {}
+ - class: SignalMseRecord
+ module_path: qlib.contrib.workflow.record_temp
+ kwargs: {}
+ - class: SigAnaRecord
+ module_path: qlib.workflow.record_temp
+ kwargs:
+ ana_long_short: False
+ ann_scaler: 252
+ - class: PortAnaRecord
+ module_path: qlib.workflow.record_temp
+ kwargs:
+ config: *port_analysis_config
diff --git a/AutoDL-Projects/configs/qlib/workflow_config_naive_v2_Alpha360.yaml b/AutoDL-Projects/configs/qlib/workflow_config_naive_v2_Alpha360.yaml
new file mode 100644
index 0000000..db2bf40
--- /dev/null
+++ b/AutoDL-Projects/configs/qlib/workflow_config_naive_v2_Alpha360.yaml
@@ -0,0 +1,64 @@
+qlib_init:
+ provider_uri: "~/.qlib/qlib_data/cn_data"
+ region: cn
+market: &market all
+benchmark: &benchmark SH000300
+data_handler_config: &data_handler_config
+ start_time: 2008-01-01
+ end_time: 2020-08-01
+ fit_start_time: 2008-01-01
+ fit_end_time: 2014-12-31
+ instruments: *market
+ infer_processors: []
+ learn_processors: []
+ label: ["Ref($close, -2) / Ref($close, -1) - 1"]
+port_analysis_config: &port_analysis_config
+ strategy:
+ class: TopkDropoutStrategy
+ module_path: qlib.contrib.strategy.strategy
+ kwargs:
+ topk: 50
+ n_drop: 5
+ backtest:
+ verbose: False
+ limit_threshold: 0.095
+ account: 100000000
+ benchmark: *benchmark
+ deal_price: close
+ open_cost: 0.0005
+ close_cost: 0.0015
+ min_cost: 5
+task:
+ model:
+ class: NAIVE_V2
+ module_path: trade_models.naive_v2_model
+ kwargs:
+ d_feat: 6
+ dataset:
+ class: DatasetH
+ module_path: qlib.data.dataset
+ kwargs:
+ handler:
+ class: Alpha360
+ module_path: qlib.contrib.data.handler
+ kwargs: *data_handler_config
+ segments:
+ train: [2008-01-01, 2014-12-31]
+ valid: [2015-01-01, 2016-12-31]
+ test: [2017-01-01, 2020-08-01]
+ record:
+ - class: SignalRecord
+ module_path: qlib.workflow.record_temp
+ kwargs: {}
+ - class: SignalMseRecord
+ module_path: qlib.contrib.workflow.record_temp
+ kwargs: {}
+ - class: SigAnaRecord
+ module_path: qlib.workflow.record_temp
+ kwargs:
+ ana_long_short: False
+ ann_scaler: 252
+ - class: PortAnaRecord
+ module_path: qlib.workflow.record_temp
+ kwargs:
+ config: *port_analysis_config
diff --git a/AutoDL-Projects/configs/qlib/workflow_config_sfm_Alpha360.yaml b/AutoDL-Projects/configs/qlib/workflow_config_sfm_Alpha360.yaml
new file mode 100644
index 0000000..41abc06
--- /dev/null
+++ b/AutoDL-Projects/configs/qlib/workflow_config_sfm_Alpha360.yaml
@@ -0,0 +1,88 @@
+qlib_init:
+ provider_uri: "~/.qlib/qlib_data/cn_data"
+ region: cn
+market: &market all
+benchmark: &benchmark SH000300
+data_handler_config: &data_handler_config
+ start_time: 2008-01-01
+ end_time: 2020-08-01
+ fit_start_time: 2008-01-01
+ fit_end_time: 2014-12-31
+ instruments: *market
+ infer_processors:
+ - class: RobustZScoreNorm
+ kwargs:
+ fields_group: feature
+ clip_outlier: true
+ - class: Fillna
+ kwargs:
+ fields_group: feature
+ learn_processors:
+ - class: DropnaLabel
+ - class: CSRankNorm
+ kwargs:
+ fields_group: label
+ label: ["Ref($close, -2) / Ref($close, -1) - 1"]
+port_analysis_config: &port_analysis_config
+ strategy:
+ class: TopkDropoutStrategy
+ module_path: qlib.contrib.strategy.strategy
+ kwargs:
+ topk: 50
+ n_drop: 5
+ backtest:
+ verbose: False
+ limit_threshold: 0.095
+ account: 100000000
+ benchmark: *benchmark
+ deal_price: close
+ open_cost: 0.0005
+ close_cost: 0.0015
+ min_cost: 5
+task:
+ model:
+ class: SFM
+ module_path: qlib.contrib.model.pytorch_sfm
+ kwargs:
+ d_feat: 6
+ hidden_size: 64
+ output_dim: 32
+ freq_dim: 25
+ dropout_W: 0.5
+ dropout_U: 0.5
+ n_epochs: 20
+ lr: 1e-3
+ batch_size: 1600
+ early_stop: 20
+ eval_steps: 5
+ loss: mse
+ optimizer: adam
+ GPU: 0
+ dataset:
+ class: DatasetH
+ module_path: qlib.data.dataset
+ kwargs:
+ handler:
+ class: Alpha360
+ module_path: qlib.contrib.data.handler
+ kwargs: *data_handler_config
+ segments:
+ train: [2008-01-01, 2014-12-31]
+ valid: [2015-01-01, 2016-12-31]
+ test: [2017-01-01, 2020-08-01]
+ record:
+ - class: SignalRecord
+ module_path: qlib.workflow.record_temp
+ kwargs: {}
+ - class: SignalMseRecord
+ module_path: qlib.contrib.workflow.record_temp
+ kwargs: {}
+ - class: SigAnaRecord
+ module_path: qlib.workflow.record_temp
+ kwargs:
+ ana_long_short: False
+ ann_scaler: 252
+ - class: PortAnaRecord
+ module_path: qlib.workflow.record_temp
+ kwargs:
+ config: *port_analysis_config
diff --git a/AutoDL-Projects/configs/qlib/workflow_config_transformer_Alpha360.yaml b/AutoDL-Projects/configs/qlib/workflow_config_transformer_Alpha360.yaml
new file mode 100644
index 0000000..36a3c28
--- /dev/null
+++ b/AutoDL-Projects/configs/qlib/workflow_config_transformer_Alpha360.yaml
@@ -0,0 +1,78 @@
+qlib_init:
+ provider_uri: "~/.qlib/qlib_data/cn_data"
+ region: cn
+market: &market all
+benchmark: &benchmark SH000300
+data_handler_config: &data_handler_config
+ start_time: 2008-01-01
+ end_time: 2020-08-01
+ fit_start_time: 2008-01-01
+ fit_end_time: 2014-12-31
+ instruments: *market
+ infer_processors:
+ - class: RobustZScoreNorm
+ kwargs:
+ fields_group: feature
+ clip_outlier: true
+ - class: Fillna
+ kwargs:
+ fields_group: feature
+ learn_processors:
+ - class: DropnaLabel
+ - class: CSRankNorm
+ kwargs:
+ fields_group: label
+ label: ["Ref($close, -2) / Ref($close, -1) - 1"]
+port_analysis_config: &port_analysis_config
+ strategy:
+ class: TopkDropoutStrategy
+ module_path: qlib.contrib.strategy.strategy
+ kwargs:
+ topk: 50
+ n_drop: 5
+ backtest:
+ verbose: False
+ limit_threshold: 0.095
+ account: 100000000
+ benchmark: *benchmark
+ deal_price: close
+ open_cost: 0.0005
+ close_cost: 0.0015
+ min_cost: 5
+task:
+ model:
+ class: QuantTransformer
+ module_path: trade_models.quant_transformer
+ kwargs:
+ net_config:
+ opt_config:
+ loss: mse
+ GPU: 0
+ dataset:
+ class: DatasetH
+ module_path: qlib.data.dataset
+ kwargs:
+ handler:
+ class: Alpha360
+ module_path: qlib.contrib.data.handler
+ kwargs: *data_handler_config
+ segments:
+ train: [2008-01-01, 2014-12-31]
+ valid: [2015-01-01, 2016-12-31]
+ test: [2017-01-01, 2020-08-01]
+ record:
+ - class: SignalRecord
+ module_path: qlib.workflow.record_temp
+ kwargs: {}
+ - class: SignalMseRecord
+ module_path: qlib.contrib.workflow.record_temp
+ kwargs: {}
+ - class: SigAnaRecord
+ module_path: qlib.workflow.record_temp
+ kwargs:
+ ana_long_short: False
+ ann_scaler: 252
+ - class: PortAnaRecord
+ module_path: qlib.workflow.record_temp
+ kwargs:
+ config: *port_analysis_config
diff --git a/AutoDL-Projects/configs/qlib/workflow_config_transformer_basic_Alpha360.yaml b/AutoDL-Projects/configs/qlib/workflow_config_transformer_basic_Alpha360.yaml
new file mode 100644
index 0000000..f651c44
--- /dev/null
+++ b/AutoDL-Projects/configs/qlib/workflow_config_transformer_basic_Alpha360.yaml
@@ -0,0 +1,86 @@
+qlib_init:
+ provider_uri: "~/.qlib/qlib_data/cn_data"
+ region: cn
+market: &market all
+benchmark: &benchmark SH000300
+data_handler_config: &data_handler_config
+ start_time: 2008-01-01
+ end_time: 2020-08-01
+ fit_start_time: 2008-01-01
+ fit_end_time: 2014-12-31
+ instruments: *market
+ infer_processors:
+ - class: RobustZScoreNorm
+ kwargs:
+ fields_group: feature
+ clip_outlier: true
+ - class: Fillna
+ kwargs:
+ fields_group: feature
+ learn_processors:
+ - class: DropnaLabel
+ - class: CSRankNorm
+ kwargs:
+ fields_group: label
+ label: ["Ref($close, -2) / Ref($close, -1) - 1"]
+port_analysis_config: &port_analysis_config
+ strategy:
+ class: TopkDropoutStrategy
+ module_path: qlib.contrib.strategy.strategy
+ kwargs:
+ topk: 50
+ n_drop: 5
+ backtest:
+ verbose: False
+ limit_threshold: 0.095
+ account: 100000000
+ benchmark: *benchmark
+ deal_price: close
+ open_cost: 0.0005
+ close_cost: 0.0015
+ min_cost: 5
+task:
+ model:
+ class: QuantTransformer
+ module_path: trade_models.quant_transformer
+ kwargs:
+ net_config:
+ name: basic
+ d_feat: 6
+ embed_dim: 32
+ num_heads: [4, 4, 4, 4, 4]
+ mlp_hidden_multipliers: [4, 4, 4, 4, 4]
+ qkv_bias: True
+ pos_drop: 0.1
+ other_drop: 0
+ opt_config:
+ loss: mse
+ GPU: 0
+ dataset:
+ class: DatasetH
+ module_path: qlib.data.dataset
+ kwargs:
+ handler:
+ class: Alpha360
+ module_path: qlib.contrib.data.handler
+ kwargs: *data_handler_config
+ segments:
+ train: [2008-01-01, 2014-12-31]
+ valid: [2015-01-01, 2016-12-31]
+ test: [2017-01-01, 2020-08-01]
+ record:
+ - class: SignalRecord
+ module_path: qlib.workflow.record_temp
+ kwargs: {}
+ - class: SignalMseRecord
+ module_path: qlib.contrib.workflow.record_temp
+ kwargs: {}
+ - class: SigAnaRecord
+ module_path: qlib.workflow.record_temp
+ kwargs:
+ ana_long_short: False
+ ann_scaler: 252
+ - class: PortAnaRecord
+ module_path: qlib.workflow.record_temp
+ kwargs:
+ config: *port_analysis_config
diff --git a/AutoDL-Projects/configs/qlib/workflow_config_xgboost_Alpha360.yaml b/AutoDL-Projects/configs/qlib/workflow_config_xgboost_Alpha360.yaml
new file mode 100644
index 0000000..2fa21f3
--- /dev/null
+++ b/AutoDL-Projects/configs/qlib/workflow_config_xgboost_Alpha360.yaml
@@ -0,0 +1,81 @@
+qlib_init:
+ provider_uri: "~/.qlib/qlib_data/cn_data"
+ region: cn
+market: &market all
+benchmark: &benchmark SH000300
+data_handler_config: &data_handler_config
+ start_time: 2008-01-01
+ end_time: 2020-08-01
+ fit_start_time: 2008-01-01
+ fit_end_time: 2014-12-31
+ instruments: *market
+ infer_processors:
+ - class: RobustZScoreNorm
+ kwargs:
+ fields_group: feature
+ clip_outlier: true
+ - class: Fillna
+ kwargs:
+ fields_group: feature
+ learn_processors:
+ - class: DropnaLabel
+ - class: CSRankNorm
+ kwargs:
+ fields_group: label
+ label: ["Ref($close, -2) / Ref($close, -1) - 1"]
+port_analysis_config: &port_analysis_config
+ strategy:
+ class: TopkDropoutStrategy
+ module_path: qlib.contrib.strategy.strategy
+ kwargs:
+ topk: 50
+ n_drop: 5
+ backtest:
+ verbose: False
+ limit_threshold: 0.095
+ account: 100000000
+ benchmark: *benchmark
+ deal_price: close
+ open_cost: 0.0005
+ close_cost: 0.0015
+ min_cost: 5
+task:
+ model:
+ class: XGBModel
+ module_path: qlib.contrib.model.xgboost
+ kwargs:
+ eval_metric: rmse
+ colsample_bytree: 0.8879
+ eta: 0.0421
+ max_depth: 8
+ n_estimators: 647
+ subsample: 0.8789
+ nthread: 20
+ dataset:
+ class: DatasetH
+ module_path: qlib.data.dataset
+ kwargs:
+ handler:
+ class: Alpha360
+ module_path: qlib.contrib.data.handler
+ kwargs: *data_handler_config
+ segments:
+ train: [2008-01-01, 2014-12-31]
+ valid: [2015-01-01, 2016-12-31]
+ test: [2017-01-01, 2020-08-01]
+ record:
+ - class: SignalRecord
+ module_path: qlib.workflow.record_temp
+ kwargs: {}
+ - class: SignalMseRecord
+ module_path: qlib.contrib.workflow.record_temp
+ kwargs: {}
+ - class: SigAnaRecord
+ module_path: qlib.workflow.record_temp
+ kwargs:
+ ana_long_short: False
+ ann_scaler: 252
+ - class: PortAnaRecord
+ module_path: qlib.workflow.record_temp
+ kwargs:
+ config: *port_analysis_config
diff --git a/AutoDL-Projects/configs/search-KD-opts/ImageNet-E120-Cos-Soft.config b/AutoDL-Projects/configs/search-KD-opts/ImageNet-E120-Cos-Soft.config
new file mode 100644
index 0000000..e1d97e8
--- /dev/null
+++ b/AutoDL-Projects/configs/search-KD-opts/ImageNet-E120-Cos-Soft.config
@@ -0,0 +1,14 @@
+{
+ "scheduler": ["str", "cos"],
+ "eta_min" : ["float", "0.0"],
+ "epochs" : ["int", "125"],
+ "T_max" : ["int", "120"],
+ "warmup" : ["int", "5"],
+ "optim" : ["str", "SGD"],
+ "LR" : ["float", "0.1"],
+ "decay" : ["float", "0.0001"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "1"],
+ "criterion": ["str", "Softmax"],
+ "auxiliary": ["float", "-1"]
+}
diff --git a/AutoDL-Projects/configs/search-KD-opts/ImageNet-E150-MobileFast.config b/AutoDL-Projects/configs/search-KD-opts/ImageNet-E150-MobileFast.config
new file mode 100644
index 0000000..bef4d7d
--- /dev/null
+++ b/AutoDL-Projects/configs/search-KD-opts/ImageNet-E150-MobileFast.config
@@ -0,0 +1,15 @@
+{
+ "scheduler": ["str", "cos"],
+ "eta_min" : ["float", "0.0"],
+ "epochs" : ["int", "155"],
+ "T_max" : ["int", "150"],
+ "warmup" : ["int", "0"],
+ "gamma" : ["float", "0.98"],
+ "optim" : ["str", "SGD"],
+ "LR" : ["float", "0.05"],
+ "decay" : ["float", "0.00004"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "0"],
+ "criterion": ["str", "Softmax"],
+ "auxiliary": ["float", "-1"]
+}
diff --git a/AutoDL-Projects/configs/search-archs/DARTS-NASNet-CIFAR.config b/AutoDL-Projects/configs/search-archs/DARTS-NASNet-CIFAR.config
new file mode 100644
index 0000000..270fca3
--- /dev/null
+++ b/AutoDL-Projects/configs/search-archs/DARTS-NASNet-CIFAR.config
@@ -0,0 +1,9 @@
+{
+ "super_type" : ["str", "nasnet-super"],
+ "name" : ["str", "DARTS"],
+ "C" : ["int", "16" ],
+ "N" : ["int", "2" ],
+ "steps" : ["int", "4" ],
+ "multiplier" : ["int", "4" ],
+ "stem_multiplier" : ["int", "3" ]
+}
diff --git a/AutoDL-Projects/configs/search-archs/GDAS-NASNet-CIFAR.config b/AutoDL-Projects/configs/search-archs/GDAS-NASNet-CIFAR.config
new file mode 100644
index 0000000..2465dd6
--- /dev/null
+++ b/AutoDL-Projects/configs/search-archs/GDAS-NASNet-CIFAR.config
@@ -0,0 +1,9 @@
+{
+ "super_type" : ["str", "nasnet-super"],
+ "name" : ["str", "GDAS"],
+ "C" : ["int", "16" ],
+ "N" : ["int", "2" ],
+ "steps" : ["int", "4" ],
+ "multiplier" : ["int", "4" ],
+ "stem_multiplier" : ["int", "3" ]
+}
diff --git a/AutoDL-Projects/configs/search-archs/GDASFRC-NASNet-CIFAR.config b/AutoDL-Projects/configs/search-archs/GDASFRC-NASNet-CIFAR.config
new file mode 100644
index 0000000..9ddb9ae
--- /dev/null
+++ b/AutoDL-Projects/configs/search-archs/GDASFRC-NASNet-CIFAR.config
@@ -0,0 +1,9 @@
+{
+ "super_type" : ["str", "nasnet-super"],
+ "name" : ["str", "GDAS_FRC"],
+ "C" : ["int", "16" ],
+ "N" : ["int", "2" ],
+ "steps" : ["int", "4" ],
+ "multiplier" : ["int", "4" ],
+ "stem_multiplier" : ["int", "3" ]
+}
diff --git a/AutoDL-Projects/configs/search-archs/ImageNet-MobileNetV2-X.config b/AutoDL-Projects/configs/search-archs/ImageNet-MobileNetV2-X.config
new file mode 100644
index 0000000..4bce4f1
--- /dev/null
+++ b/AutoDL-Projects/configs/search-archs/ImageNet-MobileNetV2-X.config
@@ -0,0 +1,9 @@
+{
+ "dataset" : ["str", "imagenet"],
+ "arch" : ["str", "MobileNetV2"],
+ "width_mult" : ["float", 1.0],
+ "dropout" : ["float", 0.0],
+ "input_channel" : ["int", 32],
+ "last_channel" : ["int", 1280],
+ "block_name" : ["str", "InvertedResidual"]
+}
diff --git a/AutoDL-Projects/configs/search-archs/ImageNet-ResNet18V1.config b/AutoDL-Projects/configs/search-archs/ImageNet-ResNet18V1.config
new file mode 100644
index 0000000..11c7851
--- /dev/null
+++ b/AutoDL-Projects/configs/search-archs/ImageNet-ResNet18V1.config
@@ -0,0 +1,8 @@
+{
+ "dataset" : ["str", "imagenet"],
+ "arch" : ["str", "resnet"],
+ "block_name" : ["str", "BasicBlock"],
+ "layers" : ["int", [2,2,2,2]],
+ "deep_stem" : ["bool", 0],
+ "zero_init_residual" : ["bool", "1"]
+}
diff --git a/AutoDL-Projects/configs/search-archs/ImageNet-ResNet34V1.config b/AutoDL-Projects/configs/search-archs/ImageNet-ResNet34V1.config
new file mode 100644
index 0000000..cc916bb
--- /dev/null
+++ b/AutoDL-Projects/configs/search-archs/ImageNet-ResNet34V1.config
@@ -0,0 +1,8 @@
+{
+ "dataset" : ["str", "imagenet"],
+ "arch" : ["str", "resnet"],
+ "block_name" : ["str", "BasicBlock"],
+ "layers" : ["int", [3,4,6,3]],
+ "deep_stem" : ["bool", 0],
+ "zero_init_residual" : ["bool", "1"]
+}
diff --git a/AutoDL-Projects/configs/search-archs/ImageNet-ResNet50V1.config b/AutoDL-Projects/configs/search-archs/ImageNet-ResNet50V1.config
new file mode 100644
index 0000000..2de4d13
--- /dev/null
+++ b/AutoDL-Projects/configs/search-archs/ImageNet-ResNet50V1.config
@@ -0,0 +1,8 @@
+{
+ "dataset" : ["str", "imagenet"],
+ "arch" : ["str", "resnet"],
+ "block_name" : ["str", "Bottleneck"],
+ "layers" : ["int", [3,4,6,3]],
+ "deep_stem" : ["bool", 0],
+ "zero_init_residual" : ["bool", "1"]
+}
diff --git a/AutoDL-Projects/configs/search-opts/CIFAR.config b/AutoDL-Projects/configs/search-opts/CIFAR.config
new file mode 100644
index 0000000..fc5400f
--- /dev/null
+++ b/AutoDL-Projects/configs/search-opts/CIFAR.config
@@ -0,0 +1,14 @@
+{
+ "scheduler": ["str", "cos"],
+ "eta_min" : ["float", "0.0"],
+ "epochs" : ["int", "300"],
+ "warmup" : ["int", "5"],
+ "optim" : ["str", "SGD"],
+ "LR" : ["float", "0.1"],
+ "decay" : ["float", "0.0005"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "1"],
+ "criterion": ["str", "Softmax"],
+ "arch_LR" : ["float", "0.001"],
+ "arch_decay" : ["float", "0.001"]
+}
diff --git a/AutoDL-Projects/configs/search-opts/CIFARX.config b/AutoDL-Projects/configs/search-opts/CIFARX.config
new file mode 100644
index 0000000..24cf82d
--- /dev/null
+++ b/AutoDL-Projects/configs/search-opts/CIFARX.config
@@ -0,0 +1,14 @@
+{
+ "scheduler": ["str", "cos"],
+ "eta_min" : ["float", "0.0"],
+ "epochs" : ["int", "600"],
+ "warmup" : ["int", "0"],
+ "optim" : ["str", "SGD"],
+ "LR" : ["float", "0.1"],
+ "decay" : ["float", "0.0005"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "1"],
+ "criterion": ["str", "Softmax"],
+ "arch_LR" : ["float", "0.001"],
+ "arch_decay" : ["float", "0.001"]
+}
diff --git a/AutoDL-Projects/configs/search-opts/CIFARXX.config b/AutoDL-Projects/configs/search-opts/CIFARXX.config
new file mode 100644
index 0000000..fe3eec9
--- /dev/null
+++ b/AutoDL-Projects/configs/search-opts/CIFARXX.config
@@ -0,0 +1,14 @@
+{
+ "scheduler": ["str", "cos"],
+ "eta_min" : ["float", "0.0"],
+ "epochs" : ["int", "900"],
+ "warmup" : ["int", "5"],
+ "optim" : ["str", "SGD"],
+ "LR" : ["float", "0.1"],
+ "decay" : ["float", "0.0005"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "1"],
+ "criterion": ["str", "Softmax"],
+ "arch_LR" : ["float", "0.001"],
+ "arch_decay" : ["float", "0.001"]
+}
diff --git a/AutoDL-Projects/configs/search-opts/DARTS-NASNet-CIFAR.config b/AutoDL-Projects/configs/search-opts/DARTS-NASNet-CIFAR.config
new file mode 100644
index 0000000..a795505
--- /dev/null
+++ b/AutoDL-Projects/configs/search-opts/DARTS-NASNet-CIFAR.config
@@ -0,0 +1,13 @@
+{
+ "scheduler": ["str", "cos"],
+ "LR" : ["float", "0.025"],
+ "eta_min" : ["float", "0.001"],
+ "epochs" : ["int", "50"],
+ "warmup" : ["int", "0"],
+ "optim" : ["str", "SGD"],
+ "decay" : ["float", "0.0003"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "1"],
+ "criterion": ["str", "Softmax"],
+ "batch_size": ["int", "64"]
+}
diff --git a/AutoDL-Projects/configs/search-opts/GDAS-NASNet-CIFAR.config b/AutoDL-Projects/configs/search-opts/GDAS-NASNet-CIFAR.config
new file mode 100644
index 0000000..85130a8
--- /dev/null
+++ b/AutoDL-Projects/configs/search-opts/GDAS-NASNet-CIFAR.config
@@ -0,0 +1,13 @@
+{
+ "scheduler": ["str", "cos"],
+ "LR" : ["float", "0.025"],
+ "eta_min" : ["float", "0.001"],
+ "epochs" : ["int", "250"],
+ "warmup" : ["int", "0"],
+ "optim" : ["str", "SGD"],
+ "decay" : ["float", "0.0005"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "1"],
+ "criterion": ["str", "Softmax"],
+ "batch_size": ["int", "256"]
+}
diff --git a/AutoDL-Projects/configs/search-opts/ImageNet-MobileFast.config b/AutoDL-Projects/configs/search-opts/ImageNet-MobileFast.config
new file mode 100644
index 0000000..8d749e5
--- /dev/null
+++ b/AutoDL-Projects/configs/search-opts/ImageNet-MobileFast.config
@@ -0,0 +1,15 @@
+{
+ "scheduler": ["str", "cos"],
+ "eta_min" : ["float", "0.0"],
+ "epochs" : ["int", "150"],
+ "warmup" : ["int", "0"],
+ "gamma" : ["float", "0.98"],
+ "optim" : ["str", "SGD"],
+ "LR" : ["float", "0.05"],
+ "decay" : ["float", "0.00004"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "0"],
+ "criterion": ["str", "Softmax"],
+ "arch_LR" : ["float", "0.001"],
+ "arch_decay" : ["float", "0.001"]
+}
diff --git a/AutoDL-Projects/configs/search-opts/ImageNet-ResNet.config b/AutoDL-Projects/configs/search-opts/ImageNet-ResNet.config
new file mode 100644
index 0000000..d71d079
--- /dev/null
+++ b/AutoDL-Projects/configs/search-opts/ImageNet-ResNet.config
@@ -0,0 +1,14 @@
+{
+ "scheduler": ["str", "cos"],
+ "eta_min" : ["float", "0.0"],
+ "epochs" : ["int", "115"],
+ "warmup" : ["int", "5"],
+ "optim" : ["str", "SGD"],
+ "LR" : ["float", "0.1"],
+ "decay" : ["float", "0.0001"],
+ "momentum" : ["float", "0.9"],
+ "nesterov" : ["bool", "1"],
+ "criterion": ["str", "Softmax"],
+ "arch_LR" : ["float", "0.001"],
+ "arch_decay" : ["float", "0.001"]
+}
diff --git a/AutoDL-Projects/configs/temps/T-MobileNetV2-X.config b/AutoDL-Projects/configs/temps/T-MobileNetV2-X.config
new file mode 100644
index 0000000..98462f0
--- /dev/null
+++ b/AutoDL-Projects/configs/temps/T-MobileNetV2-X.config
@@ -0,0 +1,8 @@
+{
+ "dataset" : ["str", "imagenet"],
+ "arch" : ["str", "MobileNetV2"],
+ "dropout" : ["float", 0.0],
+ "super_type" : ["str", "infer-shape"],
+ "xchannels" : ["str", "3-32 32-16 16-96-24 24-86-24 24-86-32 32-96-32 32-77-32 32-77-32 32-231-48 48-269-48 48-269-64 64-269-64 64-192-67 67-246-77 77-288-96 96-346-96 96-576-160 160-480-128 128-576-320 320-768"],
+ "xblocks" : ["int", [1, 2, 3, 3, 3, 3, 1]]
+}
diff --git a/AutoDL-Projects/configs/temps/T-ResNet18.config b/AutoDL-Projects/configs/temps/T-ResNet18.config
new file mode 100644
index 0000000..e69ab34
--- /dev/null
+++ b/AutoDL-Projects/configs/temps/T-ResNet18.config
@@ -0,0 +1,14 @@
+{
+ "dataset" : ["str" , "imagenet"],
+ "arch" : ["str" , "resnet"],
+ "block_name" : ["str" , "BasicBlock"],
+ "layers" : ["int" , ["2", "2", "2", "2"]],
+ "deep_stem" : ["bool" , "0"],
+ "class_num" : ["int" , "1000"],
+ "search_mode" : ["str" , "shape"],
+ "xchannels" : ["int" , ["3", "48", "64", "38", "25", "57", "102", "89", "102", "115", "128", "230", "230", "256", "153", "358", "358", "460"]],
+ "xblocks" : ["int" , ["2", "2", "2", "2"]],
+ "super_type" : ["str" , "infer-shape"],
+ "estimated_FLOP" : ["float" , "953.381522"],
+ "zero_init_residual" : ["bool" , "1"]
+}
diff --git a/AutoDL-Projects/configs/temps/T-ResNet50.config b/AutoDL-Projects/configs/temps/T-ResNet50.config
new file mode 100644
index 0000000..2d04b7d
--- /dev/null
+++ b/AutoDL-Projects/configs/temps/T-ResNet50.config
@@ -0,0 +1,14 @@
+{
+ "dataset" : ["str" , "imagenet"],
+ "arch" : ["str" , "resnet"],
+ "block_name" : ["str" , "Bottleneck"],
+ "layers" : ["int" , ["3", "4", "6", "3"]],
+ "deep_stem" : ["bool" , "0"],
+ "zero_init_residual" : ["bool" , "1"],
+ "class_num" : ["int" , "1000"],
+ "search_mode" : ["str" , "shape"],
+ "xchannels" : ["int" , ["3", "45", "45", "30", "102", "33", "60", "154", "68", "70", "180", "38", "38", "307", "38", "38", "410", "64", "128", "358", "38", "51", "256", "76", "76", "512", "76", "76", "512", "179", "256", "614", "100", "102", "307", "179", "230", "614", "204", "102", "307", "153", "153", "1228", "512", "512", "1434", "512", "512", "1844"]],
+ "xblocks" : ["int" , ["3", "4", "5", "3"]],
+ "super_type" : ["str" , "infer-shape"],
+ "estimated_FLOP" : ["float" , "2291.316289"]
+}
diff --git a/AutoDL-Projects/configs/temps/X-ResNet18.config b/AutoDL-Projects/configs/temps/X-ResNet18.config
new file mode 100644
index 0000000..9a0ab7d
--- /dev/null
+++ b/AutoDL-Projects/configs/temps/X-ResNet18.config
@@ -0,0 +1,14 @@
+{
+ "dataset" : ["str" , "imagenet"],
+ "arch" : ["str" , "resnet"],
+ "block_name" : ["str" , "BasicBlock"],
+ "layers" : ["int" , ["2", "2", "2", "2"]],
+ "deep_stem" : ["bool" , "0"],
+ "zero_init_residual" : ["bool" , "1"],
+ "class_num" : ["int" , "1000"],
+ "search_mode" : ["str" , "shape"],
+ "xchannels" : ["int" , ["3", "64", "25", "64", "38", "19", "128", "128", "38", "38", "256", "256", "256", "256", "512", "512", "512", "512"]],
+ "xblocks" : ["int" , ["1", "1", "2", "2"]],
+ "super_type" : ["str" , "infer-shape"],
+ "estimated_FLOP" : ["float" , "1120.44032"]
+}
\ No newline at end of file
diff --git a/AutoDL-Projects/configs/temps/X-ResNet50.config b/AutoDL-Projects/configs/temps/X-ResNet50.config
new file mode 100644
index 0000000..4c746e7
--- /dev/null
+++ b/AutoDL-Projects/configs/temps/X-ResNet50.config
@@ -0,0 +1,14 @@
+{
+ "dataset" : ["str" , "imagenet"],
+ "arch" : ["str" , "resnet"],
+ "block_name" : ["str" , "Bottleneck"],
+ "layers" : ["int" , ["3", "4", "6", "3"]],
+ "deep_stem" : ["bool" , "0"],
+ "zero_init_residual" : ["bool" , "1"],
+ "class_num" : ["int" , "1000"],
+ "search_mode" : ["str" , "shape"],
+ "xchannels" : ["int" , ["3", "64", "64", "64", "230", "25", "19", "128", "19", "38", "76", "128", "128", "512", "38", "38", "204", "38", "51", "256", "51", "51", "153", "256", "256", "1024", "256", "256", "1024", "256", "256", "921", "256", "256", "1024", "76", "76", "614", "102", "76", "307", "512", "512", "2048", "512", "512", "2048", "512", "512", "2048"]],
+ "xblocks" : ["int" , ["1", "1", "2", "3"]],
+ "super_type" : ["str" , "infer-shape"],
+ "estimated_FLOP" : ["float" , "1680.93696"]
+}
\ No newline at end of file
diff --git a/AutoDL-Projects/configs/yaml.data/cifar10.test b/AutoDL-Projects/configs/yaml.data/cifar10.test
new file mode 100644
index 0000000..5882a19
--- /dev/null
+++ b/AutoDL-Projects/configs/yaml.data/cifar10.test
@@ -0,0 +1,22 @@
+class_or_func: CIFAR10
+module_path: torchvision.datasets
+args: []
+kwargs:
+ train: False
+ download: True
+ transform:
+ class_or_func: Compose
+ module_path: torchvision.transforms
+ args:
+ -
+ - class_or_func: ToTensor
+ module_path: torchvision.transforms
+ args: []
+ kwargs: {}
+ - class_or_func: Normalize
+ module_path: torchvision.transforms
+ args: []
+ kwargs:
+ mean: [0.491, 0.482, 0.447]
+ std: [0.247, 0.244, 0.262]
+ kwargs: {}
diff --git a/AutoDL-Projects/configs/yaml.data/cifar10.train b/AutoDL-Projects/configs/yaml.data/cifar10.train
new file mode 100644
index 0000000..1dbb1ac
--- /dev/null
+++ b/AutoDL-Projects/configs/yaml.data/cifar10.train
@@ -0,0 +1,30 @@
+class_or_func: CIFAR10
+module_path: torchvision.datasets
+args: []
+kwargs:
+ train: True
+ download: True
+ transform:
+ class_or_func: Compose
+ module_path: torchvision.transforms
+ args:
+ -
+ - class_or_func: RandomHorizontalFlip
+ module_path: torchvision.transforms
+ args: []
+ kwargs: {}
+ - class_or_func: RandomCrop
+ module_path: torchvision.transforms
+ args: [32]
+ kwargs: {padding: 4}
+ - class_or_func: ToTensor
+ module_path: torchvision.transforms
+ args: []
+ kwargs: {}
+ - class_or_func: Normalize
+ module_path: torchvision.transforms
+ args: []
+ kwargs:
+ mean: [0.491, 0.482, 0.447]
+ std: [0.247, 0.244, 0.262]
+ kwargs: {}
diff --git a/AutoDL-Projects/configs/yaml.loss/cross-entropy b/AutoDL-Projects/configs/yaml.loss/cross-entropy
new file mode 100644
index 0000000..7c86921
--- /dev/null
+++ b/AutoDL-Projects/configs/yaml.loss/cross-entropy
@@ -0,0 +1,4 @@
+class_or_func: CrossEntropyLoss
+module_path: torch.nn
+args: []
+kwargs: {}
diff --git a/AutoDL-Projects/configs/yaml.loss/top1-ce b/AutoDL-Projects/configs/yaml.loss/top1-ce
new file mode 100644
index 0000000..f82f7b3
--- /dev/null
+++ b/AutoDL-Projects/configs/yaml.loss/top1-ce
@@ -0,0 +1,12 @@
+class_or_func: ComposeMetric
+module_path: xautodl.xmisc.meter_utils
+args:
+ - class_or_func: Top1AccMetric
+ module_path: xautodl.xmisc.meter_utils
+ args: [False]
+ kwargs: {}
+ - class_or_func: CrossEntropyMetric
+ module_path: xautodl.xmisc.meter_utils
+ args: [False]
+ kwargs: {}
+kwargs: {}
diff --git a/AutoDL-Projects/configs/yaml.loss/top1.acc b/AutoDL-Projects/configs/yaml.loss/top1.acc
new file mode 100644
index 0000000..aae4d60
--- /dev/null
+++ b/AutoDL-Projects/configs/yaml.loss/top1.acc
@@ -0,0 +1,4 @@
+class_or_func: Top1AccMetric
+module_path: xautodl.xmisc.meter_utils
+args: [False]
+kwargs: {}
diff --git a/AutoDL-Projects/configs/yaml.model/vit-cifar10.s0 b/AutoDL-Projects/configs/yaml.model/vit-cifar10.s0
new file mode 100644
index 0000000..b88fafa
--- /dev/null
+++ b/AutoDL-Projects/configs/yaml.model/vit-cifar10.s0
@@ -0,0 +1,4 @@
+class_or_func: get_transformer
+module_path: xautodl.xmodels.transformers
+args: [vit-cifar10-p4-d4-h4-c32]
+kwargs: {}
diff --git a/AutoDL-Projects/configs/yaml.opt/vit.cifar b/AutoDL-Projects/configs/yaml.opt/vit.cifar
new file mode 100644
index 0000000..d01e9ed
--- /dev/null
+++ b/AutoDL-Projects/configs/yaml.opt/vit.cifar
@@ -0,0 +1,7 @@
+class_or_func: Adam
+module_path: torch.optim
+args: []
+kwargs:
+ betas: [0.9, 0.999]
+ weight_decay: 0.1
+ amsgrad: False
diff --git a/AutoDL-Projects/docs/BASELINE.md b/AutoDL-Projects/docs/BASELINE.md
new file mode 100644
index 0000000..f273093
--- /dev/null
+++ b/AutoDL-Projects/docs/BASELINE.md
@@ -0,0 +1,139 @@
+# Basic Classification Models
+
+## Performance on CIFAR
+
+| Model | FLOPs | Params (M) | Error on CIFAR-10 | Error on CIFAR-100 | Batch-GPU |
+|:------------------:|:-----------:|:----------:|:-----------------:|:------------------:|:---------:|
+| ResNet-08 | 12.50 M | 0.08 | 12.14 | 40.20 | 256-2 |
+| ResNet-20 | 40.81 M | 0.27 | 7.26 | 31.38 | 256-2 |
+| ResNet-32 | 69.12 M | 0.47 | 6.19 | 29.56 | 256-2 |
+| ResNet-56 | 125.75 M | 0.86 | 5.74 | 26.82 | 256-2 |
+| ResNet-110 | 253.15 M | 1.73 | 5.14 | 25.18 | 256-2 |
+| ResNet-110 | 253.15 M | 1.73 | 5.06 | 25.49 | 256-1 |
+| ResNet-164 | 247.65 M | 1.70 | 4.36 | 21.48 | 256-2 |
+| ResNet-1001 | 1491.00 M | 10.33 | 5.34 | 22.50 | 256-2 |
+| DenseNet-BC100-12 | 287.93 M | 0.77 | 4.68 | 22.76 | 256-2 |
+| DenseNet-BC100-12 | 287.93 M | 0.77 | 4.25 | 21.54 | 128-2 |
+| DenseNet-BC100-12 | 287.93 M | 0.77 | 5.51 | 24.67 | 64-1 |
+| WRN-28-10 | 5243.33 M | 36.48 | 3.61 | 19.65 | 256-2 |
+
+```
+CUDA_VISIBLE_DEVICES=0,1 bash ./scripts/base-train.sh cifar10 ResNet20 E300 L1 256 -1
+CUDA_VISIBLE_DEVICES=0,1 bash ./scripts/base-train.sh cifar10 ResNet56 E300 L1 256 -1
+CUDA_VISIBLE_DEVICES=0,1 bash ./scripts/base-train.sh cifar10 ResNet110 E300 L1 256 -1
+CUDA_VISIBLE_DEVICES=0,1 bash ./scripts/base-train.sh cifar10 ResNet164 E300 L1 256 -1
+CUDA_VISIBLE_DEVICES=0,1 bash ./scripts/base-train.sh cifar10 DenseBC100-12 E300 L1 256 -1
+CUDA_VISIBLE_DEVICES=0,1 bash ./scripts/base-train.sh cifar10 WRN28-10 E300 L1 256 -1
+CUDA_VISIBLE_DEVICES=0,1 python ./exps/basic-eval.py --data_path ${TORCH_HOME}/ILSVRC2012 --checkpoint
+CUDA_VISIBLE_DEVICES=0,1 python ./exps/test-official-CNN.py --data_path ${TORCH_HOME}/ILSVRC2012
+```
+
+Train some NAS models:
+```
+CUDA_VISIBLE_DEVICES=0 bash ./scripts/nas-infer-train.sh cifar10 SETN 96 -1
+CUDA_VISIBLE_DEVICES=0 bash ./scripts/nas-infer-train.sh cifar100 SETN 96 -1
+
+CUDA_VISIBLE_DEVICES=0 bash ./scripts/nas-infer-train.sh cifar10 DARTS 96 -1
+
+CUDA_VISIBLE_DEVICES=0,1,2,3 bash ./scripts/nas-infer-train.sh imagenet-1k SETN 256 -1
+CUDA_VISIBLE_DEVICES=0,1,2,3 bash ./scripts/nas-infer-train.sh imagenet-1k SETN1 256 -1
+CUDA_VISIBLE_DEVICES=0,1,2,3 bash ./scripts/nas-infer-train.sh imagenet-1k DARTS 256 -1
+CUDA_VISIBLE_DEVICES=0,1,2,3 bash ./scripts/nas-infer-train.sh imagenet-1k GDAS_V1 256 -1
+```
+
+## Performance on ImageNet
+
+| Model | FLOPs (GB) | Params (M) | Top-1 Error | Top-5 Error | Optimizer |
+|:-----------------:|:----------:|:----------:|:-----------:|:-----------:|:----------:|
+| ResNet-18 | 1.814 | 11.69 | 30.24 | 10.92 | Official |
+| ResNet-18 | 1.814 | 11.69 | 29.97 | 10.43 | Step-120 |
+| ResNet-18 | 1.814 | 11.69 | 29.35 | 10.13 | Cosine-120 |
+| ResNet-18 | 1.814 | 11.69 | 29.45 | 10.25 | Cosine-120 B1024 |
+| ResNet-18 | 1.814 | 11.69 | 29.44 | 10.12 | Cosine-S-120 |
+| ResNet-18 (DS) | 2.053 | 11.71 | 28.53 | 9.69 | Cosine-S-120 |
+| ResNet-34 | 3.663 | 21.80 | 25.65 | 8.06 | Cosine-120 |
+| ResNet-34 (DS) | 3.903 | 21.82 | 25.05 | 7.67 | Cosine-S-120 |
+| ResNet-50 | 4.089 | 25.56 | 23.85 | 7.13 | Official |
+| ResNet-50 | 4.089 | 25.56 | 22.54 | 6.45 | Cosine-120 |
+| ResNet-50 | 4.089 | 25.56 | 22.71 | 6.38 | Cosine-120 B1024 |
+| ResNet-50 | 4.089 | 25.56 | 22.34 | 6.22 | Cosine-S-120 |
+| ResNet-50 (DS) | 4.328 | 25.58 | 22.67 | 6.39 | Step-120 |
+| ResNet-50 (DS) | 4.328 | 25.58 | 21.94 | 6.23 | Cosine-120 |
+| ResNet-50 (DS) | 4.328 | 25.58 | 21.71 | 5.99 | Cosine-S-120 |
+| ResNet-101 | 7.801 | 44.55 | 20.93 | 5.57 | Cosine-120 |
+| ResNet-101 | 7.801 | 44.55 | 20.92 | 5.58 | Cosine-120 B1024 |
+| ResNet-101 (DS) | 8.041 | 44.57 | 20.36 | 5.22 | Cosine-S-120 |
+| ResNet-152 | 11.514 | 60.19 | 20.10 | 5.17 | Cosine-120 B1024 |
+| ResNet-152 (DS) | 11.753 | 60.21 | 19.83 | 5.02 | Cosine-S-120 |
+| ResNet-200 | 15.007 | 64.67 | 20.06 | 4.98 | Cosine-S-120 |
+| Next50-32x4d (DS) | 4.2 | 25.0 | 22.2 | - | Official |
+| Next50-32x4d (DS) | 4.470 | 25.05 | 21.16 | 5.65 | Cosine-S-120 |
+| MobileNet-V2 | 0.300 | 3.40 | 28.0 | - | Official |
+| MobileNet-V2 | 0.300 | 3.50 | 27.92 | 9.50 | MobileFast |
+| MobileNet-V2 | 0.300 | 3.50 | 27.56 | 9.26 | MobileFast-Smooth |
+| ShuffleNet-V2 1.0 | 0.146 | 2.28 | 30.6 | 11.1 | Official |
+| ShuffleNet-V2 1.0 | 0.145 | 2.28 | | | Cosine-S-120 |
+| ShuffleNet-V2 1.5 | 0.299 | | 27.4 | - | Official |
+| ShuffleNet-V2 1.5 | | | | | Cosine-S-120 |
+| ShuffleNet-V2 2.0 | | | | | Cosine-S-120 |
+
+`DS` indicates deep-stem for the first convolutional layer.
+```
+CUDA_VISIBLE_DEVICES=0,1,2,3 bash ./scripts/base-imagenet.sh ResNet18V1 Step-Soft 256 -1
+CUDA_VISIBLE_DEVICES=0,1,2,3 bash ./scripts/base-imagenet.sh ResNet18V1 Cos-Soft 256 -1
+CUDA_VISIBLE_DEVICES=0,1,2,3 bash ./scripts/base-imagenet.sh ResNet18V1 Cos-Soft 1024 -1
+CUDA_VISIBLE_DEVICES=0,1,2,3 bash ./scripts/base-imagenet.sh ResNet18V1 Cos-Smooth 256 -1
+CUDA_VISIBLE_DEVICES=0,1,2,3 bash ./scripts/base-imagenet.sh ResNet18V2 Cos-Smooth 256 -1
+CUDA_VISIBLE_DEVICES=0,1,2,3 bash ./scripts/base-imagenet.sh ResNet34V2 Cos-Smooth 256 -1
+CUDA_VISIBLE_DEVICES=0,1,2,3 bash ./scripts/base-imagenet.sh ResNet50V1 Cos-Soft 256 -1
+CUDA_VISIBLE_DEVICES=0,1,2,3 bash ./scripts/base-imagenet.sh ResNet50V2 Step-Soft 256 -1
+CUDA_VISIBLE_DEVICES=0,1,2,3 bash ./scripts/base-imagenet.sh ResNet50V2 Cos-Soft 256 -1
+CUDA_VISIBLE_DEVICES=0,1,2,3 bash ./scripts/base-imagenet.sh ResNet101V2 Cos-Smooth 256 -1
+CUDA_VISIBLE_DEVICES=0,1,2,3 bash ./scripts/base-imagenet.sh ResNext50-32x4dV2 Cos-Smooth 256 -1
+```
+
+Train efficient models may require different hyper-parameters.
+```
+CUDA_VISIBLE_DEVICES=0,1,2,3 bash ./scripts/base-imagenet.sh MobileNetV2-X MobileFast 256 -1
+CUDA_VISIBLE_DEVICES=0,1,2,3 bash ./scripts/base-imagenet.sh MobileNetV2-X MobileFastS 256 -1
+CUDA_VISIBLE_DEVICES=0,1,2,3 bash ./scripts/base-imagenet.sh MobileNetV2 Mobile 256 -1 (70.96 top-1, 90.05 top-5)
+```
+
+# Train with Knowledge Distillation
+
+ResNet110 -> ResNet20
+```
+bash ./scripts-cluster/local.sh 0,1 "bash ./scripts/KD-train.sh cifar10 ResNet20 ResNet110 0.9 4 -1"
+```
+
+ResNet110 -> ResNet110
+```
+bash ./scripts-cluster/local.sh 0,1 "bash ./scripts/KD-train.sh cifar10 ResNet110 ResNet110 0.9 4 -1"
+```
+
+Set alpha=0.9 and temperature=4 following `Paying More Attention to Attention: Improving the Performance of Convolutional Neural Networks via Attention Transfer, ICLR 2017`.
+
+# Linux
+The following command will redirect the output of top command to `top.txt`.
+```
+top -b -n 1 > top.txt
+```
+
+## Download the ImageNet dataset
+The ImageNet Large Scale Visual Recognition Challenge (ILSVRC) dataset has 1000 categories and 1.2 million images. The images do not need to be preprocessed or packaged in any database, but the validation images need to be moved into appropriate subfolders.
+
+1. Download the images from http://image-net.org/download-images
+
+2. Extract the training data:
+ ```bash
+ mkdir train && mv ILSVRC2012_img_train.tar train/ && cd train
+ tar -xvf ILSVRC2012_img_train.tar && rm -f ILSVRC2012_img_train.tar
+ find . -name "*.tar" | while read NAME ; do mkdir -p "${NAME%.tar}"; tar -xvf "${NAME}" -C "${NAME%.tar}"; rm -f "${NAME}"; done
+ cd ..
+ ```
+
+3. Extract the validation data and move images to subfolders:
+ ```bash
+ mkdir val && mv ILSVRC2012_img_val.tar val/ && cd val && tar -xvf ILSVRC2012_img_val.tar
+ wget -qO- https://raw.githubusercontent.com/soumith/imagenetloader.torch/master/valprep.sh | bash
+ ```
diff --git a/AutoDL-Projects/docs/CVPR-2019-GDAS.md b/AutoDL-Projects/docs/CVPR-2019-GDAS.md
new file mode 100644
index 0000000..2bcc989
--- /dev/null
+++ b/AutoDL-Projects/docs/CVPR-2019-GDAS.md
@@ -0,0 +1,94 @@
+# [Searching for A Robust Neural Architecture in Four GPU Hours](https://arxiv.org/abs/1910.04465)
+
+
+
+Searching for A Robust Neural Architecture in Four GPU Hours is accepted at CVPR 2019.
+In this paper, we proposed a Gradient-based searching algorithm using Differentiable Architecture Sampling (GDAS).
+GDAS is baseed on DARTS and improves it with Gumbel-softmax sampling.
+Concurrently at the submission period, several NAS papers (SNAS and FBNet) also utilized Gumbel-softmax sampling. We are different at how to forward and backward, see more details in our paper and codes.
+Experiments on CIFAR-10, CIFAR-100, ImageNet, PTB, and WT2 are reported.
+
+
+## Requirements and Preparation
+
+Please install `Python>=3.6` and `PyTorch>=1.5.0`.
+
+CIFAR and ImageNet should be downloaded and extracted into `$TORCH_HOME`.
+
+### Usefull tools
+1. Compute the number of parameters and FLOPs of a model:
+```
+from utils import get_model_infos
+flop, param = get_model_infos(net, (1,3,32,32))
+```
+
+2. Different NAS-searched architectures are defined [here](https://github.com/D-X-Y/AutoDL-Projects/blob/main/xautodl/nas_infer_model/DXYs/genotypes.py).
+
+
+## Usage
+
+### Reproducing the results of our searched architecture in GDAS
+Please use the following scripts to train the searched GDAS-searched CNN on CIFAR-10, CIFAR-100, and ImageNet.
+```
+CUDA_VISIBLE_DEVICES=0 bash ./scripts/nas-infer-train.sh cifar10 GDAS_V1 96 -1
+CUDA_VISIBLE_DEVICES=0 bash ./scripts/nas-infer-train.sh cifar100 GDAS_V1 96 -1
+CUDA_VISIBLE_DEVICES=0,1,2,3 bash ./scripts/nas-infer-train.sh imagenet-1k GDAS_V1 256 -1
+```
+If you are interested in the configs of each NAS-searched architecture, they are defined at [genotypes.py](https://github.com/D-X-Y/AutoDL-Projects/blob/main/xautodl/nas_infer_model/DXYs/genotypes.py).
+
+### Searching on the NASNet search space
+
+Please use the following scripts to use GDAS to search as in the original paper:
+```
+# search for both normal and reduction cells
+CUDA_VISIBLE_DEVICES=0 bash ./scripts-search/NASNet-space-search-by-GDAS.sh cifar10 1 -1
+
+# search for the normal cell while use a fixed reduction cell
+CUDA_VISIBLE_DEVICES=0 bash ./scripts-search/NASNet-space-search-by-GDAS-FRC.sh cifar10 1 -1
+```
+
+**After searching**, if you want to re-train the searched architecture found by the above script, you can use the following script:
+```
+CUDA_VISIBLE_DEVICES=0 bash ./scripts/retrain-searched-net.sh cifar10 gdas-searched \
+ output/search-cell-darts/GDAS-cifar10-BN1/checkpoint/seed-945-basic.pth 96 -1
+```
+Note that `gdas-searched` is a string to indicate the name of the saved dir and `output/search-cell-darts/GDAS-cifar10-BN1/checkpoint/seed-945-basic.pth` is the file path that the searching algorithm generated.
+
+The above script does not apply heavy augmentation to train the model, so the accuracy will be lower than the original paper.
+If you want to change the default hyper-parameter for re-training, please have a look at `./scripts/retrain-searched-net.sh` and `configs/archs/NAS-*-none.config`.
+
+
+### Searching on a small search space (NAS-Bench-201)
+
+The GDAS searching codes on a small search space:
+```
+CUDA_VISIBLE_DEVICES=0 bash ./scripts-search/algos/GDAS.sh cifar10 1 -1
+```
+
+The baseline searching codes are DARTS:
+```
+CUDA_VISIBLE_DEVICES=0 bash ./scripts-search/algos/DARTS-V1.sh cifar10 1 -1
+CUDA_VISIBLE_DEVICES=0 bash ./scripts-search/algos/DARTS-V2.sh cifar10 1 -1
+```
+
+**After searching**, if you want to train the searched architecture found by the above scripts, please use the following codes:
+```
+CUDA_VISIBLE_DEVICES=0 bash ./scripts-search/NAS-Bench-201/train-a-net.sh '|nor_conv_3x3~0|+|nor_conv_3x3~0|nor_conv_3x3~1|+|skip_connect~0|skip_connect~1|skip_connect~2|' 16 5
+```
+`|nor_conv_3x3~0|+|nor_conv_3x3~0|nor_conv_3x3~1|+|skip_connect~0|skip_connect~1|skip_connect~2|` represents the structure of a searched architecture. My codes will automatically print it during the searching procedure.
+
+
+**Tensorflow codes for GDAS are in experimental state**, which locates at `exps-tf`.
+
+# Citation
+
+If you find that this project helps your research, please consider citing the following paper:
+```
+@inproceedings{dong2019search,
+ title = {Searching for A Robust Neural Architecture in Four GPU Hours},
+ author = {Dong, Xuanyi and Yang, Yi},
+ booktitle = {Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},
+ pages = {1761--1770},
+ year = {2019}
+}
+```
diff --git a/AutoDL-Projects/docs/ICCV-2019-SETN.md b/AutoDL-Projects/docs/ICCV-2019-SETN.md
new file mode 100644
index 0000000..13c5fa1
--- /dev/null
+++ b/AutoDL-Projects/docs/ICCV-2019-SETN.md
@@ -0,0 +1,53 @@
+# [One-Shot Neural Architecture Search via Self-Evaluated Template Network](https://arxiv.org/abs/1910.05733)
+
+
+
+Highlight : we equip one-shot NAS with an architecture sampler and train network weights using uniformly sampling.
+
+One-Shot Neural Architecture Search via Self-Evaluated Template Network is accepted by ICCV 2019.
+
+
+## Requirements and Preparation
+
+Please install `Python>=3.6` and `PyTorch>=1.2.0`.
+
+### Usefull tools
+1. Compute the number of parameters and FLOPs of a model:
+```
+from utils import get_model_infos
+flop, param = get_model_infos(net, (1,3,32,32))
+```
+
+2. Different NAS-searched architectures are defined [here](https://github.com/D-X-Y/AutoDL-Projects/blob/main/lib/nas_infer_model/DXYs/genotypes.py).
+
+
+## Usage
+
+Please use the following scripts to train the searched SETN-searched CNN on CIFAR-10, CIFAR-100, and ImageNet.
+```
+CUDA_VISIBLE_DEVICES=0 bash ./scripts/nas-infer-train.sh cifar10 SETN 96 -1
+CUDA_VISIBLE_DEVICES=0 bash ./scripts/nas-infer-train.sh cifar100 SETN 96 -1
+CUDA_VISIBLE_DEVICES=0,1,2,3 bash ./scripts/nas-infer-train.sh imagenet-1k SETN 256 -1
+```
+
+### Searching on the NAS-Bench-201 search space
+The searching codes of SETN on a small search space (NAS-Bench-201).
+```
+CUDA_VISIBLE_DEVICES=0 bash ./scripts-search/algos/SETN.sh cifar10 1 -1
+```
+
+**Searching on the NASNet search space** is not ready yet.
+
+
+# Citation
+
+If you find that this project helps your research, please consider citing the following paper:
+```
+@inproceedings{dong2019one,
+ title = {One-Shot Neural Architecture Search via Self-Evaluated Template Network},
+ author = {Dong, Xuanyi and Yang, Yi},
+ booktitle = {Proceedings of the IEEE International Conference on Computer Vision (ICCV)},
+ pages = {3681--3690},
+ year = {2019}
+}
+```
diff --git a/AutoDL-Projects/docs/ICLR-2019-DARTS.md b/AutoDL-Projects/docs/ICLR-2019-DARTS.md
new file mode 100644
index 0000000..eaf3b8b
--- /dev/null
+++ b/AutoDL-Projects/docs/ICLR-2019-DARTS.md
@@ -0,0 +1,32 @@
+# DARTS: Differentiable Architecture Search
+
+DARTS: Differentiable Architecture Search is accepted by ICLR 2019.
+In this paper, Hanxiao proposed a differentiable neural architecture search method, named as DARTS.
+Recently, DARTS becomes very popular due to its simplicity and performance.
+
+## Run DARTS on the NAS-Bench-201 search space
+```
+CUDA_VISIBLE_DEVICES=0 bash ./scripts-search/algos/DARTS-V2.sh cifar10 1 -1
+CUDA_VISIBLE_DEVICES=0 bash ./scripts-search/algos/GDAS.sh cifar10 1 -1
+```
+
+## Run the first-order DARTS on the NASNet/DARTS search space
+This command will start to use the first-order DARTS to search architectures on the DARTS search space.
+```
+CUDA_VISIBLE_DEVICES=0 bash ./scripts-search/DARTS1V-search-NASNet-space.sh cifar10 -1
+```
+
+After searching, if you want to train the searched architecture found by the above scripts, you need to add the config of that architecture (will be printed in log) in [genotypes.py](https://github.com/D-X-Y/AutoDL-Projects/blob/main/lib/nas_infer_model/DXYs/genotypes.py).
+In future, I will add a more eligent way to train the searched architecture from the DARTS search space.
+
+
+# Citation
+
+```
+@inproceedings{liu2019darts,
+ title = {{DARTS}: Differentiable architecture search},
+ author = {Liu, Hanxiao and Simonyan, Karen and Yang, Yiming},
+ booktitle = {International Conference on Learning Representations (ICLR)},
+ year = {2019}
+}
+```
diff --git a/AutoDL-Projects/docs/NAS-Bench-201-PURE.md b/AutoDL-Projects/docs/NAS-Bench-201-PURE.md
new file mode 100644
index 0000000..56a4afb
--- /dev/null
+++ b/AutoDL-Projects/docs/NAS-Bench-201-PURE.md
@@ -0,0 +1,183 @@
+# [NAS-BENCH-201: Extending the Scope of Reproducible Neural Architecture Search](https://openreview.net/forum?id=HJxyZkBKDr)
+
+**Since our NAS-BENCH-201 has been extended to NATS-Bench, this `README` is deprecated and not maintained. Please use [NATS-Bench](https://github.com/D-X-Y/AutoDL-Projects/blob/main/docs/NATS-Bench.md), which has 5x more architecture information and faster API than NAS-BENCH-201.**
+
+We propose an algorithm-agnostic NAS benchmark (NAS-Bench-201) with a fixed search space, which provides a unified benchmark for almost any up-to-date NAS algorithms.
+The design of our search space is inspired by that used in the most popular cell-based searching algorithms, where a cell is represented as a directed acyclic graph.
+Each edge here is associated with an operation selected from a predefined operation set.
+For it to be applicable for all NAS algorithms, the search space defined in NAS-Bench-201 includes 4 nodes and 5 associated operation options, which generates 15,625 neural cell candidates in total.
+
+In this Markdown file, we provide:
+- [How to Use NAS-Bench-201](#how-to-use-nas-bench-201)
+
+For the following two things, please use [AutoDL-Projects](https://github.com/D-X-Y/AutoDL-Projects):
+- [Instruction to re-generate NAS-Bench-201](#instruction-to-re-generate-nas-bench-201)
+- [10 NAS algorithms evaluated in our paper](#to-reproduce-10-baseline-nas-algorithms-in-nas-bench-201)
+
+Note: please use `PyTorch >= 1.2.0` and `Python >= 3.6.0`.
+
+You can simply type `pip install nas-bench-201` to install our api. Please see source codes of `nas-bench-201` module in [this repo](https://github.com/D-X-Y/NAS-Bench-201).
+
+**If you have any questions or issues, please post it at [here](https://github.com/D-X-Y/AutoDL-Projects/issues) or email me.**
+
+### Preparation and Download
+
+[deprecated] The **old** benchmark file of NAS-Bench-201 can be downloaded from [Google Drive](https://drive.google.com/file/d/1SKW0Cu0u8-gb18zDpaAGi0f74UdXeGKs/view?usp=sharing) or [Baidu-Wangpan (code:6u5d)](https://pan.baidu.com/s/1CiaNH6C12zuZf7q-Ilm09w).
+
+[recommended] The **latest** benchmark file of NAS-Bench-201 (`NAS-Bench-201-v1_1-096897.pth`) can be downloaded from [Google Drive](https://drive.google.com/file/d/16Y0UwGisiouVRxW-W5hEtbxmcHw_0hF_/view?usp=sharing). The files for model weight are too large (431G) and I need some time to upload it. Please be patient, thanks for your understanding.
+
+You can move it to anywhere you want and send its path to our API for initialization.
+- [2020.02.25] APIv1.0/FILEv1.0: [`NAS-Bench-201-v1_0-e61699.pth`](https://drive.google.com/open?id=1SKW0Cu0u8-gb18zDpaAGi0f74UdXeGKs) (2.2G), where `e61699` is the last six digits for this file. It contains all information except for the trained weights of each trial.
+- [2020.02.25] APIv1.0/FILEv1.0: The full data of each architecture can be download from [
+NAS-BENCH-201-4-v1.0-archive.tar](https://drive.google.com/open?id=1X2i-JXaElsnVLuGgM4tP-yNwtsspXgdQ) (about 226GB). This compressed folder has 15625 files containing the trained weights.
+- [2020.02.25] APIv1.0/FILEv1.0: Checkpoints for 3 runs of each baseline NAS algorithm are provided in [Google Drive](https://drive.google.com/open?id=1eAgLZQAViP3r6dA0_ZOOGG9zPLXhGwXi).
+- [2020.03.09] APIv1.2/FILEv1.0: More robust API with more functions and descriptions
+- [2020.03.16] APIv1.3/FILEv1.1: [`NAS-Bench-201-v1_1-096897.pth`](https://drive.google.com/open?id=16Y0UwGisiouVRxW-W5hEtbxmcHw_0hF_) (4.7G), where `096897` is the last six digits for this file. It contains information of more trials compared to `NAS-Bench-201-v1_0-e61699.pth`, especially all models trained by 12 epochs on all datasets are avaliable.
+- [2020.06.30] APIv2.0: Use abstract class (NASBenchMetaAPI) for APIs of NAS-Bench-x0y.
+- [2020.06.30] FILEv2.0: coming soon!
+
+**We recommend to use `NAS-Bench-201-v1_1-096897.pth`**
+
+
+The training and evaluation data used in NAS-Bench-201 can be downloaded from [Google Drive](https://drive.google.com/open?id=1L0Lzq8rWpZLPfiQGd6QR8q5xLV88emU7) or [Baidu-Wangpan (code:4fg7)](https://pan.baidu.com/s/1XAzavPKq3zcat1yBA1L2tQ).
+It is recommended to put these data into `$TORCH_HOME` (`~/.torch/` by default). If you want to generate NAS-Bench-201 or similar NAS datasets or training models by yourself, you need these data.
+
+## How to Use NAS-Bench-201
+
+**More usage can be found in [our test codes](https://github.com/D-X-Y/AutoDL-Projects/blob/main/exps/NAS-Bench-201/test-nas-api.py)**.
+
+1. Creating an API instance from a file:
+```
+from nas_201_api import NASBench201API as API
+api = API('$path_to_meta_nas_bench_file')
+# Create an API without the verbose log
+api = API('NAS-Bench-201-v1_1-096897.pth', verbose=False)
+# The default path for benchmark file is '{:}/{:}'.format(os.environ['TORCH_HOME'], 'NAS-Bench-201-v1_1-096897.pth')
+api = API(None)
+```
+
+2. Show the number of architectures `len(api)` and each architecture `api[i]`:
+```
+num = len(api)
+for i, arch_str in enumerate(api):
+ print ('{:5d}/{:5d} : {:}'.format(i, len(api), arch_str))
+```
+
+3. Show the results of all trials for a single architecture:
+```
+# show all information for a specific architecture
+api.show(1)
+api.show(2)
+
+# show the mean loss and accuracy of an architecture
+info = api.query_meta_info_by_index(1) # This is an instance of `ArchResults`
+res_metrics = info.get_metrics('cifar10', 'train') # This is a dict with metric names as keys
+cost_metrics = info.get_compute_costs('cifar100') # This is a dict with metric names as keys, e.g., flops, params, latency
+
+# get the detailed information
+results = api.query_by_index(1, 'cifar100') # a dict of all trials for 1st net on cifar100, where the key is the seed
+print ('There are {:} trials for this architecture [{:}] on cifar100'.format(len(results), api[1]))
+for seed, result in results.items():
+ print ('Latency : {:}'.format(result.get_latency()))
+ print ('Train Info : {:}'.format(result.get_train()))
+ print ('Valid Info : {:}'.format(result.get_eval('x-valid')))
+ print ('Test Info : {:}'.format(result.get_eval('x-test')))
+ # for the metric after a specific epoch
+ print ('Train Info [10-th epoch] : {:}'.format(result.get_train(10)))
+```
+
+4. Query the index of an architecture by string
+```
+index = api.query_index_by_arch('|nor_conv_3x3~0|+|nor_conv_3x3~0|avg_pool_3x3~1|+|skip_connect~0|nor_conv_3x3~1|skip_connect~2|')
+api.show(index)
+```
+This string `|nor_conv_3x3~0|+|nor_conv_3x3~0|avg_pool_3x3~1|+|skip_connect~0|nor_conv_3x3~1|skip_connect~2|` means:
+```
+node-0: the input tensor
+node-1: conv-3x3( node-0 )
+node-2: conv-3x3( node-0 ) + avg-pool-3x3( node-1 )
+node-3: skip-connect( node-0 ) + conv-3x3( node-1 ) + skip-connect( node-2 )
+```
+
+5. Create the network from api:
+```
+config = api.get_net_config(123, 'cifar10') # obtain the network configuration for the 123-th architecture on the CIFAR-10 dataset
+from models import get_cell_based_tiny_net # this module is in AutoDL-Projects/lib/models
+network = get_cell_based_tiny_net(config) # create the network from configurration
+print(network) # show the structure of this architecture
+```
+If you want to load the trained weights of this created network, you need to use `api.get_net_param(123, ...)` to obtain the weights and then load it to the network.
+
+6. `api.get_more_info(...)` can return the loss / accuracy / time on training / validation / test sets, which is very helpful. For more details, please look at the comments in the get_more_info function.
+
+7. For other usages, please see `lib/nas_201_api/api.py`. We provide some usage information in the comments for the corresponding functions. If what you want is not provided, please feel free to open an issue for discussion, and I am happy to answer any questions regarding NAS-Bench-201.
+
+
+### Detailed Instruction
+
+In `nas_201_api`, we define three classes: `NASBench201API`, `ArchResults`, `ResultsCount`.
+
+`ResultsCount` maintains all information of a specific trial. One can instantiate ResultsCount and get the info via the following codes (`000157-FULL.pth` saves all information of all trials of 157-th architecture):
+```
+from nas_201_api import ResultsCount
+xdata = torch.load('000157-FULL.pth')
+odata = xdata['full']['all_results'][('cifar10-valid', 777)]
+result = ResultsCount.create_from_state_dict( odata )
+print(result) # print it
+print(result.get_train()) # print the final training loss/accuracy/[optional:time-cost-of-a-training-epoch]
+print(result.get_train(11)) # print the training info of the 11-th epoch
+print(result.get_eval('x-valid')) # print the final evaluation info on the validation set
+print(result.get_eval('x-valid', 11)) # print the info on the validation set of the 11-th epoch
+print(result.get_latency()) # print the evaluation latency [in batch]
+result.get_net_param() # the trained parameters of this trial
+arch_config = result.get_config(CellStructure.str2structure) # create the network with params
+net_config = dict2config(arch_config, None)
+network = get_cell_based_tiny_net(net_config)
+network.load_state_dict(result.get_net_param())
+```
+
+`ArchResults` maintains all information of all trials of an architecture. Please see the following usages:
+```
+from nas_201_api import ArchResults
+xdata = torch.load('000157-FULL.pth')
+archRes = ArchResults.create_from_state_dict(xdata['less']) # load trials trained with 12 epochs
+archRes = ArchResults.create_from_state_dict(xdata['full']) # load trials trained with 200 epochs
+
+print(archRes.arch_idx_str()) # print the index of this architecture
+print(archRes.get_dataset_names()) # print the supported training data
+print(archRes.get_comput_costs('cifar10-valid')) # print all computational info when training on cifar10-valid
+print(archRes.get_metrics('cifar10-valid', 'x-valid', None, False)) # print the average loss/accuracy/time on all trials
+print(archRes.get_metrics('cifar10-valid', 'x-valid', None, True)) # print loss/accuracy/time of a randomly selected trial
+```
+
+`NASBench201API` is the topest level api. Please see the following usages:
+```
+from nas_201_api import NASBench201API as API
+api = API('NAS-Bench-201-v1_1-096897.pth') # This will load all the information of NAS-Bench-201 except the trained weights
+api = API('{:}/{:}'.format(os.environ['TORCH_HOME'], 'NAS-Bench-201-v1_1-096897.pth')) # The same as the above line while I usually save NAS-Bench-201-v1_1-096897.pth in ~/.torch/.
+api.show(-1) # show info of all architectures
+api.reload('{:}/{:}'.format(os.environ['TORCH_HOME'], 'NAS-BENCH-201-4-v1.0-archive'), 3) # This code will reload the information 3-th architecture with the trained weights
+
+weights = api.get_net_param(3, 'cifar10', None) # Obtaining the weights of all trials for the 3-th architecture on cifar10. It will returns a dict, where the key is the seed and the value is the trained weights.
+```
+
+To obtain the training and evaluation information (please see the comments [here](https://github.com/D-X-Y/AutoDL-Projects/blob/main/lib/nas_201_api/api_201.py#L142)):
+```
+api.get_more_info(112, 'cifar10', None, hp='200', is_random=True)
+# Query info of last training epoch for 112-th architecture
+# using 200-epoch-hyper-parameter and randomly select a trial.
+api.get_more_info(112, 'ImageNet16-120', None, hp='200', is_random=True)
+```
+
+# Citation
+
+If you find that NAS-Bench-201 helps your research, please consider citing it:
+```
+@inproceedings{dong2020nasbench201,
+ title = {{NAS-Bench-201}: Extending the Scope of Reproducible Neural Architecture Search},
+ author = {Dong, Xuanyi and Yang, Yi},
+ booktitle = {International Conference on Learning Representations (ICLR)},
+ url = {https://openreview.net/forum?id=HJxyZkBKDr},
+ year = {2020}
+}
+```
diff --git a/AutoDL-Projects/docs/NAS-Bench-201.md b/AutoDL-Projects/docs/NAS-Bench-201.md
new file mode 100644
index 0000000..4fcb7f5
--- /dev/null
+++ b/AutoDL-Projects/docs/NAS-Bench-201.md
@@ -0,0 +1,254 @@
+# [NAS-BENCH-201: Extending the Scope of Reproducible Neural Architecture Search](https://openreview.net/forum?id=HJxyZkBKDr)
+
+**Since our NAS-BENCH-201 has been extended to NATS-Bench, this README is deprecated and not maintained. Please use [NATS-Bench](https://github.com/D-X-Y/AutoDL-Projects/blob/main/docs/NATS-Bench.md), which has 5x more architecture information and faster API than NAS-BENCH-201.**
+
+We propose an algorithm-agnostic NAS benchmark (NAS-Bench-201) with a fixed search space, which provides a unified benchmark for almost any up-to-date NAS algorithms.
+The design of our search space is inspired by that used in the most popular cell-based searching algorithms, where a cell is represented as a directed acyclic graph.
+Each edge here is associated with an operation selected from a predefined operation set.
+For it to be applicable for all NAS algorithms, the search space defined in NAS-Bench-201 includes 4 nodes and 5 associated operation options, which generates 15,625 neural cell candidates in total.
+
+In this Markdown file, we provide:
+- [How to Use NAS-Bench-201](#how-to-use-nas-bench-201)
+- [Instruction to re-generate NAS-Bench-201](#instruction-to-re-generate-nas-bench-201)
+- [10 NAS algorithms evaluated in our paper](#to-reproduce-10-baseline-nas-algorithms-in-nas-bench-201)
+
+Note: please use `PyTorch >= 1.2.0` and `Python >= 3.6.0`.
+
+You can simply type `pip install nas-bench-201` to install our api. Please see source codes of `nas-bench-201` module in [this repo](https://github.com/D-X-Y/NAS-Bench-201).
+
+**If you have any questions or issues, please post it at [here](https://github.com/D-X-Y/AutoDL-Projects/issues) or email me.**
+
+### Preparation and Download
+
+[deprecated] The **old** benchmark file of NAS-Bench-201 can be downloaded from [Google Drive](https://drive.google.com/file/d/1SKW0Cu0u8-gb18zDpaAGi0f74UdXeGKs/view?usp=sharing) or [Baidu-Wangpan (code:6u5d)](https://pan.baidu.com/s/1CiaNH6C12zuZf7q-Ilm09w).
+
+[recommended] The **latest** benchmark file of NAS-Bench-201 (`NAS-Bench-201-v1_1-096897.pth`) can be downloaded from [Google Drive](https://drive.google.com/file/d/16Y0UwGisiouVRxW-W5hEtbxmcHw_0hF_/view?usp=sharing). The files for model weight are too large (431G) and I need some time to upload it. Please be patient, thanks for your understanding.
+
+You can move it to anywhere you want and send its path to our API for initialization.
+- [2020.02.25] APIv1.0/FILEv1.0: [`NAS-Bench-201-v1_0-e61699.pth`](https://drive.google.com/open?id=1SKW0Cu0u8-gb18zDpaAGi0f74UdXeGKs) (2.2G), where `e61699` is the last six digits for this file. It contains all information except for the trained weights of each trial.
+- [2020.02.25] APIv1.0/FILEv1.0: The full data of each architecture can be download from [
+NAS-BENCH-201-4-v1.0-archive.tar](https://drive.google.com/open?id=1X2i-JXaElsnVLuGgM4tP-yNwtsspXgdQ) (about 226GB). This compressed folder has 15625 files containing the trained weights.
+- [2020.02.25] APIv1.0/FILEv1.0: Checkpoints for 3 runs of each baseline NAS algorithm are provided in [Google Drive](https://drive.google.com/open?id=1eAgLZQAViP3r6dA0_ZOOGG9zPLXhGwXi).
+- [2020.03.09] APIv1.2/FILEv1.0: More robust API with more functions and descriptions
+- [2020.03.16] APIv1.3/FILEv1.1: [`NAS-Bench-201-v1_1-096897.pth`](https://drive.google.com/open?id=16Y0UwGisiouVRxW-W5hEtbxmcHw_0hF_) (4.7G), where `096897` is the last six digits for this file. It contains information of more trials compared to `NAS-Bench-201-v1_0-e61699.pth`, especially all models trained by 12 epochs on all datasets are avaliable.
+- [2020.06.30] APIv2.0: Use abstract class (NASBenchMetaAPI) for APIs of NAS-Bench-x0y.
+- [2020.06.30] FILEv2.0: coming soon!
+
+**We recommend to use `NAS-Bench-201-v1_1-096897.pth`**
+
+
+The training and evaluation data used in NAS-Bench-201 can be downloaded from [Google Drive](https://drive.google.com/open?id=1L0Lzq8rWpZLPfiQGd6QR8q5xLV88emU7) or [Baidu-Wangpan (code:4fg7)](https://pan.baidu.com/s/1XAzavPKq3zcat1yBA1L2tQ).
+It is recommended to put these data into `$TORCH_HOME` (`~/.torch/` by default). If you want to generate NAS-Bench-201 or similar NAS datasets or training models by yourself, you need these data.
+
+## How to Use NAS-Bench-201
+
+**More usage can be found in [our test codes](https://github.com/D-X-Y/AutoDL-Projects/blob/main/exps/NAS-Bench-201/test-nas-api.py)**.
+
+1. Creating an API instance from a file:
+```
+from nas_201_api import NASBench201API as API
+api = API('$path_to_meta_nas_bench_file')
+# Create an API without the verbose log
+api = API('NAS-Bench-201-v1_1-096897.pth', verbose=False)
+# The default path for benchmark file is '{:}/{:}'.format(os.environ['TORCH_HOME'], 'NAS-Bench-201-v1_1-096897.pth')
+api = API(None)
+```
+
+2. Show the number of architectures `len(api)` and each architecture `api[i]`:
+```
+num = len(api)
+for i, arch_str in enumerate(api):
+ print ('{:5d}/{:5d} : {:}'.format(i, len(api), arch_str))
+```
+
+3. Show the results of all trials for a single architecture:
+```
+# show all information for a specific architecture
+api.show(1)
+api.show(2)
+
+# show the mean loss and accuracy of an architecture
+info = api.query_meta_info_by_index(1) # This is an instance of `ArchResults`
+res_metrics = info.get_metrics('cifar10', 'train') # This is a dict with metric names as keys
+cost_metrics = info.get_compute_costs('cifar100') # This is a dict with metric names as keys, e.g., flops, params, latency
+
+# get the detailed information
+results = api.query_by_index(1, 'cifar100') # a dict of all trials for 1st net on cifar100, where the key is the seed
+print ('There are {:} trials for this architecture [{:}] on cifar100'.format(len(results), api[1]))
+for seed, result in results.items():
+ print ('Latency : {:}'.format(result.get_latency()))
+ print ('Train Info : {:}'.format(result.get_train()))
+ print ('Valid Info : {:}'.format(result.get_eval('x-valid')))
+ print ('Test Info : {:}'.format(result.get_eval('x-test')))
+ # for the metric after a specific epoch
+ print ('Train Info [10-th epoch] : {:}'.format(result.get_train(10)))
+```
+
+4. Query the index of an architecture by string
+```
+index = api.query_index_by_arch('|nor_conv_3x3~0|+|nor_conv_3x3~0|avg_pool_3x3~1|+|skip_connect~0|nor_conv_3x3~1|skip_connect~2|')
+api.show(index)
+```
+This string `|nor_conv_3x3~0|+|nor_conv_3x3~0|avg_pool_3x3~1|+|skip_connect~0|nor_conv_3x3~1|skip_connect~2|` means:
+```
+node-0: the input tensor
+node-1: conv-3x3( node-0 )
+node-2: conv-3x3( node-0 ) + avg-pool-3x3( node-1 )
+node-3: skip-connect( node-0 ) + conv-3x3( node-1 ) + skip-connect( node-2 )
+```
+
+5. Create the network from api:
+```
+config = api.get_net_config(123, 'cifar10') # obtain the network configuration for the 123-th architecture on the CIFAR-10 dataset
+from models import get_cell_based_tiny_net # this module is in AutoDL-Projects/lib/models
+network = get_cell_based_tiny_net(config) # create the network from configurration
+print(network) # show the structure of this architecture
+```
+If you want to load the trained weights of this created network, you need to use `api.get_net_param(123, ...)` to obtain the weights and then load it to the network.
+
+6. `api.get_more_info(...)` can return the loss / accuracy / time on training / validation / test sets, which is very helpful. For more details, please look at the comments in the get_more_info function.
+
+7. For other usages, please see `lib/nas_201_api/api.py`. We provide some usage information in the comments for the corresponding functions. If what you want is not provided, please feel free to open an issue for discussion, and I am happy to answer any questions regarding NAS-Bench-201.
+
+
+### Detailed Instruction
+
+In `nas_201_api`, we define three classes: `NASBench201API`, `ArchResults`, `ResultsCount`.
+
+`ResultsCount` maintains all information of a specific trial. One can instantiate ResultsCount and get the info via the following codes (`000157-FULL.pth` saves all information of all trials of 157-th architecture):
+```
+from nas_201_api import ResultsCount
+xdata = torch.load('000157-FULL.pth')
+odata = xdata['full']['all_results'][('cifar10-valid', 777)]
+result = ResultsCount.create_from_state_dict( odata )
+print(result) # print it
+print(result.get_train()) # print the final training loss/accuracy/[optional:time-cost-of-a-training-epoch]
+print(result.get_train(11)) # print the training info of the 11-th epoch
+print(result.get_eval('x-valid')) # print the final evaluation info on the validation set
+print(result.get_eval('x-valid', 11)) # print the info on the validation set of the 11-th epoch
+print(result.get_latency()) # print the evaluation latency [in batch]
+result.get_net_param() # the trained parameters of this trial
+arch_config = result.get_config(CellStructure.str2structure) # create the network with params
+net_config = dict2config(arch_config, None)
+network = get_cell_based_tiny_net(net_config)
+network.load_state_dict(result.get_net_param())
+```
+
+`ArchResults` maintains all information of all trials of an architecture. Please see the following usages:
+```
+from nas_201_api import ArchResults
+xdata = torch.load('000157-FULL.pth')
+archRes = ArchResults.create_from_state_dict(xdata['less']) # load trials trained with 12 epochs
+archRes = ArchResults.create_from_state_dict(xdata['full']) # load trials trained with 200 epochs
+
+print(archRes.arch_idx_str()) # print the index of this architecture
+print(archRes.get_dataset_names()) # print the supported training data
+print(archRes.get_comput_costs('cifar10-valid')) # print all computational info when training on cifar10-valid
+print(archRes.get_metrics('cifar10-valid', 'x-valid', None, False)) # print the average loss/accuracy/time on all trials
+print(archRes.get_metrics('cifar10-valid', 'x-valid', None, True)) # print loss/accuracy/time of a randomly selected trial
+```
+
+`NASBench201API` is the topest level api. Please see the following usages:
+```
+from nas_201_api import NASBench201API as API
+api = API('NAS-Bench-201-v1_1-096897.pth') # This will load all the information of NAS-Bench-201 except the trained weights
+api = API('{:}/{:}'.format(os.environ['TORCH_HOME'], 'NAS-Bench-201-v1_1-096897.pth')) # The same as the above line while I usually save NAS-Bench-201-v1_1-096897.pth in ~/.torch/.
+api.show(-1) # show info of all architectures
+api.reload('{:}/{:}'.format(os.environ['TORCH_HOME'], 'NAS-BENCH-201-4-v1.0-archive'), 3) # This code will reload the information 3-th architecture with the trained weights
+
+weights = api.get_net_param(3, 'cifar10', None) # Obtaining the weights of all trials for the 3-th architecture on cifar10. It will returns a dict, where the key is the seed and the value is the trained weights.
+```
+
+To obtain the training and evaluation information (please see the comments [here](https://github.com/D-X-Y/AutoDL-Projects/blob/main/lib/nas_201_api/api_201.py#L142)):
+```
+api.get_more_info(112, 'cifar10', None, hp='200', is_random=True)
+# Query info of last training epoch for 112-th architecture
+# using 200-epoch-hyper-parameter and randomly select a trial.
+api.get_more_info(112, 'ImageNet16-120', None, hp='200', is_random=True)
+```
+
+Please use the following script to show the best architectures on each dataset:
+```show the best architecture
+python exps/NAS-Bench-201/show-best.py
+```
+
+
+## Instruction to Re-Generate NAS-Bench-201
+
+There are four steps to build NAS-Bench-201.
+
+1. generate the meta file for NAS-Bench-201 using the following script, where `NAS-BENCH-201` indicates the name and `4` indicates the maximum number of nodes in a cell.
+```
+bash scripts-search/NAS-Bench-201/meta-gen.sh NAS-BENCH-201 4
+```
+
+2. train earch architecture on a single GPU (see commands in `output/NAS-BENCH-201-4/BENCH-201-N4.opt-full.script`, which is automatically generated by step-1).
+```
+CUDA_VISIBLE_DEVICES=0 bash ./scripts-search/NAS-Bench-201/train-models.sh 0 0 389 -1 '777 888 999'
+```
+This command will train 390 architectures (id from 0 to 389) using the following four kinds of splits with three random seeds (777, 888, 999).
+
+| Dataset | Train | Eval |
+|:---------------:|:-------------:|:------------:|
+| CIFAR-10 | train | valid / test |
+| CIFAR-10 | train + valid | test |
+| CIFAR-100 | train | valid / test |
+| ImageNet-16-120 | train | valid / test |
+
+Note that the above `train`, `valid`, and `test` indicate the proposed splits in our NAS-Bench-201, and they might be different with the original splits.
+
+3. calculate the latency, merge the results of all architectures, and simplify the results.
+(see commands in `output/NAS-BENCH-201-4/meta-node-4.cal-script.txt` which is automatically generated by step-1).
+```
+OMP_NUM_THREADS=6 CUDA_VISIBLE_DEVICES=0 python exps/NAS-Bench-201/statistics.py --mode cal --target_dir 000000-000389-C16-N5
+```
+
+4. merge all results into a single file for NAS-Bench-201-API.
+```
+OMP_NUM_THREADS=4 python exps/NAS-Bench-201/statistics.py --mode merge
+```
+This command will generate a single file `output/NAS-BENCH-201-4/simplifies/C16-N5-final-infos.pth` contains all the data for NAS-Bench-201.
+This generated file will serve as the input for our NAS-Bench-201 API.
+
+[option] train a single architecture on a single GPU.
+```
+CUDA_VISIBLE_DEVICES=0 bash ./scripts-search/NAS-Bench-201/train-a-net.sh resnet 16 5
+CUDA_VISIBLE_DEVICES=0 bash ./scripts-search/NAS-Bench-201/train-a-net.sh '|nor_conv_3x3~0|+|nor_conv_3x3~0|nor_conv_3x3~1|+|skip_connect~0|skip_connect~1|skip_connect~2|' 16 5
+```
+
+
+## To Reproduce 10 Baseline NAS Algorithms in NAS-Bench-201
+
+We have tried our best to implement each method. However, still, some algorithms might obtain non-optimal results since their hyper-parameters might not fit our NAS-Bench-201.
+If researchers can provide better results with different hyper-parameters, we are happy to update results according to the new experimental results. We also welcome more NAS algorithms to test on our dataset and would include them accordingly.
+
+**Note that** you need to prepare the training and test data as described in [Preparation and Download](#preparation-and-download)
+
+- [1] `CUDA_VISIBLE_DEVICES=0 bash ./scripts-search/NAS-Bench-201-algos/DARTS-V1.sh cifar10 1 -1`, where `cifar10` can be replaced with `cifar100` or `ImageNet16-120`.
+- [2] `CUDA_VISIBLE_DEVICES=0 bash ./scripts-search/NAS-Bench-201-algos/DARTS-V2.sh cifar10 1 -1`
+- [3] `CUDA_VISIBLE_DEVICES=0 bash ./scripts-search/NAS-Bench-201-algos/GDAS.sh cifar10 1 -1`
+- [4] `CUDA_VISIBLE_DEVICES=0 bash ./scripts-search/NAS-Bench-201-algos/SETN.sh cifar10 1 -1`
+- [5] `CUDA_VISIBLE_DEVICES=0 bash ./scripts-search/NAS-Bench-201-algos/ENAS.sh cifar10 1 -1`
+- [6] `CUDA_VISIBLE_DEVICES=0 bash ./scripts-search/NAS-Bench-201-algos/RANDOM-NAS.sh cifar10 1 -1`
+- [7] `bash ./scripts-search/NAS-Bench-201-algos/R-EA.sh cifar10 3 -1`
+- [8] `bash ./scripts-search/NAS-Bench-201-algos/Random.sh cifar10 -1`
+- [9] `bash ./scripts-search/NAS-Bench-201-algos/REINFORCE.sh cifar10 0.5 -1`
+- [10] `bash ./scripts-search/NAS-Bench-201-algos/BOHB.sh cifar10 -1`
+
+In commands [1-6], the first args `cifar10` indicates the dataset name, the second args `1` indicates the behavior of BN, and the first args `-1` indicates the random seed.
+
+**Note that** since 2020 March 16, in these scripts, the default NAS-Bench-201 benchmark file has changed from `NAS-Bench-201-v1_0-e61699.pth` to `NAS-Bench-201-v1_1-096897.pth`, and thus the results could be slightly different from the original paper.
+
+
+# Citation
+
+If you find that NAS-Bench-201 helps your research, please consider citing it:
+```
+@inproceedings{dong2020nasbench201,
+ title = {{NAS-Bench-201}: Extending the Scope of Reproducible Neural Architecture Search},
+ author = {Dong, Xuanyi and Yang, Yi},
+ booktitle = {International Conference on Learning Representations (ICLR)},
+ url = {https://openreview.net/forum?id=HJxyZkBKDr},
+ year = {2020}
+}
+```
diff --git a/AutoDL-Projects/docs/NeurIPS-2019-TAS.md b/AutoDL-Projects/docs/NeurIPS-2019-TAS.md
new file mode 100644
index 0000000..fb87976
--- /dev/null
+++ b/AutoDL-Projects/docs/NeurIPS-2019-TAS.md
@@ -0,0 +1,71 @@
+# [Network Pruning via Transformable Architecture Search](https://arxiv.org/abs/1905.09717)
+
+[](https://paperswithcode.com/sota/network-pruning-on-cifar-100?p=network-pruning-via-transformable)
+
+Network Pruning via Transformable Architecture Search is accepted by NeurIPS 2019.
+In this paper, we proposed a differentiable searching strategy for transformable architectures, i.e., searching for the depth and width of a deep neural network.
+You could see the highlight of our Transformable Architecture Search (TAS) at our [project page](https://xuanyidong.com/assets/projects/NeurIPS-2019-TAS.html).
+
+
+
+
+
+
+
+## Requirements and Preparation
+
+Please install `Python>=3.6` and `PyTorch>=1.2.0`.
+
+CIFAR and ImageNet should be downloaded and extracted into `$TORCH_HOME`.
+The proposed method utilized knowledge distillation (KD), which require pre-trained models. Please download these models from [Google Drive](https://drive.google.com/open?id=1ANmiYEGX-IQZTfH8w0aSpj-Wypg-0DR-) (or train by yourself) and save into `.latent-data`.
+
+**LOGS**:
+We provide some logs at [Google Drive](https://drive.google.com/open?id=1_qUY4DTtuW_l6ZonynQAC9ttqy35fxZ-). It includes (1) logs of training searched shape of ResNet-18 and ResNet-50 on ImageNet, (2) logs of searching and training for ResNet-164 on CIFAR, (3) logs of searching and training for ResNet56 on CIFAR-10, (4) logs of searching and training for ResNet110 on CIFAR-100.
+
+## Usage
+
+Use `bash ./scripts/TAS/prepare.sh` to prepare data splits for `CIFAR-10`, `CIFARR-100`, and `ILSVRC2012`.
+If you do not have `ILSVRC2012` data, please comment L12 in `./scripts/prepare.sh`.
+
+args: `cifar10` indicates the dataset name, `ResNet56` indicates the basemodel name, `CIFARX` indicates the searching hyper-parameters, `0.47/0.57` indicates the expected FLOP ratio, `-1` indicates the random seed.
+
+**Model Configuration**
+
+The searched shapes for ResNet-20/32/56/110/164 and ResNet-18/50 in Table 3/4 in the original paper are listed in [`configs/NeurIPS-2019`](https://github.com/D-X-Y/AutoDL-Projects/tree/main/configs/NeurIPS-2019).
+
+**Search for the depth configuration of ResNet**
+```
+CUDA_VISIBLE_DEVICES=0,1 bash ./scripts-search/search-depth-gumbel.sh cifar10 ResNet110 CIFARX 0.57 -1
+```
+
+**Search for the width configuration of ResNet**
+```
+CUDA_VISIBLE_DEVICES=0,1 bash ./scripts-search/search-width-gumbel.sh cifar10 ResNet110 CIFARX 0.57 -1
+```
+
+**Search for both depth and width configuration of ResNet**
+```
+CUDA_VISIBLE_DEVICES=0,1 bash ./scripts-search/search-shape-cifar.sh cifar10 ResNet56 CIFARX 0.47 -1
+```
+
+**Training the searched shape config from TAS:**
+If you want to directly train a model with searched configuration of TAS, try these:
+```
+CUDA_VISIBLE_DEVICES=0,1 bash ./scripts/tas-infer-train.sh cifar10 C010-ResNet32 -1
+CUDA_VISIBLE_DEVICES=0,1 bash ./scripts/tas-infer-train.sh cifar100 C100-ResNet32 -1
+CUDA_VISIBLE_DEVICES=0,1,2,3 bash ./scripts/tas-infer-train.sh imagenet-1k ImageNet-ResNet18V1 -1
+CUDA_VISIBLE_DEVICES=0,1,2,3 bash ./scripts/tas-infer-train.sh imagenet-1k ImageNet-ResNet50V1 -1
+```
+
+
+# Citation
+
+If you find that this project helps your research, please consider citing the following paper:
+```
+@inproceedings{dong2019tas,
+ title = {Network Pruning via Transformable Architecture Search},
+ author = {Dong, Xuanyi and Yang, Yi},
+ booktitle = {Neural Information Processing Systems (NeurIPS)},
+ year = {2019}
+}
+```
diff --git a/AutoDL-Projects/docs/README_CN.md b/AutoDL-Projects/docs/README_CN.md
new file mode 100644
index 0000000..1f90656
--- /dev/null
+++ b/AutoDL-Projects/docs/README_CN.md
@@ -0,0 +1,149 @@
+
+
+
+
+---------
+[](../LICENSE.md)
+
+自动深度学习库 (AutoDL-Projects) 是一个开源的,轻量级的,功能强大的项目。
+该项目实现了多种网络结构搜索(NAS)和超参数优化(HPO)算法。
+
+**谁应该考虑使用AutoDL-Projects**
+
+- 想尝试不同AutoDL算法的初学者
+- 想调研AutoDL在特定问题上的有效性的工程师
+- 想轻松实现和实验新AutoDL算法的研究员
+
+**为什么我们要用AutoDL-Projects**
+- 最简化的python依赖库
+- 所有算法都在一个代码库下
+- 积极地维护
+
+
+## AutoDL-Projects 能力简述
+
+目前,该项目提供了下列算法和以及对应的运行脚本。请点击每个算法对应的链接看他们的细节描述。
+
+
+
+
+
+## 准备工作
+
+请使用`3.6`以上的`Python`,更多的Python包参见[requirements.txt](requirements.txt).
+
+请下载并且解压缩`CIFAR`和`ImageNet`到`$TORCH_HOME`.
+
+## 引用
+
+如果您发现该项目对您的科研或工程有帮助,请考虑引用下列的某些文献:
+```
+@inproceedings{dong2021autohas,
+ title = {{AutoHAS}: Efficient Hyperparameter and Architecture Search},
+ author = {Dong, Xuanyi and Tan, Mingxing and Yu, Adams Wei and Peng, Daiyi and Gabrys, Bogdan and Le, Quoc V},
+ booktitle = {2nd Workshop on Neural Architecture Search at International Conference on Learning Representations (ICLR)},
+ year = {2021}
+}
+@article{dong2021nats,
+ title = {{NATS-Bench}: Benchmarking NAS Algorithms for Architecture Topology and Size},
+ author = {Dong, Xuanyi and Liu, Lu and Musial, Katarzyna and Gabrys, Bogdan},
+ doi = {10.1109/TPAMI.2021.3054824},
+ journal = {IEEE Transactions on Pattern Analysis and Machine Intelligence (TPAMI)},
+ year = {2021},
+ note = {\mbox{doi}:\url{10.1109/TPAMI.2021.3054824}}
+}
+@inproceedings{dong2020nasbench201,
+ title = {{NAS-Bench-201}: Extending the Scope of Reproducible Neural Architecture Search},
+ author = {Dong, Xuanyi and Yang, Yi},
+ booktitle = {International Conference on Learning Representations (ICLR)},
+ url = {https://openreview.net/forum?id=HJxyZkBKDr},
+ year = {2020}
+}
+@inproceedings{dong2019tas,
+ title = {Network Pruning via Transformable Architecture Search},
+ author = {Dong, Xuanyi and Yang, Yi},
+ booktitle = {Neural Information Processing Systems (NeurIPS)},
+ year = {2019}
+ pages = {760--771},
+}
+@inproceedings{dong2019one,
+ title = {One-Shot Neural Architecture Search via Self-Evaluated Template Network},
+ author = {Dong, Xuanyi and Yang, Yi},
+ booktitle = {Proceedings of the IEEE International Conference on Computer Vision (ICCV)},
+ pages = {3681--3690},
+ year = {2019}
+}
+@inproceedings{dong2019search,
+ title = {Searching for A Robust Neural Architecture in Four GPU Hours},
+ author = {Dong, Xuanyi and Yang, Yi},
+ booktitle = {Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},
+ pages = {1761--1770},
+ year = {2019}
+}
+```
+
+# 其他
+
+如果你想要给这份代码库做贡献,请看[CONTRIBUTING.md](../.github/CONTRIBUTING.md)。
+此外,使用规范请参考[CODE-OF-CONDUCT.md](../.github/CODE-OF-CONDUCT.md)。
+
+# 许可证
+The entire codebase is under [MIT license](../LICENSE.md)
diff --git a/AutoDL-Projects/docs/requirements.txt b/AutoDL-Projects/docs/requirements.txt
new file mode 100644
index 0000000..8724d60
--- /dev/null
+++ b/AutoDL-Projects/docs/requirements.txt
@@ -0,0 +1,5 @@
+torch
+torchvision
+
+nats_bench>=1.4
+nas_201_api
diff --git a/AutoDL-Projects/exps/NAS-Bench-201-algos/BOHB.py b/AutoDL-Projects/exps/NAS-Bench-201-algos/BOHB.py
new file mode 100644
index 0000000..86f740c
--- /dev/null
+++ b/AutoDL-Projects/exps/NAS-Bench-201-algos/BOHB.py
@@ -0,0 +1,367 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020 #
+###################################################################
+# BOHB: Robust and Efficient Hyperparameter Optimization at Scale #
+# required to install hpbandster ##################################
+# pip install hpbandster ##################################
+###################################################################
+# bash ./scripts-search/algos/BOHB.sh -1 ##################
+###################################################################
+import os, sys, time, random, argparse
+from copy import deepcopy
+from pathlib import Path
+import torch
+
+from xautodl.config_utils import load_config
+from xautodl.datasets import get_datasets, SearchDataset
+from xautodl.procedures import prepare_seed, prepare_logger
+from xautodl.log_utils import AverageMeter, time_string, convert_secs2time
+from xautodl.models import CellStructure, get_search_spaces
+from nas_201_api import NASBench201API as API
+
+# BOHB: Robust and Efficient Hyperparameter Optimization at Scale, ICML 2018
+import ConfigSpace
+from hpbandster.optimizers.bohb import BOHB
+import hpbandster.core.nameserver as hpns
+from hpbandster.core.worker import Worker
+
+
+def get_configuration_space(max_nodes, search_space):
+ cs = ConfigSpace.ConfigurationSpace()
+ # edge2index = {}
+ for i in range(1, max_nodes):
+ for j in range(i):
+ node_str = "{:}<-{:}".format(i, j)
+ cs.add_hyperparameter(
+ ConfigSpace.CategoricalHyperparameter(node_str, search_space)
+ )
+ return cs
+
+
+def config2structure_func(max_nodes):
+ def config2structure(config):
+ genotypes = []
+ for i in range(1, max_nodes):
+ xlist = []
+ for j in range(i):
+ node_str = "{:}<-{:}".format(i, j)
+ op_name = config[node_str]
+ xlist.append((op_name, j))
+ genotypes.append(tuple(xlist))
+ return CellStructure(genotypes)
+
+ return config2structure
+
+
+class MyWorker(Worker):
+ def __init__(
+ self,
+ *args,
+ convert_func=None,
+ dataname=None,
+ nas_bench=None,
+ time_budget=None,
+ **kwargs
+ ):
+ super().__init__(*args, **kwargs)
+ self.convert_func = convert_func
+ self._dataname = dataname
+ self._nas_bench = nas_bench
+ self.time_budget = time_budget
+ self.seen_archs = []
+ self.sim_cost_time = 0
+ self.real_cost_time = 0
+ self.is_end = False
+
+ def get_the_best(self):
+ assert len(self.seen_archs) > 0
+ best_index, best_acc = -1, None
+ for arch_index in self.seen_archs:
+ info = self._nas_bench.get_more_info(
+ arch_index, self._dataname, None, hp="200", is_random=True
+ )
+ vacc = info["valid-accuracy"]
+ if best_acc is None or best_acc < vacc:
+ best_acc = vacc
+ best_index = arch_index
+ assert best_index != -1
+ return best_index
+
+ def compute(self, config, budget, **kwargs):
+ start_time = time.time()
+ structure = self.convert_func(config)
+ arch_index = self._nas_bench.query_index_by_arch(structure)
+ info = self._nas_bench.get_more_info(
+ arch_index, self._dataname, None, hp="200", is_random=True
+ )
+ cur_time = info["train-all-time"] + info["valid-per-time"]
+ cur_vacc = info["valid-accuracy"]
+ self.real_cost_time += time.time() - start_time
+ if self.sim_cost_time + cur_time <= self.time_budget and not self.is_end:
+ self.sim_cost_time += cur_time
+ self.seen_archs.append(arch_index)
+ return {
+ "loss": 100 - float(cur_vacc),
+ "info": {
+ "seen-arch": len(self.seen_archs),
+ "sim-test-time": self.sim_cost_time,
+ "current-arch": arch_index,
+ },
+ }
+ else:
+ self.is_end = True
+ return {
+ "loss": 100,
+ "info": {
+ "seen-arch": len(self.seen_archs),
+ "sim-test-time": self.sim_cost_time,
+ "current-arch": None,
+ },
+ }
+
+
+def main(xargs, nas_bench):
+ assert torch.cuda.is_available(), "CUDA is not available."
+ torch.backends.cudnn.enabled = True
+ torch.backends.cudnn.benchmark = False
+ torch.backends.cudnn.deterministic = True
+ torch.set_num_threads(xargs.workers)
+ prepare_seed(xargs.rand_seed)
+ logger = prepare_logger(args)
+
+ if xargs.dataset == "cifar10":
+ dataname = "cifar10-valid"
+ else:
+ dataname = xargs.dataset
+ if xargs.data_path is not None:
+ train_data, valid_data, xshape, class_num = get_datasets(
+ xargs.dataset, xargs.data_path, -1
+ )
+ split_Fpath = "configs/nas-benchmark/cifar-split.txt"
+ cifar_split = load_config(split_Fpath, None, None)
+ train_split, valid_split = cifar_split.train, cifar_split.valid
+ logger.log("Load split file from {:}".format(split_Fpath))
+ config_path = "configs/nas-benchmark/algos/R-EA.config"
+ config = load_config(
+ config_path, {"class_num": class_num, "xshape": xshape}, logger
+ )
+ # To split data
+ train_data_v2 = deepcopy(train_data)
+ train_data_v2.transform = valid_data.transform
+ valid_data = train_data_v2
+ search_data = SearchDataset(xargs.dataset, train_data, train_split, valid_split)
+ # data loader
+ train_loader = torch.utils.data.DataLoader(
+ train_data,
+ batch_size=config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(train_split),
+ num_workers=xargs.workers,
+ pin_memory=True,
+ )
+ valid_loader = torch.utils.data.DataLoader(
+ valid_data,
+ batch_size=config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(valid_split),
+ num_workers=xargs.workers,
+ pin_memory=True,
+ )
+ logger.log(
+ "||||||| {:10s} ||||||| Train-Loader-Num={:}, Valid-Loader-Num={:}, batch size={:}".format(
+ xargs.dataset, len(train_loader), len(valid_loader), config.batch_size
+ )
+ )
+ logger.log("||||||| {:10s} ||||||| Config={:}".format(xargs.dataset, config))
+ extra_info = {
+ "config": config,
+ "train_loader": train_loader,
+ "valid_loader": valid_loader,
+ }
+ else:
+ config_path = "configs/nas-benchmark/algos/R-EA.config"
+ config = load_config(config_path, None, logger)
+ logger.log("||||||| {:10s} ||||||| Config={:}".format(xargs.dataset, config))
+ extra_info = {"config": config, "train_loader": None, "valid_loader": None}
+
+ # nas dataset load
+ assert xargs.arch_nas_dataset is not None and os.path.isfile(xargs.arch_nas_dataset)
+ search_space = get_search_spaces("cell", xargs.search_space_name)
+ cs = get_configuration_space(xargs.max_nodes, search_space)
+
+ config2structure = config2structure_func(xargs.max_nodes)
+ hb_run_id = "0"
+
+ NS = hpns.NameServer(run_id=hb_run_id, host="localhost", port=0)
+ ns_host, ns_port = NS.start()
+ num_workers = 1
+
+ # nas_bench = AANASBenchAPI(xargs.arch_nas_dataset)
+ # logger.log('{:} Create NAS-BENCH-API DONE'.format(time_string()))
+ workers = []
+ for i in range(num_workers):
+ w = MyWorker(
+ nameserver=ns_host,
+ nameserver_port=ns_port,
+ convert_func=config2structure,
+ dataname=dataname,
+ nas_bench=nas_bench,
+ time_budget=xargs.time_budget,
+ run_id=hb_run_id,
+ id=i,
+ )
+ w.run(background=True)
+ workers.append(w)
+
+ start_time = time.time()
+ bohb = BOHB(
+ configspace=cs,
+ run_id=hb_run_id,
+ eta=3,
+ min_budget=12,
+ max_budget=200,
+ nameserver=ns_host,
+ nameserver_port=ns_port,
+ num_samples=xargs.num_samples,
+ random_fraction=xargs.random_fraction,
+ bandwidth_factor=xargs.bandwidth_factor,
+ ping_interval=10,
+ min_bandwidth=xargs.min_bandwidth,
+ )
+
+ results = bohb.run(xargs.n_iters, min_n_workers=num_workers)
+
+ bohb.shutdown(shutdown_workers=True)
+ NS.shutdown()
+
+ real_cost_time = time.time() - start_time
+
+ id2config = results.get_id2config_mapping()
+ incumbent = results.get_incumbent_id()
+ logger.log(
+ "Best found configuration: {:} within {:.3f} s".format(
+ id2config[incumbent]["config"], real_cost_time
+ )
+ )
+ best_arch = config2structure(id2config[incumbent]["config"])
+
+ info = nas_bench.query_by_arch(best_arch, "200")
+ if info is None:
+ logger.log("Did not find this architecture : {:}.".format(best_arch))
+ else:
+ logger.log("{:}".format(info))
+ logger.log("-" * 100)
+
+ logger.log(
+ "workers : {:.1f}s with {:} archs".format(
+ workers[0].time_budget, len(workers[0].seen_archs)
+ )
+ )
+ logger.close()
+ return logger.log_dir, nas_bench.query_index_by_arch(best_arch), real_cost_time
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(
+ "BOHB: Robust and Efficient Hyperparameter Optimization at Scale"
+ )
+ parser.add_argument("--data_path", type=str, help="Path to dataset")
+ parser.add_argument(
+ "--dataset",
+ type=str,
+ choices=["cifar10", "cifar100", "ImageNet16-120"],
+ help="Choose between Cifar10/100 and ImageNet-16.",
+ )
+ # channels and number-of-cells
+ parser.add_argument("--search_space_name", type=str, help="The search space name.")
+ parser.add_argument("--max_nodes", type=int, help="The maximum number of nodes.")
+ parser.add_argument("--channel", type=int, help="The number of channels.")
+ parser.add_argument(
+ "--num_cells", type=int, help="The number of cells in one stage."
+ )
+ parser.add_argument(
+ "--time_budget",
+ type=int,
+ help="The total time cost budge for searching (in seconds).",
+ )
+ # BOHB
+ parser.add_argument(
+ "--strategy",
+ default="sampling",
+ type=str,
+ nargs="?",
+ help="optimization strategy for the acquisition function",
+ )
+ parser.add_argument(
+ "--min_bandwidth",
+ default=0.3,
+ type=float,
+ nargs="?",
+ help="minimum bandwidth for KDE",
+ )
+ parser.add_argument(
+ "--num_samples",
+ default=64,
+ type=int,
+ nargs="?",
+ help="number of samples for the acquisition function",
+ )
+ parser.add_argument(
+ "--random_fraction",
+ default=0.33,
+ type=float,
+ nargs="?",
+ help="fraction of random configurations",
+ )
+ parser.add_argument(
+ "--bandwidth_factor",
+ default=3,
+ type=int,
+ nargs="?",
+ help="factor multiplied to the bandwidth",
+ )
+ parser.add_argument(
+ "--n_iters",
+ default=100,
+ type=int,
+ nargs="?",
+ help="number of iterations for optimization method",
+ )
+ # log
+ parser.add_argument(
+ "--workers",
+ type=int,
+ default=2,
+ help="number of data loading workers (default: 2)",
+ )
+ parser.add_argument(
+ "--save_dir", type=str, help="Folder to save checkpoints and log."
+ )
+ parser.add_argument(
+ "--arch_nas_dataset",
+ type=str,
+ help="The path to load the architecture dataset (tiny-nas-benchmark).",
+ )
+ parser.add_argument("--print_freq", type=int, help="print frequency (default: 200)")
+ parser.add_argument("--rand_seed", type=int, help="manual seed")
+ args = parser.parse_args()
+ # if args.rand_seed is None or args.rand_seed < 0: args.rand_seed = random.randint(1, 100000)
+ if args.arch_nas_dataset is None or not os.path.isfile(args.arch_nas_dataset):
+ nas_bench = None
+ else:
+ print(
+ "{:} build NAS-Benchmark-API from {:}".format(
+ time_string(), args.arch_nas_dataset
+ )
+ )
+ nas_bench = API(args.arch_nas_dataset)
+ if args.rand_seed < 0:
+ save_dir, all_indexes, num, all_times = None, [], 500, []
+ for i in range(num):
+ print("{:} : {:03d}/{:03d}".format(time_string(), i, num))
+ args.rand_seed = random.randint(1, 100000)
+ save_dir, index, ctime = main(args, nas_bench)
+ all_indexes.append(index)
+ all_times.append(ctime)
+ print("\n average time : {:.3f} s".format(sum(all_times) / len(all_times)))
+ torch.save(all_indexes, save_dir / "results.pth")
+ else:
+ main(args, nas_bench)
diff --git a/AutoDL-Projects/exps/NAS-Bench-201-algos/DARTS-V1.py b/AutoDL-Projects/exps/NAS-Bench-201-algos/DARTS-V1.py
new file mode 100644
index 0000000..67441af
--- /dev/null
+++ b/AutoDL-Projects/exps/NAS-Bench-201-algos/DARTS-V1.py
@@ -0,0 +1,417 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020 #
+########################################################
+# DARTS: Differentiable Architecture Search, ICLR 2019 #
+########################################################
+import sys, time, random, argparse
+from copy import deepcopy
+import torch
+from pathlib import Path
+
+from xautodl.config_utils import load_config, dict2config, configure2str
+from xautodl.datasets import get_datasets, get_nas_search_loaders
+from xautodl.procedures import (
+ prepare_seed,
+ prepare_logger,
+ save_checkpoint,
+ copy_checkpoint,
+ get_optim_scheduler,
+)
+from xautodl.utils import get_model_infos, obtain_accuracy
+from xautodl.log_utils import AverageMeter, time_string, convert_secs2time
+from xautodl.models import get_cell_based_tiny_net, get_search_spaces
+from nas_201_api import NASBench201API as API
+
+
+def search_func(
+ xloader,
+ network,
+ criterion,
+ scheduler,
+ w_optimizer,
+ a_optimizer,
+ epoch_str,
+ print_freq,
+ logger,
+ gradient_clip,
+):
+ data_time, batch_time = AverageMeter(), AverageMeter()
+ base_losses, base_top1, base_top5 = AverageMeter(), AverageMeter(), AverageMeter()
+ arch_losses, arch_top1, arch_top5 = AverageMeter(), AverageMeter(), AverageMeter()
+ network.train()
+ end = time.time()
+ for step, (base_inputs, base_targets, arch_inputs, arch_targets) in enumerate(
+ xloader
+ ):
+ scheduler.update(None, 1.0 * step / len(xloader))
+ base_targets = base_targets.cuda(non_blocking=True)
+ arch_targets = arch_targets.cuda(non_blocking=True)
+ # measure data loading time
+ data_time.update(time.time() - end)
+
+ # update the weights
+ w_optimizer.zero_grad()
+ _, logits = network(base_inputs)
+ base_loss = criterion(logits, base_targets)
+ base_loss.backward()
+ if gradient_clip > 0:
+ torch.nn.utils.clip_grad_norm_(network.parameters(), gradient_clip)
+ w_optimizer.step()
+ # record
+ base_prec1, base_prec5 = obtain_accuracy(
+ logits.data, base_targets.data, topk=(1, 5)
+ )
+ base_losses.update(base_loss.item(), base_inputs.size(0))
+ base_top1.update(base_prec1.item(), base_inputs.size(0))
+ base_top5.update(base_prec5.item(), base_inputs.size(0))
+
+ # update the architecture-weight
+ a_optimizer.zero_grad()
+ _, logits = network(arch_inputs)
+ arch_loss = criterion(logits, arch_targets)
+ arch_loss.backward()
+ a_optimizer.step()
+ # record
+ arch_prec1, arch_prec5 = obtain_accuracy(
+ logits.data, arch_targets.data, topk=(1, 5)
+ )
+ arch_losses.update(arch_loss.item(), arch_inputs.size(0))
+ arch_top1.update(arch_prec1.item(), arch_inputs.size(0))
+ arch_top5.update(arch_prec5.item(), arch_inputs.size(0))
+
+ # measure elapsed time
+ batch_time.update(time.time() - end)
+ end = time.time()
+
+ if step % print_freq == 0 or step + 1 == len(xloader):
+ Sstr = (
+ "*SEARCH* "
+ + time_string()
+ + " [{:}][{:03d}/{:03d}]".format(epoch_str, step, len(xloader))
+ )
+ Tstr = "Time {batch_time.val:.2f} ({batch_time.avg:.2f}) Data {data_time.val:.2f} ({data_time.avg:.2f})".format(
+ batch_time=batch_time, data_time=data_time
+ )
+ Wstr = "Base [Loss {loss.val:.3f} ({loss.avg:.3f}) Prec@1 {top1.val:.2f} ({top1.avg:.2f}) Prec@5 {top5.val:.2f} ({top5.avg:.2f})]".format(
+ loss=base_losses, top1=base_top1, top5=base_top5
+ )
+ Astr = "Arch [Loss {loss.val:.3f} ({loss.avg:.3f}) Prec@1 {top1.val:.2f} ({top1.avg:.2f}) Prec@5 {top5.val:.2f} ({top5.avg:.2f})]".format(
+ loss=arch_losses, top1=arch_top1, top5=arch_top5
+ )
+ logger.log(Sstr + " " + Tstr + " " + Wstr + " " + Astr)
+ return base_losses.avg, base_top1.avg, base_top5.avg
+
+
+def valid_func(xloader, network, criterion):
+ data_time, batch_time = AverageMeter(), AverageMeter()
+ arch_losses, arch_top1, arch_top5 = AverageMeter(), AverageMeter(), AverageMeter()
+ network.eval()
+ end = time.time()
+ with torch.no_grad():
+ for step, (arch_inputs, arch_targets) in enumerate(xloader):
+ arch_targets = arch_targets.cuda(non_blocking=True)
+ # measure data loading time
+ data_time.update(time.time() - end)
+ # prediction
+ _, logits = network(arch_inputs)
+ arch_loss = criterion(logits, arch_targets)
+ # record
+ arch_prec1, arch_prec5 = obtain_accuracy(
+ logits.data, arch_targets.data, topk=(1, 5)
+ )
+ arch_losses.update(arch_loss.item(), arch_inputs.size(0))
+ arch_top1.update(arch_prec1.item(), arch_inputs.size(0))
+ arch_top5.update(arch_prec5.item(), arch_inputs.size(0))
+ # measure elapsed time
+ batch_time.update(time.time() - end)
+ end = time.time()
+ return arch_losses.avg, arch_top1.avg, arch_top5.avg
+
+
+def main(xargs):
+ assert torch.cuda.is_available(), "CUDA is not available."
+ torch.backends.cudnn.enabled = True
+ torch.backends.cudnn.benchmark = False
+ torch.backends.cudnn.deterministic = True
+ torch.set_num_threads(xargs.workers)
+ prepare_seed(xargs.rand_seed)
+ logger = prepare_logger(args)
+
+ train_data, valid_data, xshape, class_num = get_datasets(
+ xargs.dataset, xargs.data_path, -1
+ )
+ # config_path = 'configs/nas-benchmark/algos/DARTS.config'
+ config = load_config(
+ xargs.config_path, {"class_num": class_num, "xshape": xshape}, logger
+ )
+ search_loader, _, valid_loader = get_nas_search_loaders(
+ train_data,
+ valid_data,
+ xargs.dataset,
+ "configs/nas-benchmark/",
+ config.batch_size,
+ xargs.workers,
+ )
+ logger.log(
+ "||||||| {:10s} ||||||| Search-Loader-Num={:}, Valid-Loader-Num={:}, batch size={:}".format(
+ xargs.dataset, len(search_loader), len(valid_loader), config.batch_size
+ )
+ )
+ logger.log("||||||| {:10s} ||||||| Config={:}".format(xargs.dataset, config))
+
+ search_space = get_search_spaces("cell", xargs.search_space_name)
+ if xargs.model_config is None:
+ model_config = dict2config(
+ {
+ "name": "DARTS-V1",
+ "C": xargs.channel,
+ "N": xargs.num_cells,
+ "max_nodes": xargs.max_nodes,
+ "num_classes": class_num,
+ "space": search_space,
+ "affine": False,
+ "track_running_stats": bool(xargs.track_running_stats),
+ },
+ None,
+ )
+ else:
+ model_config = load_config(
+ xargs.model_config,
+ {
+ "num_classes": class_num,
+ "space": search_space,
+ "affine": False,
+ "track_running_stats": bool(xargs.track_running_stats),
+ },
+ None,
+ )
+ search_model = get_cell_based_tiny_net(model_config)
+ logger.log("search-model :\n{:}".format(search_model))
+
+ w_optimizer, w_scheduler, criterion = get_optim_scheduler(
+ search_model.get_weights(), config
+ )
+ a_optimizer = torch.optim.Adam(
+ search_model.get_alphas(),
+ lr=xargs.arch_learning_rate,
+ betas=(0.5, 0.999),
+ weight_decay=xargs.arch_weight_decay,
+ )
+ logger.log("w-optimizer : {:}".format(w_optimizer))
+ logger.log("a-optimizer : {:}".format(a_optimizer))
+ logger.log("w-scheduler : {:}".format(w_scheduler))
+ logger.log("criterion : {:}".format(criterion))
+ flop, param = get_model_infos(search_model, xshape)
+ # logger.log('{:}'.format(search_model))
+ logger.log("FLOP = {:.2f} M, Params = {:.2f} MB".format(flop, param))
+ if xargs.arch_nas_dataset is None:
+ api = None
+ else:
+ api = API(xargs.arch_nas_dataset)
+ logger.log("{:} create API = {:} done".format(time_string(), api))
+
+ last_info, model_base_path, model_best_path = (
+ logger.path("info"),
+ logger.path("model"),
+ logger.path("best"),
+ )
+ network, criterion = torch.nn.DataParallel(search_model).cuda(), criterion.cuda()
+
+ if last_info.exists(): # automatically resume from previous checkpoint
+ logger.log(
+ "=> loading checkpoint of the last-info '{:}' start".format(last_info)
+ )
+ last_info = torch.load(last_info)
+ start_epoch = last_info["epoch"]
+ checkpoint = torch.load(last_info["last_checkpoint"])
+ genotypes = checkpoint["genotypes"]
+ valid_accuracies = checkpoint["valid_accuracies"]
+ search_model.load_state_dict(checkpoint["search_model"])
+ w_scheduler.load_state_dict(checkpoint["w_scheduler"])
+ w_optimizer.load_state_dict(checkpoint["w_optimizer"])
+ a_optimizer.load_state_dict(checkpoint["a_optimizer"])
+ logger.log(
+ "=> loading checkpoint of the last-info '{:}' start with {:}-th epoch.".format(
+ last_info, start_epoch
+ )
+ )
+ else:
+ logger.log("=> do not find the last-info file : {:}".format(last_info))
+ start_epoch, valid_accuracies, genotypes = (
+ 0,
+ {"best": -1},
+ {-1: search_model.genotype()},
+ )
+
+ # start training
+ start_time, search_time, epoch_time, total_epoch = (
+ time.time(),
+ AverageMeter(),
+ AverageMeter(),
+ config.epochs + config.warmup,
+ )
+ for epoch in range(start_epoch, total_epoch):
+ w_scheduler.update(epoch, 0.0)
+ need_time = "Time Left: {:}".format(
+ convert_secs2time(epoch_time.val * (total_epoch - epoch), True)
+ )
+ epoch_str = "{:03d}-{:03d}".format(epoch, total_epoch)
+ logger.log(
+ "\n[Search the {:}-th epoch] {:}, LR={:}".format(
+ epoch_str, need_time, min(w_scheduler.get_lr())
+ )
+ )
+
+ search_w_loss, search_w_top1, search_w_top5 = search_func(
+ search_loader,
+ network,
+ criterion,
+ w_scheduler,
+ w_optimizer,
+ a_optimizer,
+ epoch_str,
+ xargs.print_freq,
+ logger,
+ xargs.gradient_clip,
+ )
+ search_time.update(time.time() - start_time)
+ logger.log(
+ "[{:}] searching : loss={:.2f}, accuracy@1={:.2f}%, accuracy@5={:.2f}%, time-cost={:.1f} s".format(
+ epoch_str, search_w_loss, search_w_top1, search_w_top5, search_time.sum
+ )
+ )
+ valid_a_loss, valid_a_top1, valid_a_top5 = valid_func(
+ valid_loader, network, criterion
+ )
+ logger.log(
+ "[{:}] evaluate : loss={:.2f}, accuracy@1={:.2f}%, accuracy@5={:.2f}%".format(
+ epoch_str, valid_a_loss, valid_a_top1, valid_a_top5
+ )
+ )
+ # check the best accuracy
+ valid_accuracies[epoch] = valid_a_top1
+ if valid_a_top1 > valid_accuracies["best"]:
+ valid_accuracies["best"] = valid_a_top1
+ genotypes["best"] = search_model.genotype()
+ find_best = True
+ else:
+ find_best = False
+
+ genotypes[epoch] = search_model.genotype()
+ logger.log(
+ "<<<--->>> The {:}-th epoch : {:}".format(epoch_str, genotypes[epoch])
+ )
+ # save checkpoint
+ save_path = save_checkpoint(
+ {
+ "epoch": epoch + 1,
+ "args": deepcopy(xargs),
+ "search_model": search_model.state_dict(),
+ "w_optimizer": w_optimizer.state_dict(),
+ "a_optimizer": a_optimizer.state_dict(),
+ "w_scheduler": w_scheduler.state_dict(),
+ "genotypes": genotypes,
+ "valid_accuracies": valid_accuracies,
+ },
+ model_base_path,
+ logger,
+ )
+ last_info = save_checkpoint(
+ {
+ "epoch": epoch + 1,
+ "args": deepcopy(args),
+ "last_checkpoint": save_path,
+ },
+ logger.path("info"),
+ logger,
+ )
+ if find_best:
+ logger.log(
+ "<<<--->>> The {:}-th epoch : find the highest validation accuracy : {:.2f}%.".format(
+ epoch_str, valid_a_top1
+ )
+ )
+ copy_checkpoint(model_base_path, model_best_path, logger)
+ with torch.no_grad():
+ # logger.log('arch-parameters :\n{:}'.format( nn.functional.softmax(search_model.arch_parameters, dim=-1).cpu() ))
+ logger.log("{:}".format(search_model.show_alphas()))
+ if api is not None:
+ logger.log("{:}".format(api.query_by_arch(genotypes[epoch], "200")))
+ # measure elapsed time
+ epoch_time.update(time.time() - start_time)
+ start_time = time.time()
+
+ logger.log("\n" + "-" * 100)
+ logger.log(
+ "DARTS-V1 : run {:} epochs, cost {:.1f} s, last-geno is {:}.".format(
+ total_epoch, search_time.sum, genotypes[total_epoch - 1]
+ )
+ )
+ if api is not None:
+ logger.log("{:}".format(api.query_by_arch(genotypes[total_epoch - 1], "200")))
+ logger.close()
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser("DARTS first order")
+ parser.add_argument("--data_path", type=str, help="Path to dataset")
+ parser.add_argument(
+ "--dataset",
+ type=str,
+ choices=["cifar10", "cifar100", "ImageNet16-120"],
+ help="Choose between Cifar10/100 and ImageNet-16.",
+ )
+ # channels and number-of-cells
+ parser.add_argument("--search_space_name", type=str, help="The search space name.")
+ parser.add_argument("--max_nodes", type=int, help="The maximum number of nodes.")
+ parser.add_argument("--channel", type=int, help="The number of channels.")
+ parser.add_argument(
+ "--num_cells", type=int, help="The number of cells in one stage."
+ )
+ parser.add_argument(
+ "--track_running_stats",
+ type=int,
+ choices=[0, 1],
+ help="Whether use track_running_stats or not in the BN layer.",
+ )
+ parser.add_argument("--config_path", type=str, help="The config path.")
+ parser.add_argument(
+ "--model_config",
+ type=str,
+ help="The path of the model configuration. When this arg is set, it will cover max_nodes / channels / num_cells.",
+ )
+ parser.add_argument("--gradient_clip", type=float, default=5, help="")
+ # architecture leraning rate
+ parser.add_argument(
+ "--arch_learning_rate",
+ type=float,
+ default=3e-4,
+ help="learning rate for arch encoding",
+ )
+ parser.add_argument(
+ "--arch_weight_decay",
+ type=float,
+ default=1e-3,
+ help="weight decay for arch encoding",
+ )
+ # log
+ parser.add_argument(
+ "--workers",
+ type=int,
+ default=2,
+ help="number of data loading workers (default: 2)",
+ )
+ parser.add_argument(
+ "--save_dir", type=str, help="Folder to save checkpoints and log."
+ )
+ parser.add_argument(
+ "--arch_nas_dataset",
+ type=str,
+ help="The path to load the architecture dataset (nas-benchmark).",
+ )
+ parser.add_argument("--print_freq", type=int, help="print frequency (default: 200)")
+ parser.add_argument("--rand_seed", type=int, help="manual seed")
+ args = parser.parse_args()
+ if args.rand_seed is None or args.rand_seed < 0:
+ args.rand_seed = random.randint(1, 100000)
+ main(args)
diff --git a/AutoDL-Projects/exps/NAS-Bench-201-algos/DARTS-V2.py b/AutoDL-Projects/exps/NAS-Bench-201-algos/DARTS-V2.py
new file mode 100644
index 0000000..0bec819
--- /dev/null
+++ b/AutoDL-Projects/exps/NAS-Bench-201-algos/DARTS-V2.py
@@ -0,0 +1,496 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020 #
+########################################################
+# DARTS: Differentiable Architecture Search, ICLR 2019 #
+########################################################
+import os, sys, time, glob, random, argparse
+import numpy as np
+from copy import deepcopy
+import torch
+import torch.nn as nn
+
+from xautodl.config_utils import load_config, dict2config, configure2str
+from xautodl.datasets import get_datasets, get_nas_search_loaders
+from xautodl.procedures import (
+ prepare_seed,
+ prepare_logger,
+ save_checkpoint,
+ copy_checkpoint,
+ get_optim_scheduler,
+)
+from xautodl.utils import get_model_infos, obtain_accuracy
+from xautodl.log_utils import AverageMeter, time_string, convert_secs2time
+from xautodl.models import get_cell_based_tiny_net, get_search_spaces
+from nas_201_api import NASBench201API as API
+
+
+def _concat(xs):
+ return torch.cat([x.view(-1) for x in xs])
+
+
+def _hessian_vector_product(
+ vector, network, criterion, base_inputs, base_targets, r=1e-2
+):
+ R = r / _concat(vector).norm()
+ for p, v in zip(network.module.get_weights(), vector):
+ p.data.add_(R, v)
+ _, logits = network(base_inputs)
+ loss = criterion(logits, base_targets)
+ grads_p = torch.autograd.grad(loss, network.module.get_alphas())
+
+ for p, v in zip(network.module.get_weights(), vector):
+ p.data.sub_(2 * R, v)
+ _, logits = network(base_inputs)
+ loss = criterion(logits, base_targets)
+ grads_n = torch.autograd.grad(loss, network.module.get_alphas())
+
+ for p, v in zip(network.module.get_weights(), vector):
+ p.data.add_(R, v)
+ return [(x - y).div_(2 * R) for x, y in zip(grads_p, grads_n)]
+
+
+def backward_step_unrolled(
+ network,
+ criterion,
+ base_inputs,
+ base_targets,
+ w_optimizer,
+ arch_inputs,
+ arch_targets,
+):
+ # _compute_unrolled_model
+ _, logits = network(base_inputs)
+ loss = criterion(logits, base_targets)
+ LR, WD, momentum = (
+ w_optimizer.param_groups[0]["lr"],
+ w_optimizer.param_groups[0]["weight_decay"],
+ w_optimizer.param_groups[0]["momentum"],
+ )
+ with torch.no_grad():
+ theta = _concat(network.module.get_weights())
+ try:
+ moment = _concat(
+ w_optimizer.state[v]["momentum_buffer"]
+ for v in network.module.get_weights()
+ )
+ moment = moment.mul_(momentum)
+ except:
+ moment = torch.zeros_like(theta)
+ dtheta = (
+ _concat(torch.autograd.grad(loss, network.module.get_weights()))
+ + WD * theta
+ )
+ params = theta.sub(LR, moment + dtheta)
+ unrolled_model = deepcopy(network)
+ model_dict = unrolled_model.state_dict()
+ new_params, offset = {}, 0
+ for k, v in network.named_parameters():
+ if "arch_parameters" in k:
+ continue
+ v_length = np.prod(v.size())
+ new_params[k] = params[offset : offset + v_length].view(v.size())
+ offset += v_length
+ model_dict.update(new_params)
+ unrolled_model.load_state_dict(model_dict)
+
+ unrolled_model.zero_grad()
+ _, unrolled_logits = unrolled_model(arch_inputs)
+ unrolled_loss = criterion(unrolled_logits, arch_targets)
+ unrolled_loss.backward()
+
+ dalpha = unrolled_model.module.arch_parameters.grad
+ vector = [v.grad.data for v in unrolled_model.module.get_weights()]
+ [implicit_grads] = _hessian_vector_product(
+ vector, network, criterion, base_inputs, base_targets
+ )
+
+ dalpha.data.sub_(LR, implicit_grads.data)
+
+ if network.module.arch_parameters.grad is None:
+ network.module.arch_parameters.grad = deepcopy(dalpha)
+ else:
+ network.module.arch_parameters.grad.data.copy_(dalpha.data)
+ return unrolled_loss.detach(), unrolled_logits.detach()
+
+
+def search_func(
+ xloader,
+ network,
+ criterion,
+ scheduler,
+ w_optimizer,
+ a_optimizer,
+ epoch_str,
+ print_freq,
+ logger,
+):
+ data_time, batch_time = AverageMeter(), AverageMeter()
+ base_losses, base_top1, base_top5 = AverageMeter(), AverageMeter(), AverageMeter()
+ arch_losses, arch_top1, arch_top5 = AverageMeter(), AverageMeter(), AverageMeter()
+ network.train()
+ end = time.time()
+ for step, (base_inputs, base_targets, arch_inputs, arch_targets) in enumerate(
+ xloader
+ ):
+ scheduler.update(None, 1.0 * step / len(xloader))
+ base_targets = base_targets.cuda(non_blocking=True)
+ arch_targets = arch_targets.cuda(non_blocking=True)
+ # measure data loading time
+ data_time.update(time.time() - end)
+
+ # update the architecture-weight
+ a_optimizer.zero_grad()
+ arch_loss, arch_logits = backward_step_unrolled(
+ network,
+ criterion,
+ base_inputs,
+ base_targets,
+ w_optimizer,
+ arch_inputs,
+ arch_targets,
+ )
+ a_optimizer.step()
+ # record
+ arch_prec1, arch_prec5 = obtain_accuracy(
+ arch_logits.data, arch_targets.data, topk=(1, 5)
+ )
+ arch_losses.update(arch_loss.item(), arch_inputs.size(0))
+ arch_top1.update(arch_prec1.item(), arch_inputs.size(0))
+ arch_top5.update(arch_prec5.item(), arch_inputs.size(0))
+
+ # update the weights
+ w_optimizer.zero_grad()
+ _, logits = network(base_inputs)
+ base_loss = criterion(logits, base_targets)
+ base_loss.backward()
+ torch.nn.utils.clip_grad_norm_(network.parameters(), 5)
+ w_optimizer.step()
+ # record
+ base_prec1, base_prec5 = obtain_accuracy(
+ logits.data, base_targets.data, topk=(1, 5)
+ )
+ base_losses.update(base_loss.item(), base_inputs.size(0))
+ base_top1.update(base_prec1.item(), base_inputs.size(0))
+ base_top5.update(base_prec5.item(), base_inputs.size(0))
+
+ # measure elapsed time
+ batch_time.update(time.time() - end)
+ end = time.time()
+
+ if step % print_freq == 0 or step + 1 == len(xloader):
+ Sstr = (
+ "*SEARCH* "
+ + time_string()
+ + " [{:}][{:03d}/{:03d}]".format(epoch_str, step, len(xloader))
+ )
+ Tstr = "Time {batch_time.val:.2f} ({batch_time.avg:.2f}) Data {data_time.val:.2f} ({data_time.avg:.2f})".format(
+ batch_time=batch_time, data_time=data_time
+ )
+ Wstr = "Base [Loss {loss.val:.3f} ({loss.avg:.3f}) Prec@1 {top1.val:.2f} ({top1.avg:.2f}) Prec@5 {top5.val:.2f} ({top5.avg:.2f})]".format(
+ loss=base_losses, top1=base_top1, top5=base_top5
+ )
+ Astr = "Arch [Loss {loss.val:.3f} ({loss.avg:.3f}) Prec@1 {top1.val:.2f} ({top1.avg:.2f}) Prec@5 {top5.val:.2f} ({top5.avg:.2f})]".format(
+ loss=arch_losses, top1=arch_top1, top5=arch_top5
+ )
+ logger.log(Sstr + " " + Tstr + " " + Wstr + " " + Astr)
+ return base_losses.avg, base_top1.avg, base_top5.avg
+
+
+def valid_func(xloader, network, criterion):
+ data_time, batch_time = AverageMeter(), AverageMeter()
+ arch_losses, arch_top1, arch_top5 = AverageMeter(), AverageMeter(), AverageMeter()
+ network.eval()
+ end = time.time()
+ with torch.no_grad():
+ for step, (arch_inputs, arch_targets) in enumerate(xloader):
+ arch_targets = arch_targets.cuda(non_blocking=True)
+ # measure data loading time
+ data_time.update(time.time() - end)
+ # prediction
+ _, logits = network(arch_inputs)
+ arch_loss = criterion(logits, arch_targets)
+ # record
+ arch_prec1, arch_prec5 = obtain_accuracy(
+ logits.data, arch_targets.data, topk=(1, 5)
+ )
+ arch_losses.update(arch_loss.item(), arch_inputs.size(0))
+ arch_top1.update(arch_prec1.item(), arch_inputs.size(0))
+ arch_top5.update(arch_prec5.item(), arch_inputs.size(0))
+ # measure elapsed time
+ batch_time.update(time.time() - end)
+ end = time.time()
+ return arch_losses.avg, arch_top1.avg, arch_top5.avg
+
+
+def main(xargs):
+ assert torch.cuda.is_available(), "CUDA is not available."
+ torch.backends.cudnn.enabled = True
+ torch.backends.cudnn.benchmark = False
+ torch.backends.cudnn.deterministic = True
+ torch.set_num_threads(xargs.workers)
+ prepare_seed(xargs.rand_seed)
+ logger = prepare_logger(args)
+
+ train_data, valid_data, xshape, class_num = get_datasets(
+ xargs.dataset, xargs.data_path, -1
+ )
+ config = load_config(
+ xargs.config_path, {"class_num": class_num, "xshape": xshape}, logger
+ )
+ search_loader, _, valid_loader = get_nas_search_loaders(
+ train_data,
+ valid_data,
+ xargs.dataset,
+ "configs/nas-benchmark/",
+ config.batch_size,
+ xargs.workers,
+ )
+ logger.log(
+ "||||||| {:10s} ||||||| Search-Loader-Num={:}, Valid-Loader-Num={:}, batch size={:}".format(
+ xargs.dataset, len(search_loader), len(valid_loader), config.batch_size
+ )
+ )
+ logger.log("||||||| {:10s} ||||||| Config={:}".format(xargs.dataset, config))
+
+ search_space = get_search_spaces("cell", xargs.search_space_name)
+ model_config = dict2config(
+ {
+ "name": "DARTS-V2",
+ "C": xargs.channel,
+ "N": xargs.num_cells,
+ "max_nodes": xargs.max_nodes,
+ "num_classes": class_num,
+ "space": search_space,
+ "affine": False,
+ "track_running_stats": bool(xargs.track_running_stats),
+ },
+ None,
+ )
+ search_model = get_cell_based_tiny_net(model_config)
+ logger.log("search-model :\n{:}".format(search_model))
+
+ w_optimizer, w_scheduler, criterion = get_optim_scheduler(
+ search_model.get_weights(), config
+ )
+ a_optimizer = torch.optim.Adam(
+ search_model.get_alphas(),
+ lr=xargs.arch_learning_rate,
+ betas=(0.5, 0.999),
+ weight_decay=xargs.arch_weight_decay,
+ )
+ logger.log("w-optimizer : {:}".format(w_optimizer))
+ logger.log("a-optimizer : {:}".format(a_optimizer))
+ logger.log("w-scheduler : {:}".format(w_scheduler))
+ logger.log("criterion : {:}".format(criterion))
+ flop, param = get_model_infos(search_model, xshape)
+ # logger.log('{:}'.format(search_model))
+ logger.log("FLOP = {:.2f} M, Params = {:.2f} MB".format(flop, param))
+ if xargs.arch_nas_dataset is None:
+ api = None
+ else:
+ api = API(xargs.arch_nas_dataset)
+ logger.log("{:} create API = {:} done".format(time_string(), api))
+
+ last_info, model_base_path, model_best_path = (
+ logger.path("info"),
+ logger.path("model"),
+ logger.path("best"),
+ )
+ network, criterion = torch.nn.DataParallel(search_model).cuda(), criterion.cuda()
+
+ if last_info.exists(): # automatically resume from previous checkpoint
+ logger.log(
+ "=> loading checkpoint of the last-info '{:}' start".format(last_info)
+ )
+ last_info = torch.load(last_info)
+ start_epoch = last_info["epoch"]
+ checkpoint = torch.load(last_info["last_checkpoint"])
+ genotypes = checkpoint["genotypes"]
+ valid_accuracies = checkpoint["valid_accuracies"]
+ search_model.load_state_dict(checkpoint["search_model"])
+ w_scheduler.load_state_dict(checkpoint["w_scheduler"])
+ w_optimizer.load_state_dict(checkpoint["w_optimizer"])
+ a_optimizer.load_state_dict(checkpoint["a_optimizer"])
+ logger.log(
+ "=> loading checkpoint of the last-info '{:}' start with {:}-th epoch.".format(
+ last_info, start_epoch
+ )
+ )
+ else:
+ logger.log("=> do not find the last-info file : {:}".format(last_info))
+ start_epoch, valid_accuracies, genotypes = (
+ 0,
+ {"best": -1},
+ {-1: search_model.genotype()},
+ )
+
+ # start training
+ start_time, search_time, epoch_time, total_epoch = (
+ time.time(),
+ AverageMeter(),
+ AverageMeter(),
+ config.epochs + config.warmup,
+ )
+ for epoch in range(start_epoch, total_epoch):
+ w_scheduler.update(epoch, 0.0)
+ need_time = "Time Left: {:}".format(
+ convert_secs2time(epoch_time.val * (total_epoch - epoch), True)
+ )
+ epoch_str = "{:03d}-{:03d}".format(epoch, total_epoch)
+ min_LR = min(w_scheduler.get_lr())
+ logger.log(
+ "\n[Search the {:}-th epoch] {:}, LR={:}".format(
+ epoch_str, need_time, min_LR
+ )
+ )
+
+ search_w_loss, search_w_top1, search_w_top5 = search_func(
+ search_loader,
+ network,
+ criterion,
+ w_scheduler,
+ w_optimizer,
+ a_optimizer,
+ epoch_str,
+ xargs.print_freq,
+ logger,
+ )
+ search_time.update(time.time() - start_time)
+ logger.log(
+ "[{:}] searching : loss={:.2f}, accuracy@1={:.2f}%, accuracy@5={:.2f}%, time-cost={:.1f} s".format(
+ epoch_str, search_w_loss, search_w_top1, search_w_top5, search_time.sum
+ )
+ )
+ valid_a_loss, valid_a_top1, valid_a_top5 = valid_func(
+ valid_loader, network, criterion
+ )
+ logger.log(
+ "[{:}] evaluate : loss={:.2f}, accuracy@1={:.2f}%, accuracy@5={:.2f}%".format(
+ epoch_str, valid_a_loss, valid_a_top1, valid_a_top5
+ )
+ )
+ # check the best accuracy
+ valid_accuracies[epoch] = valid_a_top1
+ if valid_a_top1 > valid_accuracies["best"]:
+ valid_accuracies["best"] = valid_a_top1
+ genotypes["best"] = search_model.genotype()
+ find_best = True
+ else:
+ find_best = False
+
+ genotypes[epoch] = search_model.genotype()
+ logger.log(
+ "<<<--->>> The {:}-th epoch : {:}".format(epoch_str, genotypes[epoch])
+ )
+ # save checkpoint
+ save_path = save_checkpoint(
+ {
+ "epoch": epoch + 1,
+ "args": deepcopy(xargs),
+ "search_model": search_model.state_dict(),
+ "w_optimizer": w_optimizer.state_dict(),
+ "a_optimizer": a_optimizer.state_dict(),
+ "w_scheduler": w_scheduler.state_dict(),
+ "genotypes": genotypes,
+ "valid_accuracies": valid_accuracies,
+ },
+ model_base_path,
+ logger,
+ )
+ last_info = save_checkpoint(
+ {
+ "epoch": epoch + 1,
+ "args": deepcopy(args),
+ "last_checkpoint": save_path,
+ },
+ logger.path("info"),
+ logger,
+ )
+ if find_best:
+ logger.log(
+ "<<<--->>> The {:}-th epoch : find the highest validation accuracy : {:.2f}%.".format(
+ epoch_str, valid_a_top1
+ )
+ )
+ copy_checkpoint(model_base_path, model_best_path, logger)
+ with torch.no_grad():
+ logger.log(
+ "arch-parameters :\n{:}".format(
+ nn.functional.softmax(search_model.arch_parameters, dim=-1).cpu()
+ )
+ )
+ if api is not None:
+ logger.log("{:}".format(api.query_by_arch(genotypes[epoch], "200")))
+ # measure elapsed time
+ epoch_time.update(time.time() - start_time)
+ start_time = time.time()
+
+ logger.log("\n" + "-" * 100)
+ # check the performance from the architecture dataset
+ logger.log(
+ "DARTS-V2 : run {:} epochs, cost {:.1f} s, last-geno is {:}.".format(
+ total_epoch, search_time.sum, genotypes[total_epoch - 1]
+ )
+ )
+ if api is not None:
+ logger.log("{:}".format(api.query_by_arch(genotypes[total_epoch - 1], "200")))
+ logger.close()
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser("DARTS Second Order")
+ parser.add_argument("--data_path", type=str, help="The path to dataset")
+ parser.add_argument(
+ "--dataset",
+ type=str,
+ choices=["cifar10", "cifar100", "ImageNet16-120"],
+ help="Choose between Cifar10/100 and ImageNet-16.",
+ )
+ # channels and number-of-cells
+ parser.add_argument("--config_path", type=str, help="The config path.")
+ parser.add_argument("--search_space_name", type=str, help="The search space name.")
+ parser.add_argument("--max_nodes", type=int, help="The maximum number of nodes.")
+ parser.add_argument("--channel", type=int, help="The number of channels.")
+ parser.add_argument(
+ "--num_cells", type=int, help="The number of cells in one stage."
+ )
+ parser.add_argument(
+ "--track_running_stats",
+ type=int,
+ choices=[0, 1],
+ help="Whether use track_running_stats or not in the BN layer.",
+ )
+ # architecture leraning rate
+ parser.add_argument(
+ "--arch_learning_rate",
+ type=float,
+ default=3e-4,
+ help="learning rate for arch encoding",
+ )
+ parser.add_argument(
+ "--arch_weight_decay",
+ type=float,
+ default=1e-3,
+ help="weight decay for arch encoding",
+ )
+ # log
+ parser.add_argument(
+ "--workers",
+ type=int,
+ default=2,
+ help="number of data loading workers (default: 2)",
+ )
+ parser.add_argument(
+ "--save_dir", type=str, help="Folder to save checkpoints and log."
+ )
+ parser.add_argument(
+ "--arch_nas_dataset",
+ type=str,
+ help="The path to load the architecture dataset (tiny-nas-benchmark).",
+ )
+ parser.add_argument("--print_freq", type=int, help="print frequency (default: 200)")
+ parser.add_argument("--rand_seed", type=int, help="manual seed")
+ args = parser.parse_args()
+ if args.rand_seed is None or args.rand_seed < 0:
+ args.rand_seed = random.randint(1, 100000)
+ main(args)
diff --git a/AutoDL-Projects/exps/NAS-Bench-201-algos/ENAS.py b/AutoDL-Projects/exps/NAS-Bench-201-algos/ENAS.py
new file mode 100644
index 0000000..43e4c1b
--- /dev/null
+++ b/AutoDL-Projects/exps/NAS-Bench-201-algos/ENAS.py
@@ -0,0 +1,578 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020 #
+##########################################################################
+# Efficient Neural Architecture Search via Parameters Sharing, ICML 2018 #
+##########################################################################
+import os, sys, time, glob, random, argparse
+import numpy as np
+from copy import deepcopy
+import torch
+import torch.nn as nn
+
+from xautodl.config_utils import load_config, dict2config, configure2str
+from xautodl.datasets import get_datasets, get_nas_search_loaders
+from xautodl.procedures import (
+ prepare_seed,
+ prepare_logger,
+ save_checkpoint,
+ copy_checkpoint,
+ get_optim_scheduler,
+)
+from xautodl.utils import get_model_infos, obtain_accuracy
+from xautodl.log_utils import AverageMeter, time_string, convert_secs2time
+from xautodl.models import get_cell_based_tiny_net, get_search_spaces
+from nas_201_api import NASBench201API as API
+
+
+def train_shared_cnn(
+ xloader,
+ shared_cnn,
+ controller,
+ criterion,
+ scheduler,
+ optimizer,
+ epoch_str,
+ print_freq,
+ logger,
+):
+ data_time, batch_time = AverageMeter(), AverageMeter()
+ losses, top1s, top5s, xend = (
+ AverageMeter(),
+ AverageMeter(),
+ AverageMeter(),
+ time.time(),
+ )
+
+ shared_cnn.train()
+ controller.eval()
+
+ for step, (inputs, targets) in enumerate(xloader):
+ scheduler.update(None, 1.0 * step / len(xloader))
+ targets = targets.cuda(non_blocking=True)
+ # measure data loading time
+ data_time.update(time.time() - xend)
+
+ with torch.no_grad():
+ _, _, sampled_arch = controller()
+
+ optimizer.zero_grad()
+ shared_cnn.module.update_arch(sampled_arch)
+ _, logits = shared_cnn(inputs)
+ loss = criterion(logits, targets)
+ loss.backward()
+ torch.nn.utils.clip_grad_norm_(shared_cnn.parameters(), 5)
+ optimizer.step()
+ # record
+ prec1, prec5 = obtain_accuracy(logits.data, targets.data, topk=(1, 5))
+ losses.update(loss.item(), inputs.size(0))
+ top1s.update(prec1.item(), inputs.size(0))
+ top5s.update(prec5.item(), inputs.size(0))
+
+ # measure elapsed time
+ batch_time.update(time.time() - xend)
+ xend = time.time()
+
+ if step % print_freq == 0 or step + 1 == len(xloader):
+ Sstr = (
+ "*Train-Shared-CNN* "
+ + time_string()
+ + " [{:}][{:03d}/{:03d}]".format(epoch_str, step, len(xloader))
+ )
+ Tstr = "Time {batch_time.val:.2f} ({batch_time.avg:.2f}) Data {data_time.val:.2f} ({data_time.avg:.2f})".format(
+ batch_time=batch_time, data_time=data_time
+ )
+ Wstr = "[Loss {loss.val:.3f} ({loss.avg:.3f}) Prec@1 {top1.val:.2f} ({top1.avg:.2f}) Prec@5 {top5.val:.2f} ({top5.avg:.2f})]".format(
+ loss=losses, top1=top1s, top5=top5s
+ )
+ logger.log(Sstr + " " + Tstr + " " + Wstr)
+ return losses.avg, top1s.avg, top5s.avg
+
+
+def train_controller(
+ xloader,
+ shared_cnn,
+ controller,
+ criterion,
+ optimizer,
+ config,
+ epoch_str,
+ print_freq,
+ logger,
+):
+ # config. (containing some necessary arg)
+ # baseline: The baseline score (i.e. average val_acc) from the previous epoch
+ data_time, batch_time = AverageMeter(), AverageMeter()
+ (
+ GradnormMeter,
+ LossMeter,
+ ValAccMeter,
+ EntropyMeter,
+ BaselineMeter,
+ RewardMeter,
+ xend,
+ ) = (
+ AverageMeter(),
+ AverageMeter(),
+ AverageMeter(),
+ AverageMeter(),
+ AverageMeter(),
+ AverageMeter(),
+ time.time(),
+ )
+
+ shared_cnn.eval()
+ controller.train()
+ controller.zero_grad()
+ # for step, (inputs, targets) in enumerate(xloader):
+ loader_iter = iter(xloader)
+ for step in range(config.ctl_train_steps * config.ctl_num_aggre):
+ try:
+ inputs, targets = next(loader_iter)
+ except:
+ loader_iter = iter(xloader)
+ inputs, targets = next(loader_iter)
+ targets = targets.cuda(non_blocking=True)
+ # measure data loading time
+ data_time.update(time.time() - xend)
+
+ log_prob, entropy, sampled_arch = controller()
+ with torch.no_grad():
+ shared_cnn.module.update_arch(sampled_arch)
+ _, logits = shared_cnn(inputs)
+ val_top1, val_top5 = obtain_accuracy(logits.data, targets.data, topk=(1, 5))
+ val_top1 = val_top1.view(-1) / 100
+ reward = val_top1 + config.ctl_entropy_w * entropy
+ if config.baseline is None:
+ baseline = val_top1
+ else:
+ baseline = config.baseline - (1 - config.ctl_bl_dec) * (
+ config.baseline - reward
+ )
+
+ loss = -1 * log_prob * (reward - baseline)
+
+ # account
+ RewardMeter.update(reward.item())
+ BaselineMeter.update(baseline.item())
+ ValAccMeter.update(val_top1.item() * 100)
+ LossMeter.update(loss.item())
+ EntropyMeter.update(entropy.item())
+
+ # Average gradient over controller_num_aggregate samples
+ loss = loss / config.ctl_num_aggre
+ loss.backward(retain_graph=True)
+
+ # measure elapsed time
+ batch_time.update(time.time() - xend)
+ xend = time.time()
+ if (step + 1) % config.ctl_num_aggre == 0:
+ grad_norm = torch.nn.utils.clip_grad_norm_(controller.parameters(), 5.0)
+ GradnormMeter.update(grad_norm)
+ optimizer.step()
+ controller.zero_grad()
+
+ if step % print_freq == 0:
+ Sstr = (
+ "*Train-Controller* "
+ + time_string()
+ + " [{:}][{:03d}/{:03d}]".format(
+ epoch_str, step, config.ctl_train_steps * config.ctl_num_aggre
+ )
+ )
+ Tstr = "Time {batch_time.val:.2f} ({batch_time.avg:.2f}) Data {data_time.val:.2f} ({data_time.avg:.2f})".format(
+ batch_time=batch_time, data_time=data_time
+ )
+ Wstr = "[Loss {loss.val:.3f} ({loss.avg:.3f}) Prec@1 {top1.val:.2f} ({top1.avg:.2f}) Reward {reward.val:.2f} ({reward.avg:.2f})] Baseline {basel.val:.2f} ({basel.avg:.2f})".format(
+ loss=LossMeter,
+ top1=ValAccMeter,
+ reward=RewardMeter,
+ basel=BaselineMeter,
+ )
+ Estr = "Entropy={:.4f} ({:.4f})".format(EntropyMeter.val, EntropyMeter.avg)
+ logger.log(Sstr + " " + Tstr + " " + Wstr + " " + Estr)
+
+ return (
+ LossMeter.avg,
+ ValAccMeter.avg,
+ BaselineMeter.avg,
+ RewardMeter.avg,
+ baseline.item(),
+ )
+
+
+def get_best_arch(controller, shared_cnn, xloader, n_samples=10):
+ with torch.no_grad():
+ controller.eval()
+ shared_cnn.eval()
+ archs, valid_accs = [], []
+ loader_iter = iter(xloader)
+ for i in range(n_samples):
+ try:
+ inputs, targets = next(loader_iter)
+ except:
+ loader_iter = iter(xloader)
+ inputs, targets = next(loader_iter)
+
+ _, _, sampled_arch = controller()
+ arch = shared_cnn.module.update_arch(sampled_arch)
+ _, logits = shared_cnn(inputs)
+ val_top1, val_top5 = obtain_accuracy(
+ logits.cpu().data, targets.data, topk=(1, 5)
+ )
+
+ archs.append(arch)
+ valid_accs.append(val_top1.item())
+
+ best_idx = np.argmax(valid_accs)
+ best_arch, best_valid_acc = archs[best_idx], valid_accs[best_idx]
+ return best_arch, best_valid_acc
+
+
+def valid_func(xloader, network, criterion):
+ data_time, batch_time = AverageMeter(), AverageMeter()
+ arch_losses, arch_top1, arch_top5 = AverageMeter(), AverageMeter(), AverageMeter()
+ network.eval()
+ end = time.time()
+ with torch.no_grad():
+ for step, (arch_inputs, arch_targets) in enumerate(xloader):
+ arch_targets = arch_targets.cuda(non_blocking=True)
+ # measure data loading time
+ data_time.update(time.time() - end)
+ # prediction
+ _, logits = network(arch_inputs)
+ arch_loss = criterion(logits, arch_targets)
+ # record
+ arch_prec1, arch_prec5 = obtain_accuracy(
+ logits.data, arch_targets.data, topk=(1, 5)
+ )
+ arch_losses.update(arch_loss.item(), arch_inputs.size(0))
+ arch_top1.update(arch_prec1.item(), arch_inputs.size(0))
+ arch_top5.update(arch_prec5.item(), arch_inputs.size(0))
+ # measure elapsed time
+ batch_time.update(time.time() - end)
+ end = time.time()
+ return arch_losses.avg, arch_top1.avg, arch_top5.avg
+
+
+def main(xargs):
+ assert torch.cuda.is_available(), "CUDA is not available."
+ torch.backends.cudnn.enabled = True
+ torch.backends.cudnn.benchmark = False
+ torch.backends.cudnn.deterministic = True
+ torch.set_num_threads(xargs.workers)
+ prepare_seed(xargs.rand_seed)
+ logger = prepare_logger(args)
+
+ train_data, test_data, xshape, class_num = get_datasets(
+ xargs.dataset, xargs.data_path, -1
+ )
+ logger.log("use config from : {:}".format(xargs.config_path))
+ config = load_config(
+ xargs.config_path, {"class_num": class_num, "xshape": xshape}, logger
+ )
+ _, train_loader, valid_loader = get_nas_search_loaders(
+ train_data,
+ test_data,
+ xargs.dataset,
+ "configs/nas-benchmark/",
+ config.batch_size,
+ xargs.workers,
+ )
+ # since ENAS will train the controller on valid-loader, we need to use train transformation for valid-loader
+ valid_loader.dataset.transform = deepcopy(train_loader.dataset.transform)
+ if hasattr(valid_loader.dataset, "transforms"):
+ valid_loader.dataset.transforms = deepcopy(train_loader.dataset.transforms)
+ # data loader
+ logger.log(
+ "||||||| {:10s} ||||||| Train-Loader-Num={:}, Valid-Loader-Num={:}, batch size={:}".format(
+ xargs.dataset, len(train_loader), len(valid_loader), config.batch_size
+ )
+ )
+ logger.log("||||||| {:10s} ||||||| Config={:}".format(xargs.dataset, config))
+
+ search_space = get_search_spaces("cell", xargs.search_space_name)
+ model_config = dict2config(
+ {
+ "name": "ENAS",
+ "C": xargs.channel,
+ "N": xargs.num_cells,
+ "max_nodes": xargs.max_nodes,
+ "num_classes": class_num,
+ "space": search_space,
+ "affine": False,
+ "track_running_stats": bool(xargs.track_running_stats),
+ },
+ None,
+ )
+ shared_cnn = get_cell_based_tiny_net(model_config)
+ controller = shared_cnn.create_controller()
+
+ w_optimizer, w_scheduler, criterion = get_optim_scheduler(
+ shared_cnn.parameters(), config
+ )
+ a_optimizer = torch.optim.Adam(
+ controller.parameters(),
+ lr=config.controller_lr,
+ betas=config.controller_betas,
+ eps=config.controller_eps,
+ )
+ logger.log("w-optimizer : {:}".format(w_optimizer))
+ logger.log("a-optimizer : {:}".format(a_optimizer))
+ logger.log("w-scheduler : {:}".format(w_scheduler))
+ logger.log("criterion : {:}".format(criterion))
+ # flop, param = get_model_infos(shared_cnn, xshape)
+ # logger.log('{:}'.format(shared_cnn))
+ # logger.log('FLOP = {:.2f} M, Params = {:.2f} MB'.format(flop, param))
+ logger.log("search-space : {:}".format(search_space))
+ if xargs.arch_nas_dataset is None:
+ api = None
+ else:
+ api = API(xargs.arch_nas_dataset)
+ logger.log("{:} create API = {:} done".format(time_string(), api))
+ shared_cnn, controller, criterion = (
+ torch.nn.DataParallel(shared_cnn).cuda(),
+ controller.cuda(),
+ criterion.cuda(),
+ )
+
+ last_info, model_base_path, model_best_path = (
+ logger.path("info"),
+ logger.path("model"),
+ logger.path("best"),
+ )
+
+ if last_info.exists(): # automatically resume from previous checkpoint
+ logger.log(
+ "=> loading checkpoint of the last-info '{:}' start".format(last_info)
+ )
+ last_info = torch.load(last_info)
+ start_epoch = last_info["epoch"]
+ checkpoint = torch.load(last_info["last_checkpoint"])
+ genotypes = checkpoint["genotypes"]
+ baseline = checkpoint["baseline"]
+ valid_accuracies = checkpoint["valid_accuracies"]
+ shared_cnn.load_state_dict(checkpoint["shared_cnn"])
+ controller.load_state_dict(checkpoint["controller"])
+ w_scheduler.load_state_dict(checkpoint["w_scheduler"])
+ w_optimizer.load_state_dict(checkpoint["w_optimizer"])
+ a_optimizer.load_state_dict(checkpoint["a_optimizer"])
+ logger.log(
+ "=> loading checkpoint of the last-info '{:}' start with {:}-th epoch.".format(
+ last_info, start_epoch
+ )
+ )
+ else:
+ logger.log("=> do not find the last-info file : {:}".format(last_info))
+ start_epoch, valid_accuracies, genotypes, baseline = 0, {"best": -1}, {}, None
+
+ # start training
+ start_time, search_time, epoch_time, total_epoch = (
+ time.time(),
+ AverageMeter(),
+ AverageMeter(),
+ config.epochs + config.warmup,
+ )
+ for epoch in range(start_epoch, total_epoch):
+ w_scheduler.update(epoch, 0.0)
+ need_time = "Time Left: {:}".format(
+ convert_secs2time(epoch_time.val * (total_epoch - epoch), True)
+ )
+ epoch_str = "{:03d}-{:03d}".format(epoch, total_epoch)
+ logger.log(
+ "\n[Search the {:}-th epoch] {:}, LR={:}, baseline={:}".format(
+ epoch_str, need_time, min(w_scheduler.get_lr()), baseline
+ )
+ )
+
+ cnn_loss, cnn_top1, cnn_top5 = train_shared_cnn(
+ train_loader,
+ shared_cnn,
+ controller,
+ criterion,
+ w_scheduler,
+ w_optimizer,
+ epoch_str,
+ xargs.print_freq,
+ logger,
+ )
+ logger.log(
+ "[{:}] shared-cnn : loss={:.2f}, accuracy@1={:.2f}%, accuracy@5={:.2f}%".format(
+ epoch_str, cnn_loss, cnn_top1, cnn_top5
+ )
+ )
+ ctl_loss, ctl_acc, ctl_baseline, ctl_reward, baseline = train_controller(
+ valid_loader,
+ shared_cnn,
+ controller,
+ criterion,
+ a_optimizer,
+ dict2config(
+ {
+ "baseline": baseline,
+ "ctl_train_steps": xargs.controller_train_steps,
+ "ctl_num_aggre": xargs.controller_num_aggregate,
+ "ctl_entropy_w": xargs.controller_entropy_weight,
+ "ctl_bl_dec": xargs.controller_bl_dec,
+ },
+ None,
+ ),
+ epoch_str,
+ xargs.print_freq,
+ logger,
+ )
+ search_time.update(time.time() - start_time)
+ logger.log(
+ "[{:}] controller : loss={:.2f}, accuracy={:.2f}%, baseline={:.2f}, reward={:.2f}, current-baseline={:.4f}, time-cost={:.1f} s".format(
+ epoch_str,
+ ctl_loss,
+ ctl_acc,
+ ctl_baseline,
+ ctl_reward,
+ baseline,
+ search_time.sum,
+ )
+ )
+ best_arch, _ = get_best_arch(controller, shared_cnn, valid_loader)
+ shared_cnn.module.update_arch(best_arch)
+ _, best_valid_acc, _ = valid_func(valid_loader, shared_cnn, criterion)
+
+ genotypes[epoch] = best_arch
+ # check the best accuracy
+ valid_accuracies[epoch] = best_valid_acc
+ if best_valid_acc > valid_accuracies["best"]:
+ valid_accuracies["best"] = best_valid_acc
+ genotypes["best"] = best_arch
+ find_best = True
+ else:
+ find_best = False
+
+ logger.log(
+ "<<<--->>> The {:}-th epoch : {:}".format(epoch_str, genotypes[epoch])
+ )
+ # save checkpoint
+ save_path = save_checkpoint(
+ {
+ "epoch": epoch + 1,
+ "args": deepcopy(xargs),
+ "baseline": baseline,
+ "shared_cnn": shared_cnn.state_dict(),
+ "controller": controller.state_dict(),
+ "w_optimizer": w_optimizer.state_dict(),
+ "a_optimizer": a_optimizer.state_dict(),
+ "w_scheduler": w_scheduler.state_dict(),
+ "genotypes": genotypes,
+ "valid_accuracies": valid_accuracies,
+ },
+ model_base_path,
+ logger,
+ )
+ last_info = save_checkpoint(
+ {
+ "epoch": epoch + 1,
+ "args": deepcopy(args),
+ "last_checkpoint": save_path,
+ },
+ logger.path("info"),
+ logger,
+ )
+ if find_best:
+ logger.log(
+ "<<<--->>> The {:}-th epoch : find the highest validation accuracy : {:.2f}%.".format(
+ epoch_str, best_valid_acc
+ )
+ )
+ copy_checkpoint(model_base_path, model_best_path, logger)
+ if api is not None:
+ logger.log("{:}".format(api.query_by_arch(genotypes[epoch], "200")))
+ # measure elapsed time
+ epoch_time.update(time.time() - start_time)
+ start_time = time.time()
+
+ logger.log("\n" + "-" * 100)
+ logger.log(
+ "During searching, the best architecture is {:}".format(genotypes["best"])
+ )
+ logger.log("Its accuracy is {:.2f}%".format(valid_accuracies["best"]))
+ logger.log(
+ "Randomly select {:} architectures and select the best.".format(
+ xargs.controller_num_samples
+ )
+ )
+ start_time = time.time()
+ final_arch, _ = get_best_arch(
+ controller, shared_cnn, valid_loader, xargs.controller_num_samples
+ )
+ search_time.update(time.time() - start_time)
+ shared_cnn.module.update_arch(final_arch)
+ final_loss, final_top1, final_top5 = valid_func(valid_loader, shared_cnn, criterion)
+ logger.log("The Selected Final Architecture : {:}".format(final_arch))
+ logger.log(
+ "Loss={:.3f}, Accuracy@1={:.2f}%, Accuracy@5={:.2f}%".format(
+ final_loss, final_top1, final_top5
+ )
+ )
+ logger.log(
+ "ENAS : run {:} epochs, cost {:.1f} s, last-geno is {:}.".format(
+ total_epoch, search_time.sum, final_arch
+ )
+ )
+ if api is not None:
+ logger.log("{:}".format(api.query_by_arch(final_arch)))
+ logger.close()
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser("ENAS")
+ parser.add_argument("--data_path", type=str, help="The path to dataset")
+ parser.add_argument(
+ "--dataset",
+ type=str,
+ choices=["cifar10", "cifar100", "ImageNet16-120"],
+ help="Choose between Cifar10/100 and ImageNet-16.",
+ )
+ # channels and number-of-cells
+ parser.add_argument(
+ "--track_running_stats",
+ type=int,
+ choices=[0, 1],
+ help="Whether use track_running_stats or not in the BN layer.",
+ )
+ parser.add_argument("--search_space_name", type=str, help="The search space name.")
+ parser.add_argument("--max_nodes", type=int, help="The maximum number of nodes.")
+ parser.add_argument("--channel", type=int, help="The number of channels.")
+ parser.add_argument(
+ "--num_cells", type=int, help="The number of cells in one stage."
+ )
+ parser.add_argument(
+ "--config_path", type=str, help="The config file to train ENAS."
+ )
+ parser.add_argument("--controller_train_steps", type=int, help=".")
+ parser.add_argument("--controller_num_aggregate", type=int, help=".")
+ parser.add_argument(
+ "--controller_entropy_weight",
+ type=float,
+ help="The weight for the entropy of the controller.",
+ )
+ parser.add_argument("--controller_bl_dec", type=float, help=".")
+ parser.add_argument("--controller_num_samples", type=int, help=".")
+ # log
+ parser.add_argument(
+ "--workers",
+ type=int,
+ default=2,
+ help="number of data loading workers (default: 2)",
+ )
+ parser.add_argument(
+ "--save_dir", type=str, help="Folder to save checkpoints and log."
+ )
+ parser.add_argument(
+ "--arch_nas_dataset",
+ type=str,
+ help="The path to load the architecture dataset (nas-benchmark).",
+ )
+ parser.add_argument("--print_freq", type=int, help="print frequency (default: 200)")
+ parser.add_argument("--rand_seed", type=int, help="manual seed")
+ args = parser.parse_args()
+ if args.rand_seed is None or args.rand_seed < 0:
+ args.rand_seed = random.randint(1, 100000)
+ main(args)
diff --git a/AutoDL-Projects/exps/NAS-Bench-201-algos/GDAS.py b/AutoDL-Projects/exps/NAS-Bench-201-algos/GDAS.py
new file mode 100644
index 0000000..d030cb8
--- /dev/null
+++ b/AutoDL-Projects/exps/NAS-Bench-201-algos/GDAS.py
@@ -0,0 +1,404 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020 #
+###########################################################################
+# Searching for A Robust Neural Architecture in Four GPU Hours, CVPR 2019 #
+###########################################################################
+import sys, time, random, argparse
+from copy import deepcopy
+import torch
+from xautodl.config_utils import load_config, dict2config
+from xautodl.datasets import get_datasets, get_nas_search_loaders
+from xautodl.procedures import (
+ prepare_seed,
+ prepare_logger,
+ save_checkpoint,
+ copy_checkpoint,
+ get_optim_scheduler,
+)
+from xautodl.utils import get_model_infos, obtain_accuracy
+from xautodl.log_utils import AverageMeter, time_string, convert_secs2time
+from xautodl.models import get_cell_based_tiny_net, get_search_spaces
+from nas_201_api import NASBench201API as API
+
+
+def search_func(
+ xloader,
+ network,
+ criterion,
+ scheduler,
+ w_optimizer,
+ a_optimizer,
+ epoch_str,
+ print_freq,
+ logger,
+):
+ data_time, batch_time = AverageMeter(), AverageMeter()
+ base_losses, base_top1, base_top5 = AverageMeter(), AverageMeter(), AverageMeter()
+ arch_losses, arch_top1, arch_top5 = AverageMeter(), AverageMeter(), AverageMeter()
+ network.train()
+ end = time.time()
+ for step, (base_inputs, base_targets, arch_inputs, arch_targets) in enumerate(
+ xloader
+ ):
+ scheduler.update(None, 1.0 * step / len(xloader))
+ base_targets = base_targets.cuda(non_blocking=True)
+ arch_targets = arch_targets.cuda(non_blocking=True)
+ # measure data loading time
+ data_time.update(time.time() - end)
+
+ # update the weights
+ w_optimizer.zero_grad()
+ _, logits = network(base_inputs)
+ base_loss = criterion(logits, base_targets)
+ base_loss.backward()
+ torch.nn.utils.clip_grad_norm_(network.parameters(), 5)
+ w_optimizer.step()
+ # record
+ base_prec1, base_prec5 = obtain_accuracy(
+ logits.data, base_targets.data, topk=(1, 5)
+ )
+ base_losses.update(base_loss.item(), base_inputs.size(0))
+ base_top1.update(base_prec1.item(), base_inputs.size(0))
+ base_top5.update(base_prec5.item(), base_inputs.size(0))
+
+ # update the architecture-weight
+ a_optimizer.zero_grad()
+ _, logits = network(arch_inputs)
+ arch_loss = criterion(logits, arch_targets)
+ arch_loss.backward()
+ a_optimizer.step()
+ # record
+ arch_prec1, arch_prec5 = obtain_accuracy(
+ logits.data, arch_targets.data, topk=(1, 5)
+ )
+ arch_losses.update(arch_loss.item(), arch_inputs.size(0))
+ arch_top1.update(arch_prec1.item(), arch_inputs.size(0))
+ arch_top5.update(arch_prec5.item(), arch_inputs.size(0))
+
+ # measure elapsed time
+ batch_time.update(time.time() - end)
+ end = time.time()
+
+ if step % print_freq == 0 or step + 1 == len(xloader):
+ Sstr = (
+ "*SEARCH* "
+ + time_string()
+ + " [{:}][{:03d}/{:03d}]".format(epoch_str, step, len(xloader))
+ )
+ Tstr = "Time {batch_time.val:.2f} ({batch_time.avg:.2f}) Data {data_time.val:.2f} ({data_time.avg:.2f})".format(
+ batch_time=batch_time, data_time=data_time
+ )
+ Wstr = "Base [Loss {loss.val:.3f} ({loss.avg:.3f}) Prec@1 {top1.val:.2f} ({top1.avg:.2f}) Prec@5 {top5.val:.2f} ({top5.avg:.2f})]".format(
+ loss=base_losses, top1=base_top1, top5=base_top5
+ )
+ Astr = "Arch [Loss {loss.val:.3f} ({loss.avg:.3f}) Prec@1 {top1.val:.2f} ({top1.avg:.2f}) Prec@5 {top5.val:.2f} ({top5.avg:.2f})]".format(
+ loss=arch_losses, top1=arch_top1, top5=arch_top5
+ )
+ logger.log(Sstr + " " + Tstr + " " + Wstr + " " + Astr)
+ return (
+ base_losses.avg,
+ base_top1.avg,
+ base_top5.avg,
+ arch_losses.avg,
+ arch_top1.avg,
+ arch_top5.avg,
+ )
+
+
+def main(xargs):
+ assert torch.cuda.is_available(), "CUDA is not available."
+ torch.backends.cudnn.enabled = True
+ torch.backends.cudnn.benchmark = False
+ torch.backends.cudnn.deterministic = True
+ torch.set_num_threads(xargs.workers)
+ prepare_seed(xargs.rand_seed)
+ logger = prepare_logger(args)
+
+ train_data, valid_data, xshape, class_num = get_datasets(
+ xargs.dataset, xargs.data_path, -1
+ )
+ # config_path = 'configs/nas-benchmark/algos/GDAS.config'
+ config = load_config(
+ xargs.config_path, {"class_num": class_num, "xshape": xshape}, logger
+ )
+ search_loader, _, valid_loader = get_nas_search_loaders(
+ train_data,
+ valid_data,
+ xargs.dataset,
+ "configs/nas-benchmark/",
+ config.batch_size,
+ xargs.workers,
+ )
+ logger.log(
+ "||||||| {:10s} ||||||| Search-Loader-Num={:}, batch size={:}".format(
+ xargs.dataset, len(search_loader), config.batch_size
+ )
+ )
+ logger.log("||||||| {:10s} ||||||| Config={:}".format(xargs.dataset, config))
+
+ search_space = get_search_spaces("cell", xargs.search_space_name)
+ if xargs.model_config is None:
+ model_config = dict2config(
+ {
+ "name": "GDAS",
+ "C": xargs.channel,
+ "N": xargs.num_cells,
+ "max_nodes": xargs.max_nodes,
+ "num_classes": class_num,
+ "space": search_space,
+ "affine": False,
+ "track_running_stats": bool(xargs.track_running_stats),
+ },
+ None,
+ )
+ else:
+ model_config = load_config(
+ xargs.model_config,
+ {
+ "num_classes": class_num,
+ "space": search_space,
+ "affine": False,
+ "track_running_stats": bool(xargs.track_running_stats),
+ },
+ None,
+ )
+ search_model = get_cell_based_tiny_net(model_config)
+ logger.log("search-model :\n{:}".format(search_model))
+ logger.log("model-config : {:}".format(model_config))
+
+ w_optimizer, w_scheduler, criterion = get_optim_scheduler(
+ search_model.get_weights(), config
+ )
+ a_optimizer = torch.optim.Adam(
+ search_model.get_alphas(),
+ lr=xargs.arch_learning_rate,
+ betas=(0.5, 0.999),
+ weight_decay=xargs.arch_weight_decay,
+ )
+ logger.log("w-optimizer : {:}".format(w_optimizer))
+ logger.log("a-optimizer : {:}".format(a_optimizer))
+ logger.log("w-scheduler : {:}".format(w_scheduler))
+ logger.log("criterion : {:}".format(criterion))
+ flop, param = get_model_infos(search_model, xshape)
+ logger.log("FLOP = {:.2f} M, Params = {:.2f} MB".format(flop, param))
+ logger.log("search-space [{:} ops] : {:}".format(len(search_space), search_space))
+ if xargs.arch_nas_dataset is None:
+ api = None
+ else:
+ api = API(xargs.arch_nas_dataset)
+ logger.log("{:} create API = {:} done".format(time_string(), api))
+
+ last_info, model_base_path, model_best_path = (
+ logger.path("info"),
+ logger.path("model"),
+ logger.path("best"),
+ )
+ network, criterion = torch.nn.DataParallel(search_model).cuda(), criterion.cuda()
+
+ if last_info.exists(): # automatically resume from previous checkpoint
+ logger.log(
+ "=> loading checkpoint of the last-info '{:}' start".format(last_info)
+ )
+ last_info = torch.load(last_info)
+ start_epoch = last_info["epoch"]
+ checkpoint = torch.load(last_info["last_checkpoint"])
+ genotypes = checkpoint["genotypes"]
+ valid_accuracies = checkpoint["valid_accuracies"]
+ search_model.load_state_dict(checkpoint["search_model"])
+ w_scheduler.load_state_dict(checkpoint["w_scheduler"])
+ w_optimizer.load_state_dict(checkpoint["w_optimizer"])
+ a_optimizer.load_state_dict(checkpoint["a_optimizer"])
+ logger.log(
+ "=> loading checkpoint of the last-info '{:}' start with {:}-th epoch.".format(
+ last_info, start_epoch
+ )
+ )
+ else:
+ logger.log("=> do not find the last-info file : {:}".format(last_info))
+ start_epoch, valid_accuracies, genotypes = (
+ 0,
+ {"best": -1},
+ {-1: search_model.genotype()},
+ )
+
+ # start training
+ start_time, search_time, epoch_time, total_epoch = (
+ time.time(),
+ AverageMeter(),
+ AverageMeter(),
+ config.epochs + config.warmup,
+ )
+ for epoch in range(start_epoch, total_epoch):
+ w_scheduler.update(epoch, 0.0)
+ need_time = "Time Left: {:}".format(
+ convert_secs2time(epoch_time.val * (total_epoch - epoch), True)
+ )
+ epoch_str = "{:03d}-{:03d}".format(epoch, total_epoch)
+ search_model.set_tau(
+ xargs.tau_max - (xargs.tau_max - xargs.tau_min) * epoch / (total_epoch - 1)
+ )
+ logger.log(
+ "\n[Search the {:}-th epoch] {:}, tau={:}, LR={:}".format(
+ epoch_str, need_time, search_model.get_tau(), min(w_scheduler.get_lr())
+ )
+ )
+
+ (
+ search_w_loss,
+ search_w_top1,
+ search_w_top5,
+ valid_a_loss,
+ valid_a_top1,
+ valid_a_top5,
+ ) = search_func(
+ search_loader,
+ network,
+ criterion,
+ w_scheduler,
+ w_optimizer,
+ a_optimizer,
+ epoch_str,
+ xargs.print_freq,
+ logger,
+ )
+ search_time.update(time.time() - start_time)
+ logger.log(
+ "[{:}] searching : loss={:.2f}, accuracy@1={:.2f}%, accuracy@5={:.2f}%, time-cost={:.1f} s".format(
+ epoch_str, search_w_loss, search_w_top1, search_w_top5, search_time.sum
+ )
+ )
+ logger.log(
+ "[{:}] evaluate : loss={:.2f}, accuracy@1={:.2f}%, accuracy@5={:.2f}%".format(
+ epoch_str, valid_a_loss, valid_a_top1, valid_a_top5
+ )
+ )
+ # check the best accuracy
+ valid_accuracies[epoch] = valid_a_top1
+ if valid_a_top1 > valid_accuracies["best"]:
+ valid_accuracies["best"] = valid_a_top1
+ genotypes["best"] = search_model.genotype()
+ find_best = True
+ else:
+ find_best = False
+
+ genotypes[epoch] = search_model.genotype()
+ logger.log(
+ "<<<--->>> The {:}-th epoch : {:}".format(epoch_str, genotypes[epoch])
+ )
+ # save checkpoint
+ save_path = save_checkpoint(
+ {
+ "epoch": epoch + 1,
+ "args": deepcopy(xargs),
+ "search_model": search_model.state_dict(),
+ "w_optimizer": w_optimizer.state_dict(),
+ "a_optimizer": a_optimizer.state_dict(),
+ "w_scheduler": w_scheduler.state_dict(),
+ "genotypes": genotypes,
+ "valid_accuracies": valid_accuracies,
+ },
+ model_base_path,
+ logger,
+ )
+ last_info = save_checkpoint(
+ {
+ "epoch": epoch + 1,
+ "args": deepcopy(args),
+ "last_checkpoint": save_path,
+ },
+ logger.path("info"),
+ logger,
+ )
+ if find_best:
+ logger.log(
+ "<<<--->>> The {:}-th epoch : find the highest validation accuracy : {:.2f}%.".format(
+ epoch_str, valid_a_top1
+ )
+ )
+ copy_checkpoint(model_base_path, model_best_path, logger)
+ with torch.no_grad():
+ logger.log("{:}".format(search_model.show_alphas()))
+ if api is not None:
+ logger.log("{:}".format(api.query_by_arch(genotypes[epoch], "200")))
+ # measure elapsed time
+ epoch_time.update(time.time() - start_time)
+ start_time = time.time()
+
+ logger.log("\n" + "-" * 100)
+ # check the performance from the architecture dataset
+ logger.log(
+ "GDAS : run {:} epochs, cost {:.1f} s, last-geno is {:}.".format(
+ total_epoch, search_time.sum, genotypes[total_epoch - 1]
+ )
+ )
+ if api is not None:
+ logger.log("{:}".format(api.query_by_arch(genotypes[total_epoch - 1], "200")))
+ logger.close()
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser("GDAS")
+ parser.add_argument("--data_path", type=str, help="The path to dataset")
+ parser.add_argument(
+ "--dataset",
+ type=str,
+ choices=["cifar10", "cifar100", "ImageNet16-120"],
+ help="Choose between Cifar10/100 and ImageNet-16.",
+ )
+ # channels and number-of-cells
+ parser.add_argument("--search_space_name", type=str, help="The search space name.")
+ parser.add_argument("--max_nodes", type=int, help="The maximum number of nodes.")
+ parser.add_argument("--channel", type=int, help="The number of channels.")
+ parser.add_argument(
+ "--num_cells", type=int, help="The number of cells in one stage."
+ )
+ parser.add_argument(
+ "--track_running_stats",
+ type=int,
+ choices=[0, 1],
+ help="Whether use track_running_stats or not in the BN layer.",
+ )
+ parser.add_argument(
+ "--config_path", type=str, help="The path of the configuration."
+ )
+ parser.add_argument(
+ "--model_config",
+ type=str,
+ help="The path of the model configuration. When this arg is set, it will cover max_nodes / channels / num_cells.",
+ )
+ # architecture leraning rate
+ parser.add_argument(
+ "--arch_learning_rate",
+ type=float,
+ default=3e-4,
+ help="learning rate for arch encoding",
+ )
+ parser.add_argument(
+ "--arch_weight_decay",
+ type=float,
+ default=1e-3,
+ help="weight decay for arch encoding",
+ )
+ parser.add_argument("--tau_min", type=float, help="The minimum tau for Gumbel")
+ parser.add_argument("--tau_max", type=float, help="The maximum tau for Gumbel")
+ # log
+ parser.add_argument(
+ "--workers",
+ type=int,
+ default=2,
+ help="number of data loading workers (default: 2)",
+ )
+ parser.add_argument(
+ "--save_dir", type=str, help="Folder to save checkpoints and log."
+ )
+ parser.add_argument(
+ "--arch_nas_dataset",
+ type=str,
+ help="The path to load the architecture dataset (tiny-nas-benchmark).",
+ )
+ parser.add_argument("--print_freq", type=int, help="print frequency (default: 200)")
+ parser.add_argument("--rand_seed", type=int, help="manual seed")
+ args = parser.parse_args()
+ if args.rand_seed is None or args.rand_seed < 0:
+ args.rand_seed = random.randint(1, 100000)
+ main(args)
diff --git a/AutoDL-Projects/exps/NAS-Bench-201-algos/RANDOM-NAS.py b/AutoDL-Projects/exps/NAS-Bench-201-algos/RANDOM-NAS.py
new file mode 100644
index 0000000..51192b4
--- /dev/null
+++ b/AutoDL-Projects/exps/NAS-Bench-201-algos/RANDOM-NAS.py
@@ -0,0 +1,382 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020 #
+##############################################################################
+# Random Search and Reproducibility for Neural Architecture Search, UAI 2019 #
+##############################################################################
+import os, sys, time, glob, random, argparse
+import numpy as np
+from copy import deepcopy
+import torch
+import torch.nn as nn
+
+from xautodl.config_utils import load_config, dict2config, configure2str
+from xautodl.datasets import get_datasets, get_nas_search_loaders
+from xautodl.procedures import (
+ prepare_seed,
+ prepare_logger,
+ save_checkpoint,
+ copy_checkpoint,
+ get_optim_scheduler,
+)
+from xautodl.utils import get_model_infos, obtain_accuracy
+from xautodl.log_utils import AverageMeter, time_string, convert_secs2time
+from xautodl.models import get_cell_based_tiny_net, get_search_spaces
+from nas_201_api import NASBench201API as API
+
+
+def search_func(
+ xloader, network, criterion, scheduler, w_optimizer, epoch_str, print_freq, logger
+):
+ data_time, batch_time = AverageMeter(), AverageMeter()
+ base_losses, base_top1, base_top5 = AverageMeter(), AverageMeter(), AverageMeter()
+ network.train()
+ end = time.time()
+ for step, (base_inputs, base_targets, arch_inputs, arch_targets) in enumerate(
+ xloader
+ ):
+ scheduler.update(None, 1.0 * step / len(xloader))
+ base_targets = base_targets.cuda(non_blocking=True)
+ arch_targets = arch_targets.cuda(non_blocking=True)
+ # measure data loading time
+ data_time.update(time.time() - end)
+
+ # update the weights
+ network.module.random_genotype(True)
+ w_optimizer.zero_grad()
+ _, logits = network(base_inputs)
+ base_loss = criterion(logits, base_targets)
+ base_loss.backward()
+ nn.utils.clip_grad_norm_(network.parameters(), 5)
+ w_optimizer.step()
+ # record
+ base_prec1, base_prec5 = obtain_accuracy(
+ logits.data, base_targets.data, topk=(1, 5)
+ )
+ base_losses.update(base_loss.item(), base_inputs.size(0))
+ base_top1.update(base_prec1.item(), base_inputs.size(0))
+ base_top5.update(base_prec5.item(), base_inputs.size(0))
+
+ # measure elapsed time
+ batch_time.update(time.time() - end)
+ end = time.time()
+
+ if step % print_freq == 0 or step + 1 == len(xloader):
+ Sstr = (
+ "*SEARCH* "
+ + time_string()
+ + " [{:}][{:03d}/{:03d}]".format(epoch_str, step, len(xloader))
+ )
+ Tstr = "Time {batch_time.val:.2f} ({batch_time.avg:.2f}) Data {data_time.val:.2f} ({data_time.avg:.2f})".format(
+ batch_time=batch_time, data_time=data_time
+ )
+ Wstr = "Base [Loss {loss.val:.3f} ({loss.avg:.3f}) Prec@1 {top1.val:.2f} ({top1.avg:.2f}) Prec@5 {top5.val:.2f} ({top5.avg:.2f})]".format(
+ loss=base_losses, top1=base_top1, top5=base_top5
+ )
+ logger.log(Sstr + " " + Tstr + " " + Wstr)
+ return base_losses.avg, base_top1.avg, base_top5.avg
+
+
+def valid_func(xloader, network, criterion):
+ data_time, batch_time = AverageMeter(), AverageMeter()
+ arch_losses, arch_top1, arch_top5 = AverageMeter(), AverageMeter(), AverageMeter()
+ network.eval()
+ end = time.time()
+ with torch.no_grad():
+ for step, (arch_inputs, arch_targets) in enumerate(xloader):
+ arch_targets = arch_targets.cuda(non_blocking=True)
+ # measure data loading time
+ data_time.update(time.time() - end)
+ # prediction
+
+ network.module.random_genotype(True)
+ _, logits = network(arch_inputs)
+ arch_loss = criterion(logits, arch_targets)
+ # record
+ arch_prec1, arch_prec5 = obtain_accuracy(
+ logits.data, arch_targets.data, topk=(1, 5)
+ )
+ arch_losses.update(arch_loss.item(), arch_inputs.size(0))
+ arch_top1.update(arch_prec1.item(), arch_inputs.size(0))
+ arch_top5.update(arch_prec5.item(), arch_inputs.size(0))
+ # measure elapsed time
+ batch_time.update(time.time() - end)
+ end = time.time()
+ return arch_losses.avg, arch_top1.avg, arch_top5.avg
+
+
+def search_find_best(xloader, network, n_samples):
+ with torch.no_grad():
+ network.eval()
+ archs, valid_accs = [], []
+ # print ('obtain the top-{:} architectures'.format(n_samples))
+ loader_iter = iter(xloader)
+ for i in range(n_samples):
+ arch = network.module.random_genotype(True)
+ try:
+ inputs, targets = next(loader_iter)
+ except:
+ loader_iter = iter(xloader)
+ inputs, targets = next(loader_iter)
+
+ _, logits = network(inputs)
+ val_top1, val_top5 = obtain_accuracy(
+ logits.cpu().data, targets.data, topk=(1, 5)
+ )
+
+ archs.append(arch)
+ valid_accs.append(val_top1.item())
+
+ best_idx = np.argmax(valid_accs)
+ best_arch, best_valid_acc = archs[best_idx], valid_accs[best_idx]
+ return best_arch, best_valid_acc
+
+
+def main(xargs):
+ assert torch.cuda.is_available(), "CUDA is not available."
+ torch.backends.cudnn.enabled = True
+ torch.backends.cudnn.benchmark = False
+ torch.backends.cudnn.deterministic = True
+ torch.set_num_threads(xargs.workers)
+ prepare_seed(xargs.rand_seed)
+ logger = prepare_logger(args)
+
+ train_data, valid_data, xshape, class_num = get_datasets(
+ xargs.dataset, xargs.data_path, -1
+ )
+ config = load_config(
+ xargs.config_path, {"class_num": class_num, "xshape": xshape}, logger
+ )
+ search_loader, _, valid_loader = get_nas_search_loaders(
+ train_data,
+ valid_data,
+ xargs.dataset,
+ "configs/nas-benchmark/",
+ (config.batch_size, config.test_batch_size),
+ xargs.workers,
+ )
+ logger.log(
+ "||||||| {:10s} ||||||| Search-Loader-Num={:}, Valid-Loader-Num={:}, batch size={:}".format(
+ xargs.dataset, len(search_loader), len(valid_loader), config.batch_size
+ )
+ )
+ logger.log("||||||| {:10s} ||||||| Config={:}".format(xargs.dataset, config))
+
+ search_space = get_search_spaces("cell", xargs.search_space_name)
+ model_config = dict2config(
+ {
+ "name": "RANDOM",
+ "C": xargs.channel,
+ "N": xargs.num_cells,
+ "max_nodes": xargs.max_nodes,
+ "num_classes": class_num,
+ "space": search_space,
+ "affine": False,
+ "track_running_stats": bool(xargs.track_running_stats),
+ },
+ None,
+ )
+ search_model = get_cell_based_tiny_net(model_config)
+
+ w_optimizer, w_scheduler, criterion = get_optim_scheduler(
+ search_model.parameters(), config
+ )
+ logger.log("w-optimizer : {:}".format(w_optimizer))
+ logger.log("w-scheduler : {:}".format(w_scheduler))
+ logger.log("criterion : {:}".format(criterion))
+ if xargs.arch_nas_dataset is None:
+ api = None
+ else:
+ api = API(xargs.arch_nas_dataset)
+ logger.log("{:} create API = {:} done".format(time_string(), api))
+
+ last_info, model_base_path, model_best_path = (
+ logger.path("info"),
+ logger.path("model"),
+ logger.path("best"),
+ )
+ network, criterion = torch.nn.DataParallel(search_model).cuda(), criterion.cuda()
+
+ if last_info.exists(): # automatically resume from previous checkpoint
+ logger.log(
+ "=> loading checkpoint of the last-info '{:}' start".format(last_info)
+ )
+ last_info = torch.load(last_info)
+ start_epoch = last_info["epoch"]
+ checkpoint = torch.load(last_info["last_checkpoint"])
+ genotypes = checkpoint["genotypes"]
+ valid_accuracies = checkpoint["valid_accuracies"]
+ search_model.load_state_dict(checkpoint["search_model"])
+ w_scheduler.load_state_dict(checkpoint["w_scheduler"])
+ w_optimizer.load_state_dict(checkpoint["w_optimizer"])
+ logger.log(
+ "=> loading checkpoint of the last-info '{:}' start with {:}-th epoch.".format(
+ last_info, start_epoch
+ )
+ )
+ else:
+ logger.log("=> do not find the last-info file : {:}".format(last_info))
+ start_epoch, valid_accuracies, genotypes = 0, {"best": -1}, {}
+
+ # start training
+ start_time, search_time, epoch_time, total_epoch = (
+ time.time(),
+ AverageMeter(),
+ AverageMeter(),
+ config.epochs + config.warmup,
+ )
+ for epoch in range(start_epoch, total_epoch):
+ w_scheduler.update(epoch, 0.0)
+ need_time = "Time Left: {:}".format(
+ convert_secs2time(epoch_time.val * (total_epoch - epoch), True)
+ )
+ epoch_str = "{:03d}-{:03d}".format(epoch, total_epoch)
+ logger.log(
+ "\n[Search the {:}-th epoch] {:}, LR={:}".format(
+ epoch_str, need_time, min(w_scheduler.get_lr())
+ )
+ )
+
+ # selected_arch = search_find_best(valid_loader, network, criterion, xargs.select_num)
+ search_w_loss, search_w_top1, search_w_top5 = search_func(
+ search_loader,
+ network,
+ criterion,
+ w_scheduler,
+ w_optimizer,
+ epoch_str,
+ xargs.print_freq,
+ logger,
+ )
+ search_time.update(time.time() - start_time)
+ logger.log(
+ "[{:}] searching : loss={:.2f}, accuracy@1={:.2f}%, accuracy@5={:.2f}%, time-cost={:.1f} s".format(
+ epoch_str, search_w_loss, search_w_top1, search_w_top5, search_time.sum
+ )
+ )
+ valid_a_loss, valid_a_top1, valid_a_top5 = valid_func(
+ valid_loader, network, criterion
+ )
+ logger.log(
+ "[{:}] evaluate : loss={:.2f}, accuracy@1={:.2f}%, accuracy@5={:.2f}%".format(
+ epoch_str, valid_a_loss, valid_a_top1, valid_a_top5
+ )
+ )
+ cur_arch, cur_valid_acc = search_find_best(
+ valid_loader, network, xargs.select_num
+ )
+ logger.log(
+ "[{:}] find-the-best : {:}, accuracy@1={:.2f}%".format(
+ epoch_str, cur_arch, cur_valid_acc
+ )
+ )
+ genotypes[epoch] = cur_arch
+ # check the best accuracy
+ valid_accuracies[epoch] = valid_a_top1
+ if valid_a_top1 > valid_accuracies["best"]:
+ valid_accuracies["best"] = valid_a_top1
+ find_best = True
+ else:
+ find_best = False
+
+ # save checkpoint
+ save_path = save_checkpoint(
+ {
+ "epoch": epoch + 1,
+ "args": deepcopy(xargs),
+ "search_model": search_model.state_dict(),
+ "w_optimizer": w_optimizer.state_dict(),
+ "w_scheduler": w_scheduler.state_dict(),
+ "genotypes": genotypes,
+ "valid_accuracies": valid_accuracies,
+ },
+ model_base_path,
+ logger,
+ )
+ last_info = save_checkpoint(
+ {
+ "epoch": epoch + 1,
+ "args": deepcopy(args),
+ "last_checkpoint": save_path,
+ },
+ logger.path("info"),
+ logger,
+ )
+ if find_best:
+ logger.log(
+ "<<<--->>> The {:}-th epoch : find the highest validation accuracy : {:.2f}%.".format(
+ epoch_str, valid_a_top1
+ )
+ )
+ copy_checkpoint(model_base_path, model_best_path, logger)
+ if api is not None:
+ logger.log("{:}".format(api.query_by_arch(genotypes[epoch], "200")))
+ # measure elapsed time
+ epoch_time.update(time.time() - start_time)
+ start_time = time.time()
+
+ logger.log("\n" + "-" * 200)
+ logger.log("Pre-searching costs {:.1f} s".format(search_time.sum))
+ start_time = time.time()
+ best_arch, best_acc = search_find_best(valid_loader, network, xargs.select_num)
+ search_time.update(time.time() - start_time)
+ logger.log(
+ "RANDOM-NAS finds the best one : {:} with accuracy={:.2f}%, with {:.1f} s.".format(
+ best_arch, best_acc, search_time.sum
+ )
+ )
+ if api is not None:
+ logger.log("{:}".format(api.query_by_arch(best_arch, "200")))
+ logger.close()
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser("Random search for NAS.")
+ parser.add_argument("--data_path", type=str, help="The path to dataset")
+ parser.add_argument(
+ "--dataset",
+ type=str,
+ choices=["cifar10", "cifar100", "ImageNet16-120"],
+ help="Choose between Cifar10/100 and ImageNet-16.",
+ )
+ # channels and number-of-cells
+ parser.add_argument("--search_space_name", type=str, help="The search space name.")
+ parser.add_argument(
+ "--config_path", type=str, help="The path to the configuration."
+ )
+ parser.add_argument("--max_nodes", type=int, help="The maximum number of nodes.")
+ parser.add_argument("--channel", type=int, help="The number of channels.")
+ parser.add_argument(
+ "--num_cells", type=int, help="The number of cells in one stage."
+ )
+ parser.add_argument(
+ "--select_num",
+ type=int,
+ help="The number of selected architectures to evaluate.",
+ )
+ parser.add_argument(
+ "--track_running_stats",
+ type=int,
+ choices=[0, 1],
+ help="Whether use track_running_stats or not in the BN layer.",
+ )
+ # log
+ parser.add_argument(
+ "--workers",
+ type=int,
+ default=2,
+ help="number of data loading workers (default: 2)",
+ )
+ parser.add_argument(
+ "--save_dir", type=str, help="Folder to save checkpoints and log."
+ )
+ parser.add_argument(
+ "--arch_nas_dataset",
+ type=str,
+ help="The path to load the architecture dataset (tiny-nas-benchmark).",
+ )
+ parser.add_argument("--print_freq", type=int, help="print frequency (default: 200)")
+ parser.add_argument("--rand_seed", type=int, help="manual seed")
+ args = parser.parse_args()
+ if args.rand_seed is None or args.rand_seed < 0:
+ args.rand_seed = random.randint(1, 100000)
+ main(args)
diff --git a/AutoDL-Projects/exps/NAS-Bench-201-algos/RANDOM.py b/AutoDL-Projects/exps/NAS-Bench-201-algos/RANDOM.py
new file mode 100644
index 0000000..88349f5
--- /dev/null
+++ b/AutoDL-Projects/exps/NAS-Bench-201-algos/RANDOM.py
@@ -0,0 +1,189 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020 #
+##############################################################################
+import os, sys, time, glob, random, argparse
+import numpy as np, collections
+from copy import deepcopy
+import torch
+import torch.nn as nn
+from pathlib import Path
+
+from xautodl.config_utils import load_config, dict2config, configure2str
+from xautodl.datasets import get_datasets, SearchDataset
+from xautodl.procedures import (
+ prepare_seed,
+ prepare_logger,
+ save_checkpoint,
+ copy_checkpoint,
+ get_optim_scheduler,
+)
+from xautodl.utils import get_model_infos, obtain_accuracy
+from xautodl.log_utils import AverageMeter, time_string, convert_secs2time
+from xautodl.models import get_search_spaces
+
+from nas_201_api import NASBench201API as API
+from R_EA import train_and_eval, random_architecture_func
+
+
+def main(xargs, nas_bench):
+ assert torch.cuda.is_available(), "CUDA is not available."
+ torch.backends.cudnn.enabled = True
+ torch.backends.cudnn.benchmark = False
+ torch.backends.cudnn.deterministic = True
+ torch.set_num_threads(xargs.workers)
+ prepare_seed(xargs.rand_seed)
+ logger = prepare_logger(args)
+
+ if xargs.dataset == "cifar10":
+ dataname = "cifar10-valid"
+ else:
+ dataname = xargs.dataset
+ if xargs.data_path is not None:
+ train_data, valid_data, xshape, class_num = get_datasets(
+ xargs.dataset, xargs.data_path, -1
+ )
+ split_Fpath = "configs/nas-benchmark/cifar-split.txt"
+ cifar_split = load_config(split_Fpath, None, None)
+ train_split, valid_split = cifar_split.train, cifar_split.valid
+ logger.log("Load split file from {:}".format(split_Fpath))
+ config_path = "configs/nas-benchmark/algos/R-EA.config"
+ config = load_config(
+ config_path, {"class_num": class_num, "xshape": xshape}, logger
+ )
+ # To split data
+ train_data_v2 = deepcopy(train_data)
+ train_data_v2.transform = valid_data.transform
+ valid_data = train_data_v2
+ search_data = SearchDataset(xargs.dataset, train_data, train_split, valid_split)
+ # data loader
+ train_loader = torch.utils.data.DataLoader(
+ train_data,
+ batch_size=config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(train_split),
+ num_workers=xargs.workers,
+ pin_memory=True,
+ )
+ valid_loader = torch.utils.data.DataLoader(
+ valid_data,
+ batch_size=config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(valid_split),
+ num_workers=xargs.workers,
+ pin_memory=True,
+ )
+ logger.log(
+ "||||||| {:10s} ||||||| Train-Loader-Num={:}, Valid-Loader-Num={:}, batch size={:}".format(
+ xargs.dataset, len(train_loader), len(valid_loader), config.batch_size
+ )
+ )
+ logger.log("||||||| {:10s} ||||||| Config={:}".format(xargs.dataset, config))
+ extra_info = {
+ "config": config,
+ "train_loader": train_loader,
+ "valid_loader": valid_loader,
+ }
+ else:
+ config_path = "configs/nas-benchmark/algos/R-EA.config"
+ config = load_config(config_path, None, logger)
+ logger.log("||||||| {:10s} ||||||| Config={:}".format(xargs.dataset, config))
+ extra_info = {"config": config, "train_loader": None, "valid_loader": None}
+ search_space = get_search_spaces("cell", xargs.search_space_name)
+ random_arch = random_architecture_func(xargs.max_nodes, search_space)
+ # x =random_arch() ; y = mutate_arch(x)
+ x_start_time = time.time()
+ logger.log("{:} use nas_bench : {:}".format(time_string(), nas_bench))
+ best_arch, best_acc, total_time_cost, history = None, -1, 0, []
+ # for idx in range(xargs.random_num):
+ while total_time_cost < xargs.time_budget:
+ arch = random_arch()
+ accuracy, cost_time = train_and_eval(arch, nas_bench, extra_info, dataname)
+ if total_time_cost + cost_time > xargs.time_budget:
+ break
+ else:
+ total_time_cost += cost_time
+ history.append(arch)
+ if best_arch is None or best_acc < accuracy:
+ best_acc, best_arch = accuracy, arch
+ logger.log(
+ "[{:03d}] : {:} : accuracy = {:.2f}%".format(len(history), arch, accuracy)
+ )
+ logger.log(
+ "{:} best arch is {:}, accuracy = {:.2f}%, visit {:} archs with {:.1f} s (real-cost = {:.3f} s).".format(
+ time_string(),
+ best_arch,
+ best_acc,
+ len(history),
+ total_time_cost,
+ time.time() - x_start_time,
+ )
+ )
+
+ info = nas_bench.query_by_arch(best_arch, "200")
+ if info is None:
+ logger.log("Did not find this architecture : {:}.".format(best_arch))
+ else:
+ logger.log("{:}".format(info))
+ logger.log("-" * 100)
+ logger.close()
+ return logger.log_dir, nas_bench.query_index_by_arch(best_arch)
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser("Random NAS")
+ parser.add_argument("--data_path", type=str, help="Path to dataset")
+ parser.add_argument(
+ "--dataset",
+ type=str,
+ choices=["cifar10", "cifar100", "ImageNet16-120"],
+ help="Choose between Cifar10/100 and ImageNet-16.",
+ )
+ # channels and number-of-cells
+ parser.add_argument("--search_space_name", type=str, help="The search space name.")
+ parser.add_argument("--max_nodes", type=int, help="The maximum number of nodes.")
+ parser.add_argument("--channel", type=int, help="The number of channels.")
+ parser.add_argument(
+ "--num_cells", type=int, help="The number of cells in one stage."
+ )
+ # parser.add_argument('--random_num', type=int, help='The number of random selected architectures.')
+ parser.add_argument(
+ "--time_budget",
+ type=int,
+ help="The total time cost budge for searching (in seconds).",
+ )
+ # log
+ parser.add_argument(
+ "--workers",
+ type=int,
+ default=2,
+ help="number of data loading workers (default: 2)",
+ )
+ parser.add_argument(
+ "--save_dir", type=str, help="Folder to save checkpoints and log."
+ )
+ parser.add_argument(
+ "--arch_nas_dataset",
+ type=str,
+ help="The path to load the architecture dataset (tiny-nas-benchmark).",
+ )
+ parser.add_argument("--print_freq", type=int, help="print frequency (default: 200)")
+ parser.add_argument("--rand_seed", type=int, help="manual seed")
+ args = parser.parse_args()
+ # if args.rand_seed is None or args.rand_seed < 0: args.rand_seed = random.randint(1, 100000)
+ if args.arch_nas_dataset is None or not os.path.isfile(args.arch_nas_dataset):
+ nas_bench = None
+ else:
+ print(
+ "{:} build NAS-Benchmark-API from {:}".format(
+ time_string(), args.arch_nas_dataset
+ )
+ )
+ nas_bench = API(args.arch_nas_dataset)
+ if args.rand_seed < 0:
+ save_dir, all_indexes, num = None, [], 500
+ for i in range(num):
+ print("{:} : {:03d}/{:03d}".format(time_string(), i, num))
+ args.rand_seed = random.randint(1, 100000)
+ save_dir, index = main(args, nas_bench)
+ all_indexes.append(index)
+ torch.save(all_indexes, save_dir / "results.pth")
+ else:
+ main(args, nas_bench)
diff --git a/AutoDL-Projects/exps/NAS-Bench-201-algos/README.md b/AutoDL-Projects/exps/NAS-Bench-201-algos/README.md
new file mode 100644
index 0000000..edd4e7e
--- /dev/null
+++ b/AutoDL-Projects/exps/NAS-Bench-201-algos/README.md
@@ -0,0 +1,7 @@
+# NAS Algorithms evaluated in NAS-Bench-201
+
+The Python files in this folder are used to re-produce the results in our NAS-Bench-201 paper.
+
+We have upgraded the codes to be more general and extendable at [NATS-algos](https://github.com/D-X-Y/AutoDL-Projects/tree/main/exps/NATS-algos).
+
+**Notice** On 24 May 2021, the codes in `AutoDL` repo have been re-organized. If you find `module not found` error, please let me know. I will fix them ASAP.
diff --git a/AutoDL-Projects/exps/NAS-Bench-201-algos/R_EA.py b/AutoDL-Projects/exps/NAS-Bench-201-algos/R_EA.py
new file mode 100644
index 0000000..d18a098
--- /dev/null
+++ b/AutoDL-Projects/exps/NAS-Bench-201-algos/R_EA.py
@@ -0,0 +1,399 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020 #
+##################################################################
+# Regularized Evolution for Image Classifier Architecture Search #
+##################################################################
+import os, sys, time, glob, random, argparse
+import numpy as np, collections
+from copy import deepcopy
+import torch
+import torch.nn as nn
+from pathlib import Path
+
+from xautodl.config_utils import load_config, dict2config, configure2str
+from xautodl.datasets import get_datasets, SearchDataset
+from xautodl.procedures import (
+ prepare_seed,
+ prepare_logger,
+ save_checkpoint,
+ copy_checkpoint,
+ get_optim_scheduler,
+)
+from xautodl.utils import get_model_infos, obtain_accuracy
+from xautodl.log_utils import AverageMeter, time_string, convert_secs2time
+from xautodl.models import CellStructure, get_search_spaces
+from nas_201_api import NASBench201API as API
+
+
+class Model(object):
+ def __init__(self):
+ self.arch = None
+ self.accuracy = None
+
+ def __str__(self):
+ """Prints a readable version of this bitstring."""
+ return "{:}".format(self.arch)
+
+
+# This function is to mimic the training and evaluatinig procedure for a single architecture `arch`.
+# The time_cost is calculated as the total training time for a few (e.g., 12 epochs) plus the evaluation time for one epoch.
+# For use_012_epoch_training = True, the architecture is trained for 12 epochs, with LR being decaded from 0.1 to 0.
+# In this case, the LR schedular is converged.
+# For use_012_epoch_training = False, the architecture is planed to be trained for 200 epochs, but we early stop its procedure.
+#
+def train_and_eval(
+ arch, nas_bench, extra_info, dataname="cifar10-valid", use_012_epoch_training=True
+):
+
+ if use_012_epoch_training and nas_bench is not None:
+ arch_index = nas_bench.query_index_by_arch(arch)
+ assert arch_index >= 0, "can not find this arch : {:}".format(arch)
+ info = nas_bench.get_more_info(
+ arch_index, dataname, iepoch=None, hp="12", is_random=True
+ )
+ valid_acc, time_cost = (
+ info["valid-accuracy"],
+ info["train-all-time"] + info["valid-per-time"],
+ )
+ # _, valid_acc = info.get_metrics('cifar10-valid', 'x-valid' , 25, True) # use the validation accuracy after 25 training epochs
+ elif not use_012_epoch_training and nas_bench is not None:
+ # Please contact me if you want to use the following logic, because it has some potential issues.
+ # Please use `use_012_epoch_training=False` for cifar10 only.
+ # It did return values for cifar100 and ImageNet16-120, but it has some potential issues. (Please email me for more details)
+ arch_index, nepoch = nas_bench.query_index_by_arch(arch), 25
+ assert arch_index >= 0, "can not find this arch : {:}".format(arch)
+ xoinfo = nas_bench.get_more_info(
+ arch_index, "cifar10-valid", iepoch=None, hp="12"
+ )
+ xocost = nas_bench.get_cost_info(arch_index, "cifar10-valid", hp="200")
+ info = nas_bench.get_more_info(
+ arch_index, dataname, nepoch, hp="200", is_random=True
+ ) # use the validation accuracy after 25 training epochs, which is used in our ICLR submission (not the camera ready).
+ cost = nas_bench.get_cost_info(arch_index, dataname, hp="200")
+ # The following codes are used to estimate the time cost.
+ # When we build NAS-Bench-201, architectures are trained on different machines and we can not use that time record.
+ # When we create checkpoints for converged_LR, we run all experiments on 1080Ti, and thus the time for each architecture can be fairly compared.
+ nums = {
+ "ImageNet16-120-train": 151700,
+ "ImageNet16-120-valid": 3000,
+ "cifar10-valid-train": 25000,
+ "cifar10-valid-valid": 25000,
+ "cifar100-train": 50000,
+ "cifar100-valid": 5000,
+ }
+ estimated_train_cost = (
+ xoinfo["train-per-time"]
+ / nums["cifar10-valid-train"]
+ * nums["{:}-train".format(dataname)]
+ / xocost["latency"]
+ * cost["latency"]
+ * nepoch
+ )
+ estimated_valid_cost = (
+ xoinfo["valid-per-time"]
+ / nums["cifar10-valid-valid"]
+ * nums["{:}-valid".format(dataname)]
+ / xocost["latency"]
+ * cost["latency"]
+ )
+ try:
+ valid_acc, time_cost = (
+ info["valid-accuracy"],
+ estimated_train_cost + estimated_valid_cost,
+ )
+ except:
+ valid_acc, time_cost = (
+ info["valtest-accuracy"],
+ estimated_train_cost + estimated_valid_cost,
+ )
+ else:
+ # train a model from scratch.
+ raise ValueError("NOT IMPLEMENT YET")
+ return valid_acc, time_cost
+
+
+def random_architecture_func(max_nodes, op_names):
+ # return a random architecture
+ def random_architecture():
+ genotypes = []
+ for i in range(1, max_nodes):
+ xlist = []
+ for j in range(i):
+ node_str = "{:}<-{:}".format(i, j)
+ op_name = random.choice(op_names)
+ xlist.append((op_name, j))
+ genotypes.append(tuple(xlist))
+ return CellStructure(genotypes)
+
+ return random_architecture
+
+
+def mutate_arch_func(op_names):
+ """Computes the architecture for a child of the given parent architecture.
+ The parent architecture is cloned and mutated to produce the child architecture. The child architecture is mutated by randomly switch one operation to another.
+ """
+
+ def mutate_arch_func(parent_arch):
+ child_arch = deepcopy(parent_arch)
+ node_id = random.randint(0, len(child_arch.nodes) - 1)
+ node_info = list(child_arch.nodes[node_id])
+ snode_id = random.randint(0, len(node_info) - 1)
+ xop = random.choice(op_names)
+ while xop == node_info[snode_id][0]:
+ xop = random.choice(op_names)
+ node_info[snode_id] = (xop, node_info[snode_id][1])
+ child_arch.nodes[node_id] = tuple(node_info)
+ return child_arch
+
+ return mutate_arch_func
+
+
+def regularized_evolution(
+ cycles,
+ population_size,
+ sample_size,
+ time_budget,
+ random_arch,
+ mutate_arch,
+ nas_bench,
+ extra_info,
+ dataname,
+):
+ """Algorithm for regularized evolution (i.e. aging evolution).
+
+ Follows "Algorithm 1" in Real et al. "Regularized Evolution for Image
+ Classifier Architecture Search".
+
+ Args:
+ cycles: the number of cycles the algorithm should run for.
+ population_size: the number of individuals to keep in the population.
+ sample_size: the number of individuals that should participate in each tournament.
+ time_budget: the upper bound of searching cost
+
+ Returns:
+ history: a list of `Model` instances, representing all the models computed
+ during the evolution experiment.
+ """
+ population = collections.deque()
+ history, total_time_cost = (
+ [],
+ 0,
+ ) # Not used by the algorithm, only used to report results.
+
+ # Initialize the population with random models.
+ while len(population) < population_size:
+ model = Model()
+ model.arch = random_arch()
+ model.accuracy, time_cost = train_and_eval(
+ model.arch, nas_bench, extra_info, dataname
+ )
+ population.append(model)
+ history.append(model)
+ total_time_cost += time_cost
+
+ # Carry out evolution in cycles. Each cycle produces a model and removes
+ # another.
+ # while len(history) < cycles:
+ while total_time_cost < time_budget:
+ # Sample randomly chosen models from the current population.
+ start_time, sample = time.time(), []
+ while len(sample) < sample_size:
+ # Inefficient, but written this way for clarity. In the case of neural
+ # nets, the efficiency of this line is irrelevant because training neural
+ # nets is the rate-determining step.
+ candidate = random.choice(list(population))
+ sample.append(candidate)
+
+ # The parent is the best model in the sample.
+ parent = max(sample, key=lambda i: i.accuracy)
+
+ # Create the child model and store it.
+ child = Model()
+ child.arch = mutate_arch(parent.arch)
+ total_time_cost += time.time() - start_time
+ child.accuracy, time_cost = train_and_eval(
+ child.arch, nas_bench, extra_info, dataname
+ )
+ if total_time_cost + time_cost > time_budget: # return
+ return history, total_time_cost
+ else:
+ total_time_cost += time_cost
+ population.append(child)
+ history.append(child)
+
+ # Remove the oldest model.
+ population.popleft()
+ return history, total_time_cost
+
+
+def main(xargs, nas_bench):
+ assert torch.cuda.is_available(), "CUDA is not available."
+ torch.backends.cudnn.enabled = True
+ torch.backends.cudnn.benchmark = False
+ torch.backends.cudnn.deterministic = True
+ torch.set_num_threads(xargs.workers)
+ prepare_seed(xargs.rand_seed)
+ logger = prepare_logger(args)
+
+ if xargs.dataset == "cifar10":
+ dataname = "cifar10-valid"
+ else:
+ dataname = xargs.dataset
+ if xargs.data_path is not None:
+ train_data, valid_data, xshape, class_num = get_datasets(
+ xargs.dataset, xargs.data_path, -1
+ )
+ split_Fpath = "configs/nas-benchmark/cifar-split.txt"
+ cifar_split = load_config(split_Fpath, None, None)
+ train_split, valid_split = cifar_split.train, cifar_split.valid
+ logger.log("Load split file from {:}".format(split_Fpath))
+ config_path = "configs/nas-benchmark/algos/R-EA.config"
+ config = load_config(
+ config_path, {"class_num": class_num, "xshape": xshape}, logger
+ )
+ # To split data
+ train_data_v2 = deepcopy(train_data)
+ train_data_v2.transform = valid_data.transform
+ valid_data = train_data_v2
+ search_data = SearchDataset(xargs.dataset, train_data, train_split, valid_split)
+ # data loader
+ train_loader = torch.utils.data.DataLoader(
+ train_data,
+ batch_size=config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(train_split),
+ num_workers=xargs.workers,
+ pin_memory=True,
+ )
+ valid_loader = torch.utils.data.DataLoader(
+ valid_data,
+ batch_size=config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(valid_split),
+ num_workers=xargs.workers,
+ pin_memory=True,
+ )
+ logger.log(
+ "||||||| {:10s} ||||||| Train-Loader-Num={:}, Valid-Loader-Num={:}, batch size={:}".format(
+ xargs.dataset, len(train_loader), len(valid_loader), config.batch_size
+ )
+ )
+ logger.log("||||||| {:10s} ||||||| Config={:}".format(xargs.dataset, config))
+ extra_info = {
+ "config": config,
+ "train_loader": train_loader,
+ "valid_loader": valid_loader,
+ }
+ else:
+ config_path = "configs/nas-benchmark/algos/R-EA.config"
+ config = load_config(config_path, None, logger)
+ logger.log("||||||| {:10s} ||||||| Config={:}".format(xargs.dataset, config))
+ extra_info = {"config": config, "train_loader": None, "valid_loader": None}
+
+ search_space = get_search_spaces("cell", xargs.search_space_name)
+ random_arch = random_architecture_func(xargs.max_nodes, search_space)
+ mutate_arch = mutate_arch_func(search_space)
+ # x =random_arch() ; y = mutate_arch(x)
+ x_start_time = time.time()
+ logger.log("{:} use nas_bench : {:}".format(time_string(), nas_bench))
+ logger.log(
+ "-" * 30
+ + " start searching with the time budget of {:} s".format(xargs.time_budget)
+ )
+ history, total_cost = regularized_evolution(
+ xargs.ea_cycles,
+ xargs.ea_population,
+ xargs.ea_sample_size,
+ xargs.time_budget,
+ random_arch,
+ mutate_arch,
+ nas_bench if args.ea_fast_by_api else None,
+ extra_info,
+ dataname,
+ )
+ logger.log(
+ "{:} regularized_evolution finish with history of {:} arch with {:.1f} s (real-cost={:.2f} s).".format(
+ time_string(), len(history), total_cost, time.time() - x_start_time
+ )
+ )
+ best_arch = max(history, key=lambda i: i.accuracy)
+ best_arch = best_arch.arch
+ logger.log("{:} best arch is {:}".format(time_string(), best_arch))
+
+ info = nas_bench.query_by_arch(best_arch, "200")
+ if info is None:
+ logger.log("Did not find this architecture : {:}.".format(best_arch))
+ else:
+ logger.log("{:}".format(info))
+ logger.log("-" * 100)
+ logger.close()
+ return logger.log_dir, nas_bench.query_index_by_arch(best_arch)
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser("Regularized Evolution Algorithm")
+ parser.add_argument("--data_path", type=str, help="Path to dataset")
+ parser.add_argument(
+ "--dataset",
+ type=str,
+ choices=["cifar10", "cifar100", "ImageNet16-120"],
+ help="Choose between Cifar10/100 and ImageNet-16.",
+ )
+ # channels and number-of-cells
+ parser.add_argument("--search_space_name", type=str, help="The search space name.")
+ parser.add_argument("--max_nodes", type=int, help="The maximum number of nodes.")
+ parser.add_argument("--channel", type=int, help="The number of channels.")
+ parser.add_argument(
+ "--num_cells", type=int, help="The number of cells in one stage."
+ )
+ parser.add_argument("--ea_cycles", type=int, help="The number of cycles in EA.")
+ parser.add_argument("--ea_population", type=int, help="The population size in EA.")
+ parser.add_argument("--ea_sample_size", type=int, help="The sample size in EA.")
+ parser.add_argument(
+ "--ea_fast_by_api",
+ type=int,
+ help="Use our API to speed up the experiments or not.",
+ )
+ parser.add_argument(
+ "--time_budget",
+ type=int,
+ help="The total time cost budge for searching (in seconds).",
+ )
+ # log
+ parser.add_argument(
+ "--workers",
+ type=int,
+ default=2,
+ help="number of data loading workers (default: 2)",
+ )
+ parser.add_argument(
+ "--save_dir", type=str, help="Folder to save checkpoints and log."
+ )
+ parser.add_argument(
+ "--arch_nas_dataset",
+ type=str,
+ help="The path to load the architecture dataset (tiny-nas-benchmark).",
+ )
+ parser.add_argument("--print_freq", type=int, help="print frequency (default: 200)")
+ parser.add_argument("--rand_seed", type=int, default=-1, help="manual seed")
+ args = parser.parse_args()
+ # if args.rand_seed is None or args.rand_seed < 0: args.rand_seed = random.randint(1, 100000)
+ args.ea_fast_by_api = args.ea_fast_by_api > 0
+
+ if args.arch_nas_dataset is None or not os.path.isfile(args.arch_nas_dataset):
+ nas_bench = None
+ else:
+ print(
+ "{:} build NAS-Benchmark-API from {:}".format(
+ time_string(), args.arch_nas_dataset
+ )
+ )
+ nas_bench = API(args.arch_nas_dataset)
+ if args.rand_seed < 0:
+ save_dir, all_indexes, num = None, [], 500
+ for i in range(num):
+ print("{:} : {:03d}/{:03d}".format(time_string(), i, num))
+ args.rand_seed = random.randint(1, 100000)
+ save_dir, index = main(args, nas_bench)
+ all_indexes.append(index)
+ torch.save(all_indexes, save_dir / "results.pth")
+ else:
+ main(args, nas_bench)
diff --git a/AutoDL-Projects/exps/NAS-Bench-201-algos/SETN.py b/AutoDL-Projects/exps/NAS-Bench-201-algos/SETN.py
new file mode 100644
index 0000000..327df31
--- /dev/null
+++ b/AutoDL-Projects/exps/NAS-Bench-201-algos/SETN.py
@@ -0,0 +1,476 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020 #
+######################################################################################
+# One-Shot Neural Architecture Search via Self-Evaluated Template Network, ICCV 2019 #
+######################################################################################
+import sys, time, random, argparse
+import numpy as np
+from copy import deepcopy
+import torch
+import torch.nn as nn
+from pathlib import Path
+
+from xautodl.config_utils import load_config, dict2config, configure2str
+from xautodl.datasets import get_datasets, get_nas_search_loaders
+from xautodl.procedures import (
+ prepare_seed,
+ prepare_logger,
+ save_checkpoint,
+ copy_checkpoint,
+ get_optim_scheduler,
+)
+from xautodl.utils import get_model_infos, obtain_accuracy
+from xautodl.log_utils import AverageMeter, time_string, convert_secs2time
+from xautodl.models import get_cell_based_tiny_net, get_search_spaces
+from nas_201_api import NASBench201API as API
+
+
+def search_func(
+ xloader,
+ network,
+ criterion,
+ scheduler,
+ w_optimizer,
+ a_optimizer,
+ epoch_str,
+ print_freq,
+ logger,
+):
+ data_time, batch_time = AverageMeter(), AverageMeter()
+ base_losses, base_top1, base_top5 = AverageMeter(), AverageMeter(), AverageMeter()
+ arch_losses, arch_top1, arch_top5 = AverageMeter(), AverageMeter(), AverageMeter()
+ end = time.time()
+ network.train()
+ for step, (base_inputs, base_targets, arch_inputs, arch_targets) in enumerate(
+ xloader
+ ):
+ scheduler.update(None, 1.0 * step / len(xloader))
+ base_targets = base_targets.cuda(non_blocking=True)
+ arch_targets = arch_targets.cuda(non_blocking=True)
+ # measure data loading time
+ data_time.update(time.time() - end)
+
+ # update the weights
+ sampled_arch = network.module.dync_genotype(True)
+ network.module.set_cal_mode("dynamic", sampled_arch)
+ # network.module.set_cal_mode( 'urs' )
+ network.zero_grad()
+ _, logits = network(base_inputs)
+ base_loss = criterion(logits, base_targets)
+ base_loss.backward()
+ w_optimizer.step()
+ # record
+ base_prec1, base_prec5 = obtain_accuracy(
+ logits.data, base_targets.data, topk=(1, 5)
+ )
+ base_losses.update(base_loss.item(), base_inputs.size(0))
+ base_top1.update(base_prec1.item(), base_inputs.size(0))
+ base_top5.update(base_prec5.item(), base_inputs.size(0))
+
+ # update the architecture-weight
+ network.module.set_cal_mode("joint")
+ network.zero_grad()
+ _, logits = network(arch_inputs)
+ arch_loss = criterion(logits, arch_targets)
+ arch_loss.backward()
+ a_optimizer.step()
+ # record
+ arch_prec1, arch_prec5 = obtain_accuracy(
+ logits.data, arch_targets.data, topk=(1, 5)
+ )
+ arch_losses.update(arch_loss.item(), arch_inputs.size(0))
+ arch_top1.update(arch_prec1.item(), arch_inputs.size(0))
+ arch_top5.update(arch_prec5.item(), arch_inputs.size(0))
+
+ # measure elapsed time
+ batch_time.update(time.time() - end)
+ end = time.time()
+
+ if step % print_freq == 0 or step + 1 == len(xloader):
+ Sstr = (
+ "*SEARCH* "
+ + time_string()
+ + " [{:}][{:03d}/{:03d}]".format(epoch_str, step, len(xloader))
+ )
+ Tstr = "Time {batch_time.val:.2f} ({batch_time.avg:.2f}) Data {data_time.val:.2f} ({data_time.avg:.2f})".format(
+ batch_time=batch_time, data_time=data_time
+ )
+ Wstr = "Base [Loss {loss.val:.3f} ({loss.avg:.3f}) Prec@1 {top1.val:.2f} ({top1.avg:.2f}) Prec@5 {top5.val:.2f} ({top5.avg:.2f})]".format(
+ loss=base_losses, top1=base_top1, top5=base_top5
+ )
+ Astr = "Arch [Loss {loss.val:.3f} ({loss.avg:.3f}) Prec@1 {top1.val:.2f} ({top1.avg:.2f}) Prec@5 {top5.val:.2f} ({top5.avg:.2f})]".format(
+ loss=arch_losses, top1=arch_top1, top5=arch_top5
+ )
+ logger.log(Sstr + " " + Tstr + " " + Wstr + " " + Astr)
+ # print (nn.functional.softmax(network.module.arch_parameters, dim=-1))
+ # print (network.module.arch_parameters)
+ return (
+ base_losses.avg,
+ base_top1.avg,
+ base_top5.avg,
+ arch_losses.avg,
+ arch_top1.avg,
+ arch_top5.avg,
+ )
+
+
+def get_best_arch(xloader, network, n_samples):
+ with torch.no_grad():
+ network.eval()
+ archs, valid_accs = network.module.return_topK(n_samples), []
+ # print ('obtain the top-{:} architectures'.format(n_samples))
+ loader_iter = iter(xloader)
+ for i, sampled_arch in enumerate(archs):
+ network.module.set_cal_mode("dynamic", sampled_arch)
+ try:
+ inputs, targets = next(loader_iter)
+ except:
+ loader_iter = iter(xloader)
+ inputs, targets = next(loader_iter)
+
+ _, logits = network(inputs)
+ val_top1, val_top5 = obtain_accuracy(
+ logits.cpu().data, targets.data, topk=(1, 5)
+ )
+
+ valid_accs.append(val_top1.item())
+
+ best_idx = np.argmax(valid_accs)
+ best_arch, best_valid_acc = archs[best_idx], valid_accs[best_idx]
+ return best_arch, best_valid_acc
+
+
+def valid_func(xloader, network, criterion):
+ data_time, batch_time = AverageMeter(), AverageMeter()
+ arch_losses, arch_top1, arch_top5 = AverageMeter(), AverageMeter(), AverageMeter()
+ end = time.time()
+ with torch.no_grad():
+ network.eval()
+ for step, (arch_inputs, arch_targets) in enumerate(xloader):
+ arch_targets = arch_targets.cuda(non_blocking=True)
+ # measure data loading time
+ data_time.update(time.time() - end)
+ # prediction
+ _, logits = network(arch_inputs)
+ arch_loss = criterion(logits, arch_targets)
+ # record
+ arch_prec1, arch_prec5 = obtain_accuracy(
+ logits.data, arch_targets.data, topk=(1, 5)
+ )
+ arch_losses.update(arch_loss.item(), arch_inputs.size(0))
+ arch_top1.update(arch_prec1.item(), arch_inputs.size(0))
+ arch_top5.update(arch_prec5.item(), arch_inputs.size(0))
+ # measure elapsed time
+ batch_time.update(time.time() - end)
+ end = time.time()
+ return arch_losses.avg, arch_top1.avg, arch_top5.avg
+
+
+def main(xargs):
+ assert torch.cuda.is_available(), "CUDA is not available."
+ torch.backends.cudnn.enabled = True
+ torch.backends.cudnn.benchmark = False
+ torch.backends.cudnn.deterministic = True
+ torch.set_num_threads(xargs.workers)
+ prepare_seed(xargs.rand_seed)
+ logger = prepare_logger(args)
+
+ train_data, valid_data, xshape, class_num = get_datasets(
+ xargs.dataset, xargs.data_path, -1
+ )
+ config = load_config(
+ xargs.config_path, {"class_num": class_num, "xshape": xshape}, logger
+ )
+ search_loader, _, valid_loader = get_nas_search_loaders(
+ train_data,
+ valid_data,
+ xargs.dataset,
+ "configs/nas-benchmark/",
+ (config.batch_size, config.test_batch_size),
+ xargs.workers,
+ )
+ logger.log(
+ "||||||| {:10s} ||||||| Search-Loader-Num={:}, Valid-Loader-Num={:}, batch size={:}".format(
+ xargs.dataset, len(search_loader), len(valid_loader), config.batch_size
+ )
+ )
+ logger.log("||||||| {:10s} ||||||| Config={:}".format(xargs.dataset, config))
+
+ search_space = get_search_spaces("cell", xargs.search_space_name)
+ if xargs.model_config is None:
+ model_config = dict2config(
+ dict(
+ name="SETN",
+ C=xargs.channel,
+ N=xargs.num_cells,
+ max_nodes=xargs.max_nodes,
+ num_classes=class_num,
+ space=search_space,
+ affine=False,
+ track_running_stats=bool(xargs.track_running_stats),
+ ),
+ None,
+ )
+ else:
+ model_config = load_config(
+ xargs.model_config,
+ dict(
+ num_classes=class_num,
+ space=search_space,
+ affine=False,
+ track_running_stats=bool(xargs.track_running_stats),
+ ),
+ None,
+ )
+ logger.log("search space : {:}".format(search_space))
+ search_model = get_cell_based_tiny_net(model_config)
+
+ w_optimizer, w_scheduler, criterion = get_optim_scheduler(
+ search_model.get_weights(), config
+ )
+ a_optimizer = torch.optim.Adam(
+ search_model.get_alphas(),
+ lr=xargs.arch_learning_rate,
+ betas=(0.5, 0.999),
+ weight_decay=xargs.arch_weight_decay,
+ )
+ logger.log("w-optimizer : {:}".format(w_optimizer))
+ logger.log("a-optimizer : {:}".format(a_optimizer))
+ logger.log("w-scheduler : {:}".format(w_scheduler))
+ logger.log("criterion : {:}".format(criterion))
+ flop, param = get_model_infos(search_model, xshape)
+ logger.log("FLOP = {:.2f} M, Params = {:.2f} MB".format(flop, param))
+ logger.log("search-space : {:}".format(search_space))
+ if xargs.arch_nas_dataset is None:
+ api = None
+ else:
+ api = API(xargs.arch_nas_dataset)
+ logger.log("{:} create API = {:} done".format(time_string(), api))
+
+ last_info, model_base_path, model_best_path = (
+ logger.path("info"),
+ logger.path("model"),
+ logger.path("best"),
+ )
+ network, criterion = torch.nn.DataParallel(search_model).cuda(), criterion.cuda()
+
+ if last_info.exists(): # automatically resume from previous checkpoint
+ logger.log(
+ "=> loading checkpoint of the last-info '{:}' start".format(last_info)
+ )
+ last_info = torch.load(last_info)
+ start_epoch = last_info["epoch"]
+ checkpoint = torch.load(last_info["last_checkpoint"])
+ genotypes = checkpoint["genotypes"]
+ valid_accuracies = checkpoint["valid_accuracies"]
+ search_model.load_state_dict(checkpoint["search_model"])
+ w_scheduler.load_state_dict(checkpoint["w_scheduler"])
+ w_optimizer.load_state_dict(checkpoint["w_optimizer"])
+ a_optimizer.load_state_dict(checkpoint["a_optimizer"])
+ logger.log(
+ "=> loading checkpoint of the last-info '{:}' start with {:}-th epoch.".format(
+ last_info, start_epoch
+ )
+ )
+ else:
+ logger.log("=> do not find the last-info file : {:}".format(last_info))
+ init_genotype, _ = get_best_arch(valid_loader, network, xargs.select_num)
+ start_epoch, valid_accuracies, genotypes = 0, {"best": -1}, {-1: init_genotype}
+
+ # start training
+ start_time, search_time, epoch_time, total_epoch = (
+ time.time(),
+ AverageMeter(),
+ AverageMeter(),
+ config.epochs + config.warmup,
+ )
+ for epoch in range(start_epoch, total_epoch):
+ w_scheduler.update(epoch, 0.0)
+ need_time = "Time Left: {:}".format(
+ convert_secs2time(epoch_time.val * (total_epoch - epoch), True)
+ )
+ epoch_str = "{:03d}-{:03d}".format(epoch, total_epoch)
+ logger.log(
+ "\n[Search the {:}-th epoch] {:}, LR={:}".format(
+ epoch_str, need_time, min(w_scheduler.get_lr())
+ )
+ )
+
+ (
+ search_w_loss,
+ search_w_top1,
+ search_w_top5,
+ search_a_loss,
+ search_a_top1,
+ search_a_top5,
+ ) = search_func(
+ search_loader,
+ network,
+ criterion,
+ w_scheduler,
+ w_optimizer,
+ a_optimizer,
+ epoch_str,
+ xargs.print_freq,
+ logger,
+ )
+ search_time.update(time.time() - start_time)
+ logger.log(
+ "[{:}] search [base] : loss={:.2f}, accuracy@1={:.2f}%, accuracy@5={:.2f}%, time-cost={:.1f} s".format(
+ epoch_str, search_w_loss, search_w_top1, search_w_top5, search_time.sum
+ )
+ )
+ logger.log(
+ "[{:}] search [arch] : loss={:.2f}, accuracy@1={:.2f}%, accuracy@5={:.2f}%".format(
+ epoch_str, search_a_loss, search_a_top1, search_a_top5
+ )
+ )
+
+ genotype, temp_accuracy = get_best_arch(valid_loader, network, xargs.select_num)
+ network.module.set_cal_mode("dynamic", genotype)
+ valid_a_loss, valid_a_top1, valid_a_top5 = valid_func(
+ valid_loader, network, criterion
+ )
+ logger.log(
+ "[{:}] evaluate : loss={:.2f}, accuracy@1={:.2f}%, accuracy@5={:.2f}% | {:}".format(
+ epoch_str, valid_a_loss, valid_a_top1, valid_a_top5, genotype
+ )
+ )
+ # search_model.set_cal_mode('urs')
+ # valid_a_loss , valid_a_top1 , valid_a_top5 = valid_func(valid_loader, network, criterion)
+ # logger.log('[{:}] URS---evaluate : loss={:.2f}, accuracy@1={:.2f}%, accuracy@5={:.2f}%'.format(epoch_str, valid_a_loss, valid_a_top1, valid_a_top5))
+ # search_model.set_cal_mode('joint')
+ # valid_a_loss , valid_a_top1 , valid_a_top5 = valid_func(valid_loader, network, criterion)
+ # logger.log('[{:}] JOINT-evaluate : loss={:.2f}, accuracy@1={:.2f}%, accuracy@5={:.2f}%'.format(epoch_str, valid_a_loss, valid_a_top1, valid_a_top5))
+ # search_model.set_cal_mode('select')
+ # valid_a_loss , valid_a_top1 , valid_a_top5 = valid_func(valid_loader, network, criterion)
+ # logger.log('[{:}] Selec-evaluate : loss={:.2f}, accuracy@1={:.2f}%, accuracy@5={:.2f}%'.format(epoch_str, valid_a_loss, valid_a_top1, valid_a_top5))
+ # check the best accuracy
+ valid_accuracies[epoch] = valid_a_top1
+
+ genotypes[epoch] = genotype
+ logger.log(
+ "<<<--->>> The {:}-th epoch : {:}".format(epoch_str, genotypes[epoch])
+ )
+ # save checkpoint
+ save_path = save_checkpoint(
+ {
+ "epoch": epoch + 1,
+ "args": deepcopy(xargs),
+ "search_model": search_model.state_dict(),
+ "w_optimizer": w_optimizer.state_dict(),
+ "a_optimizer": a_optimizer.state_dict(),
+ "w_scheduler": w_scheduler.state_dict(),
+ "genotypes": genotypes,
+ "valid_accuracies": valid_accuracies,
+ },
+ model_base_path,
+ logger,
+ )
+ last_info = save_checkpoint(
+ {
+ "epoch": epoch + 1,
+ "args": deepcopy(args),
+ "last_checkpoint": save_path,
+ },
+ logger.path("info"),
+ logger,
+ )
+ with torch.no_grad():
+ logger.log("{:}".format(search_model.show_alphas()))
+ if api is not None:
+ logger.log("{:}".format(api.query_by_arch(genotypes[epoch], "200")))
+ # measure elapsed time
+ epoch_time.update(time.time() - start_time)
+ start_time = time.time()
+
+ # the final post procedure : count the time
+ start_time = time.time()
+ genotype, temp_accuracy = get_best_arch(valid_loader, network, xargs.select_num)
+ search_time.update(time.time() - start_time)
+ network.module.set_cal_mode("dynamic", genotype)
+ valid_a_loss, valid_a_top1, valid_a_top5 = valid_func(
+ valid_loader, network, criterion
+ )
+ logger.log(
+ "Last : the gentotype is : {:}, with the validation accuracy of {:.3f}%.".format(
+ genotype, valid_a_top1
+ )
+ )
+
+ logger.log("\n" + "-" * 100)
+ # check the performance from the architecture dataset
+ logger.log(
+ "SETN : run {:} epochs, cost {:.1f} s, last-geno is {:}.".format(
+ total_epoch, search_time.sum, genotype
+ )
+ )
+ if api is not None:
+ logger.log("{:}".format(api.query_by_arch(genotype, "200")))
+ logger.close()
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser("SETN")
+ parser.add_argument("--data_path", type=str, help="Path to dataset")
+ parser.add_argument(
+ "--dataset",
+ type=str,
+ choices=["cifar10", "cifar100", "ImageNet16-120"],
+ help="Choose between Cifar10/100 and ImageNet-16.",
+ )
+ # channels and number-of-cells
+ parser.add_argument("--search_space_name", type=str, help="The search space name.")
+ parser.add_argument("--max_nodes", type=int, help="The maximum number of nodes.")
+ parser.add_argument("--channel", type=int, help="The number of channels.")
+ parser.add_argument(
+ "--num_cells", type=int, help="The number of cells in one stage."
+ )
+ parser.add_argument(
+ "--select_num",
+ type=int,
+ help="The number of selected architectures to evaluate.",
+ )
+ parser.add_argument(
+ "--track_running_stats",
+ type=int,
+ choices=[0, 1],
+ help="Whether use track_running_stats or not in the BN layer.",
+ )
+ parser.add_argument(
+ "--config_path", type=str, help="The path of the configuration."
+ )
+ # architecture leraning rate
+ parser.add_argument(
+ "--arch_learning_rate",
+ type=float,
+ default=3e-4,
+ help="learning rate for arch encoding",
+ )
+ parser.add_argument(
+ "--arch_weight_decay",
+ type=float,
+ default=1e-3,
+ help="weight decay for arch encoding",
+ )
+ # log
+ parser.add_argument(
+ "--workers",
+ type=int,
+ default=2,
+ help="number of data loading workers (default: 2)",
+ )
+ parser.add_argument(
+ "--save_dir", type=str, help="Folder to save checkpoints and log."
+ )
+ parser.add_argument(
+ "--arch_nas_dataset",
+ type=str,
+ help="The path to load the architecture dataset (tiny-nas-benchmark).",
+ )
+ parser.add_argument("--print_freq", type=int, help="print frequency (default: 200)")
+ parser.add_argument("--rand_seed", type=int, help="manual seed")
+ args = parser.parse_args()
+ if args.rand_seed is None or args.rand_seed < 0:
+ args.rand_seed = random.randint(1, 100000)
+ main(args)
diff --git a/AutoDL-Projects/exps/NAS-Bench-201-algos/reinforce.py b/AutoDL-Projects/exps/NAS-Bench-201-algos/reinforce.py
new file mode 100644
index 0000000..5ef02da
--- /dev/null
+++ b/AutoDL-Projects/exps/NAS-Bench-201-algos/reinforce.py
@@ -0,0 +1,294 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019 #
+#####################################################################################################
+# modified from https://github.com/pytorch/examples/blob/master/reinforcement_learning/reinforce.py #
+#####################################################################################################
+import os, sys, time, glob, random, argparse
+import numpy as np, collections
+from copy import deepcopy
+from pathlib import Path
+import torch
+import torch.nn as nn
+from torch.distributions import Categorical
+
+from xautodl.config_utils import load_config, dict2config, configure2str
+from xautodl.datasets import get_datasets, SearchDataset
+from xautodl.procedures import (
+ prepare_seed,
+ prepare_logger,
+ save_checkpoint,
+ copy_checkpoint,
+ get_optim_scheduler,
+)
+from xautodl.utils import get_model_infos, obtain_accuracy
+from xautodl.log_utils import AverageMeter, time_string, convert_secs2time
+from xautodl.models import CellStructure, get_search_spaces
+from nas_201_api import NASBench201API as API
+from R_EA import train_and_eval
+
+
+class Policy(nn.Module):
+ def __init__(self, max_nodes, search_space):
+ super(Policy, self).__init__()
+ self.max_nodes = max_nodes
+ self.search_space = deepcopy(search_space)
+ self.edge2index = {}
+ for i in range(1, max_nodes):
+ for j in range(i):
+ node_str = "{:}<-{:}".format(i, j)
+ self.edge2index[node_str] = len(self.edge2index)
+ self.arch_parameters = nn.Parameter(
+ 1e-3 * torch.randn(len(self.edge2index), len(search_space))
+ )
+
+ def generate_arch(self, actions):
+ genotypes = []
+ for i in range(1, self.max_nodes):
+ xlist = []
+ for j in range(i):
+ node_str = "{:}<-{:}".format(i, j)
+ op_name = self.search_space[actions[self.edge2index[node_str]]]
+ xlist.append((op_name, j))
+ genotypes.append(tuple(xlist))
+ return CellStructure(genotypes)
+
+ def genotype(self):
+ genotypes = []
+ for i in range(1, self.max_nodes):
+ xlist = []
+ for j in range(i):
+ node_str = "{:}<-{:}".format(i, j)
+ with torch.no_grad():
+ weights = self.arch_parameters[self.edge2index[node_str]]
+ op_name = self.search_space[weights.argmax().item()]
+ xlist.append((op_name, j))
+ genotypes.append(tuple(xlist))
+ return CellStructure(genotypes)
+
+ def forward(self):
+ alphas = nn.functional.softmax(self.arch_parameters, dim=-1)
+ return alphas
+
+
+class ExponentialMovingAverage(object):
+ """Class that maintains an exponential moving average."""
+
+ def __init__(self, momentum):
+ self._numerator = 0
+ self._denominator = 0
+ self._momentum = momentum
+
+ def update(self, value):
+ self._numerator = (
+ self._momentum * self._numerator + (1 - self._momentum) * value
+ )
+ self._denominator = self._momentum * self._denominator + (1 - self._momentum)
+
+ def value(self):
+ """Return the current value of the moving average"""
+ return self._numerator / self._denominator
+
+
+def select_action(policy):
+ probs = policy()
+ m = Categorical(probs)
+ action = m.sample()
+ # policy.saved_log_probs.append(m.log_prob(action))
+ return m.log_prob(action), action.cpu().tolist()
+
+
+def main(xargs, nas_bench):
+ assert torch.cuda.is_available(), "CUDA is not available."
+ torch.backends.cudnn.enabled = True
+ torch.backends.cudnn.benchmark = False
+ torch.backends.cudnn.deterministic = True
+ torch.set_num_threads(xargs.workers)
+ prepare_seed(xargs.rand_seed)
+ logger = prepare_logger(args)
+
+ if xargs.dataset == "cifar10":
+ dataname = "cifar10-valid"
+ else:
+ dataname = xargs.dataset
+ if xargs.data_path is not None:
+ train_data, valid_data, xshape, class_num = get_datasets(
+ xargs.dataset, xargs.data_path, -1
+ )
+ split_Fpath = "configs/nas-benchmark/cifar-split.txt"
+ cifar_split = load_config(split_Fpath, None, None)
+ train_split, valid_split = cifar_split.train, cifar_split.valid
+ logger.log("Load split file from {:}".format(split_Fpath))
+ config_path = "configs/nas-benchmark/algos/R-EA.config"
+ config = load_config(
+ config_path, {"class_num": class_num, "xshape": xshape}, logger
+ )
+ # To split data
+ train_data_v2 = deepcopy(train_data)
+ train_data_v2.transform = valid_data.transform
+ valid_data = train_data_v2
+ search_data = SearchDataset(xargs.dataset, train_data, train_split, valid_split)
+ # data loader
+ train_loader = torch.utils.data.DataLoader(
+ train_data,
+ batch_size=config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(train_split),
+ num_workers=xargs.workers,
+ pin_memory=True,
+ )
+ valid_loader = torch.utils.data.DataLoader(
+ valid_data,
+ batch_size=config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(valid_split),
+ num_workers=xargs.workers,
+ pin_memory=True,
+ )
+ logger.log(
+ "||||||| {:10s} ||||||| Train-Loader-Num={:}, Valid-Loader-Num={:}, batch size={:}".format(
+ xargs.dataset, len(train_loader), len(valid_loader), config.batch_size
+ )
+ )
+ logger.log("||||||| {:10s} ||||||| Config={:}".format(xargs.dataset, config))
+ extra_info = {
+ "config": config,
+ "train_loader": train_loader,
+ "valid_loader": valid_loader,
+ }
+ else:
+ config_path = "configs/nas-benchmark/algos/R-EA.config"
+ config = load_config(config_path, None, logger)
+ extra_info = {"config": config, "train_loader": None, "valid_loader": None}
+ logger.log("||||||| {:10s} ||||||| Config={:}".format(xargs.dataset, config))
+
+ search_space = get_search_spaces("cell", xargs.search_space_name)
+ policy = Policy(xargs.max_nodes, search_space)
+ optimizer = torch.optim.Adam(policy.parameters(), lr=xargs.learning_rate)
+ # optimizer = torch.optim.SGD(policy.parameters(), lr=xargs.learning_rate)
+ eps = np.finfo(np.float32).eps.item()
+ baseline = ExponentialMovingAverage(xargs.EMA_momentum)
+ logger.log("policy : {:}".format(policy))
+ logger.log("optimizer : {:}".format(optimizer))
+ logger.log("eps : {:}".format(eps))
+
+ # nas dataset load
+ logger.log("{:} use nas_bench : {:}".format(time_string(), nas_bench))
+
+ # REINFORCE
+ # attempts = 0
+ x_start_time = time.time()
+ logger.log(
+ "Will start searching with time budget of {:} s.".format(xargs.time_budget)
+ )
+ total_steps, total_costs, trace = 0, 0, []
+ # for istep in range(xargs.RL_steps):
+ while total_costs < xargs.time_budget:
+ start_time = time.time()
+ log_prob, action = select_action(policy)
+ arch = policy.generate_arch(action)
+ reward, cost_time = train_and_eval(arch, nas_bench, extra_info, dataname)
+ trace.append((reward, arch))
+ # accumulate time
+ if total_costs + cost_time < xargs.time_budget:
+ total_costs += cost_time
+ else:
+ break
+
+ baseline.update(reward)
+ # calculate loss
+ policy_loss = (-log_prob * (reward - baseline.value())).sum()
+ optimizer.zero_grad()
+ policy_loss.backward()
+ optimizer.step()
+ # accumulate time
+ total_costs += time.time() - start_time
+ total_steps += 1
+ logger.log(
+ "step [{:3d}] : average-reward={:.3f} : policy_loss={:.4f} : {:}".format(
+ total_steps, baseline.value(), policy_loss.item(), policy.genotype()
+ )
+ )
+ # logger.log('----> {:}'.format(policy.arch_parameters))
+ # logger.log('')
+
+ # best_arch = policy.genotype() # first version
+ best_arch = max(trace, key=lambda x: x[0])[1]
+ logger.log(
+ "REINFORCE finish with {:} steps and {:.1f} s (real cost={:.3f}).".format(
+ total_steps, total_costs, time.time() - x_start_time
+ )
+ )
+ info = nas_bench.query_by_arch(best_arch, "200")
+ if info is None:
+ logger.log("Did not find this architecture : {:}.".format(best_arch))
+ else:
+ logger.log("{:}".format(info))
+ logger.log("-" * 100)
+ logger.close()
+ return logger.log_dir, nas_bench.query_index_by_arch(best_arch)
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser("The REINFORCE Algorithm")
+ parser.add_argument("--data_path", type=str, help="Path to dataset")
+ parser.add_argument(
+ "--dataset",
+ type=str,
+ choices=["cifar10", "cifar100", "ImageNet16-120"],
+ help="Choose between Cifar10/100 and ImageNet-16.",
+ )
+ # channels and number-of-cells
+ parser.add_argument("--search_space_name", type=str, help="The search space name.")
+ parser.add_argument("--max_nodes", type=int, help="The maximum number of nodes.")
+ parser.add_argument("--channel", type=int, help="The number of channels.")
+ parser.add_argument(
+ "--num_cells", type=int, help="The number of cells in one stage."
+ )
+ parser.add_argument(
+ "--learning_rate", type=float, help="The learning rate for REINFORCE."
+ )
+ # parser.add_argument('--RL_steps', type=int, help='The steps for REINFORCE.')
+ parser.add_argument(
+ "--EMA_momentum", type=float, help="The momentum value for EMA."
+ )
+ parser.add_argument(
+ "--time_budget",
+ type=int,
+ help="The total time cost budge for searching (in seconds).",
+ )
+ # log
+ parser.add_argument(
+ "--workers",
+ type=int,
+ default=2,
+ help="number of data loading workers (default: 2)",
+ )
+ parser.add_argument(
+ "--save_dir", type=str, help="Folder to save checkpoints and log."
+ )
+ parser.add_argument(
+ "--arch_nas_dataset",
+ type=str,
+ help="The path to load the architecture dataset (tiny-nas-benchmark).",
+ )
+ parser.add_argument("--print_freq", type=int, help="print frequency (default: 200)")
+ parser.add_argument("--rand_seed", type=int, default=-1, help="manual seed")
+ args = parser.parse_args()
+ # if args.rand_seed is None or args.rand_seed < 0: args.rand_seed = random.randint(1, 100000)
+ if args.arch_nas_dataset is None or not os.path.isfile(args.arch_nas_dataset):
+ nas_bench = None
+ else:
+ print(
+ "{:} build NAS-Benchmark-API from {:}".format(
+ time_string(), args.arch_nas_dataset
+ )
+ )
+ nas_bench = API(args.arch_nas_dataset)
+ if args.rand_seed < 0:
+ save_dir, all_indexes, num = None, [], 500
+ for i in range(num):
+ print("{:} : {:03d}/{:03d}".format(time_string(), i, num))
+ args.rand_seed = random.randint(1, 100000)
+ save_dir, index = main(args, nas_bench)
+ all_indexes.append(index)
+ torch.save(all_indexes, save_dir / "results.pth")
+ else:
+ main(args, nas_bench)
diff --git a/AutoDL-Projects/exps/NAS-Bench-201/check.py b/AutoDL-Projects/exps/NAS-Bench-201/check.py
new file mode 100644
index 0000000..b81ed34
--- /dev/null
+++ b/AutoDL-Projects/exps/NAS-Bench-201/check.py
@@ -0,0 +1,137 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.08 #
+#####################################################
+# python exps/NAS-Bench-201/check.py --base_str C16-N5-LESS
+#####################################################
+import sys, time, argparse, collections
+import torch
+from pathlib import Path
+from collections import defaultdict
+
+from xautodl.log_utils import AverageMeter, time_string, convert_secs2time
+
+
+def check_files(save_dir, meta_file, basestr):
+ meta_infos = torch.load(meta_file, map_location="cpu")
+ meta_archs = meta_infos["archs"]
+ meta_num_archs = meta_infos["total"]
+ assert meta_num_archs == len(
+ meta_archs
+ ), "invalid number of archs : {:} vs {:}".format(meta_num_archs, len(meta_archs))
+
+ sub_model_dirs = sorted(list(save_dir.glob("*-*-{:}".format(basestr))))
+ print(
+ "{:} find {:} directories used to save checkpoints".format(
+ time_string(), len(sub_model_dirs)
+ )
+ )
+
+ subdir2archs, num_evaluated_arch = collections.OrderedDict(), 0
+ num_seeds = defaultdict(lambda: 0)
+ for index, sub_dir in enumerate(sub_model_dirs):
+ xcheckpoints = list(sub_dir.glob("arch-*-seed-*.pth"))
+ # xcheckpoints = list(sub_dir.glob('arch-*-seed-0777.pth')) + list(sub_dir.glob('arch-*-seed-0888.pth')) + list(sub_dir.glob('arch-*-seed-0999.pth'))
+ arch_indexes = set()
+ for checkpoint in xcheckpoints:
+ temp_names = checkpoint.name.split("-")
+ assert (
+ len(temp_names) == 4
+ and temp_names[0] == "arch"
+ and temp_names[2] == "seed"
+ ), "invalid checkpoint name : {:}".format(checkpoint.name)
+ arch_indexes.add(temp_names[1])
+ subdir2archs[sub_dir] = sorted(list(arch_indexes))
+ num_evaluated_arch += len(arch_indexes)
+ # count number of seeds for each architecture
+ for arch_index in arch_indexes:
+ num_seeds[
+ len(list(sub_dir.glob("arch-{:}-seed-*.pth".format(arch_index))))
+ ] += 1
+ print(
+ "There are {:5d} architectures that have been evaluated ({:} in total, {:} ckps in total).".format(
+ num_evaluated_arch, meta_num_archs, sum(k * v for k, v in num_seeds.items())
+ )
+ )
+ for key in sorted(list(num_seeds.keys())):
+ print(
+ "There are {:5d} architectures that are evaluated {:} times.".format(
+ num_seeds[key], key
+ )
+ )
+
+ dir2ckps, dir2ckp_exists = dict(), dict()
+ start_time, epoch_time = time.time(), AverageMeter()
+ for IDX, (sub_dir, arch_indexes) in enumerate(subdir2archs.items()):
+ if basestr == "C16-N5":
+ seeds = [777, 888, 999]
+ elif basestr == "C16-N5-LESS":
+ seeds = [111, 777]
+ else:
+ raise ValueError("Invalid base str : {:}".format(basestr))
+ numrs = defaultdict(lambda: 0)
+ all_checkpoints, all_ckp_exists = [], []
+ for arch_index in arch_indexes:
+ checkpoints = [
+ "arch-{:}-seed-{:04d}.pth".format(arch_index, seed) for seed in seeds
+ ]
+ ckp_exists = [(sub_dir / x).exists() for x in checkpoints]
+ arch_index = int(arch_index)
+ assert (
+ 0 <= arch_index < len(meta_archs)
+ ), "invalid arch-index {:} (not found in meta_archs)".format(arch_index)
+ all_checkpoints += checkpoints
+ all_ckp_exists += ckp_exists
+ numrs[sum(ckp_exists)] += 1
+ dir2ckps[str(sub_dir)] = all_checkpoints
+ dir2ckp_exists[str(sub_dir)] = all_ckp_exists
+ # measure time
+ epoch_time.update(time.time() - start_time)
+ start_time = time.time()
+ numrstr = ", ".join(
+ ["{:}: {:03d}".format(x, numrs[x]) for x in sorted(numrs.keys())]
+ )
+ print(
+ "{:} load [{:2d}/{:2d}] [{:03d} archs] [{:04d}->{:04d} ckps] {:} done, need {:}. {:}".format(
+ time_string(),
+ IDX + 1,
+ len(subdir2archs),
+ len(arch_indexes),
+ len(all_checkpoints),
+ sum(all_ckp_exists),
+ sub_dir,
+ convert_secs2time(epoch_time.avg * (len(subdir2archs) - IDX - 1), True),
+ numrstr,
+ )
+ )
+
+
+if __name__ == "__main__":
+
+ parser = argparse.ArgumentParser(
+ description="NAS Benchmark 201",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ )
+ parser.add_argument(
+ "--base_save_dir",
+ type=str,
+ default="./output/NAS-BENCH-201-4",
+ help="The base-name of folder to save checkpoints and log.",
+ )
+ parser.add_argument(
+ "--meta_path",
+ type=str,
+ default="./output/NAS-BENCH-201-4/meta-node-4.pth",
+ help="The meta file path.",
+ )
+ parser.add_argument(
+ "--base_str", type=str, default="C16-N5", help="The basic string."
+ )
+ args = parser.parse_args()
+
+ save_dir = Path(args.base_save_dir)
+ meta_path = Path(args.meta_path)
+ assert save_dir.exists(), "invalid save dir path : {:}".format(save_dir)
+ assert meta_path.exists(), "invalid saved meta path : {:}".format(meta_path)
+ print("check NAS-Bench-201 in {:}".format(save_dir))
+
+ check_files(save_dir, meta_path, args.base_str)
diff --git a/AutoDL-Projects/exps/NAS-Bench-201/dist-setup.py b/AutoDL-Projects/exps/NAS-Bench-201/dist-setup.py
new file mode 100644
index 0000000..9ec7dab
--- /dev/null
+++ b/AutoDL-Projects/exps/NAS-Bench-201/dist-setup.py
@@ -0,0 +1,37 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.08 #
+#####################################################
+# [2020.02.25] Initialize the API as v1.1
+# [2020.03.09] Upgrade the API to v1.2
+# [2020.03.16] Upgrade the API to v1.3
+# [2020.06.30] Upgrade the API to v2.0
+import os
+from setuptools import setup
+
+
+def read(fname="README.md"):
+ with open(
+ os.path.join(os.path.dirname(__file__), fname), encoding="utf-8"
+ ) as cfile:
+ return cfile.read()
+
+
+setup(
+ name="nas_bench_201",
+ version="2.0",
+ author="Xuanyi Dong",
+ author_email="dongxuanyi888@gmail.com",
+ description="API for NAS-Bench-201 (a benchmark for neural architecture search).",
+ license="MIT",
+ keywords="NAS Dataset API DeepLearning",
+ url="https://github.com/D-X-Y/NAS-Bench-201",
+ packages=["nas_201_api"],
+ long_description=read("README.md"),
+ long_description_content_type="text/markdown",
+ classifiers=[
+ "Programming Language :: Python",
+ "Topic :: Database",
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
+ "License :: OSI Approved :: MIT License",
+ ],
+)
diff --git a/AutoDL-Projects/exps/NAS-Bench-201/functions.py b/AutoDL-Projects/exps/NAS-Bench-201/functions.py
new file mode 100644
index 0000000..5ac92bb
--- /dev/null
+++ b/AutoDL-Projects/exps/NAS-Bench-201/functions.py
@@ -0,0 +1,182 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.08 #
+#####################################################
+import time, torch
+from procedures import prepare_seed, get_optim_scheduler
+from utils import get_model_infos, obtain_accuracy
+from config_utils import dict2config
+from log_utils import AverageMeter, time_string, convert_secs2time
+from models import get_cell_based_tiny_net
+
+
+__all__ = ["evaluate_for_seed", "pure_evaluate"]
+
+
+def pure_evaluate(xloader, network, criterion=torch.nn.CrossEntropyLoss()):
+ data_time, batch_time, batch = AverageMeter(), AverageMeter(), None
+ losses, top1, top5 = AverageMeter(), AverageMeter(), AverageMeter()
+ latencies = []
+ network.eval()
+ with torch.no_grad():
+ end = time.time()
+ for i, (inputs, targets) in enumerate(xloader):
+ targets = targets.cuda(non_blocking=True)
+ inputs = inputs.cuda(non_blocking=True)
+ data_time.update(time.time() - end)
+ # forward
+ features, logits = network(inputs)
+ loss = criterion(logits, targets)
+ batch_time.update(time.time() - end)
+ if batch is None or batch == inputs.size(0):
+ batch = inputs.size(0)
+ latencies.append(batch_time.val - data_time.val)
+ # record loss and accuracy
+ prec1, prec5 = obtain_accuracy(logits.data, targets.data, topk=(1, 5))
+ losses.update(loss.item(), inputs.size(0))
+ top1.update(prec1.item(), inputs.size(0))
+ top5.update(prec5.item(), inputs.size(0))
+ end = time.time()
+ if len(latencies) > 2:
+ latencies = latencies[1:]
+ return losses.avg, top1.avg, top5.avg, latencies
+
+
+def procedure(xloader, network, criterion, scheduler, optimizer, mode):
+ losses, top1, top5 = AverageMeter(), AverageMeter(), AverageMeter()
+ if mode == "train":
+ network.train()
+ elif mode == "valid":
+ network.eval()
+ else:
+ raise ValueError("The mode is not right : {:}".format(mode))
+
+ data_time, batch_time, end = AverageMeter(), AverageMeter(), time.time()
+ for i, (inputs, targets) in enumerate(xloader):
+ if mode == "train":
+ scheduler.update(None, 1.0 * i / len(xloader))
+
+ targets = targets.cuda(non_blocking=True)
+ if mode == "train":
+ optimizer.zero_grad()
+ # forward
+ features, logits = network(inputs)
+ loss = criterion(logits, targets)
+ # backward
+ if mode == "train":
+ loss.backward()
+ optimizer.step()
+ # record loss and accuracy
+ prec1, prec5 = obtain_accuracy(logits.data, targets.data, topk=(1, 5))
+ losses.update(loss.item(), inputs.size(0))
+ top1.update(prec1.item(), inputs.size(0))
+ top5.update(prec5.item(), inputs.size(0))
+ # count time
+ batch_time.update(time.time() - end)
+ end = time.time()
+ return losses.avg, top1.avg, top5.avg, batch_time.sum
+
+
+def evaluate_for_seed(
+ arch_config, config, arch, train_loader, valid_loaders, seed, logger
+):
+
+ prepare_seed(seed) # random seed
+ net = get_cell_based_tiny_net(
+ dict2config(
+ {
+ "name": "infer.tiny",
+ "C": arch_config["channel"],
+ "N": arch_config["num_cells"],
+ "genotype": arch,
+ "num_classes": config.class_num,
+ },
+ None,
+ )
+ )
+ # net = TinyNetwork(arch_config['channel'], arch_config['num_cells'], arch, config.class_num)
+ flop, param = get_model_infos(net, config.xshape)
+ logger.log("Network : {:}".format(net.get_message()), False)
+ logger.log(
+ "{:} Seed-------------------------- {:} --------------------------".format(
+ time_string(), seed
+ )
+ )
+ logger.log("FLOP = {:} MB, Param = {:} MB".format(flop, param))
+ # train and valid
+ optimizer, scheduler, criterion = get_optim_scheduler(net.parameters(), config)
+ network, criterion = torch.nn.DataParallel(net).cuda(), criterion.cuda()
+ # start training
+ start_time, epoch_time, total_epoch = (
+ time.time(),
+ AverageMeter(),
+ config.epochs + config.warmup,
+ )
+ (
+ train_losses,
+ train_acc1es,
+ train_acc5es,
+ valid_losses,
+ valid_acc1es,
+ valid_acc5es,
+ ) = ({}, {}, {}, {}, {}, {})
+ train_times, valid_times = {}, {}
+ for epoch in range(total_epoch):
+ scheduler.update(epoch, 0.0)
+
+ train_loss, train_acc1, train_acc5, train_tm = procedure(
+ train_loader, network, criterion, scheduler, optimizer, "train"
+ )
+ train_losses[epoch] = train_loss
+ train_acc1es[epoch] = train_acc1
+ train_acc5es[epoch] = train_acc5
+ train_times[epoch] = train_tm
+ with torch.no_grad():
+ for key, xloder in valid_loaders.items():
+ valid_loss, valid_acc1, valid_acc5, valid_tm = procedure(
+ xloder, network, criterion, None, None, "valid"
+ )
+ valid_losses["{:}@{:}".format(key, epoch)] = valid_loss
+ valid_acc1es["{:}@{:}".format(key, epoch)] = valid_acc1
+ valid_acc5es["{:}@{:}".format(key, epoch)] = valid_acc5
+ valid_times["{:}@{:}".format(key, epoch)] = valid_tm
+
+ # measure elapsed time
+ epoch_time.update(time.time() - start_time)
+ start_time = time.time()
+ need_time = "Time Left: {:}".format(
+ convert_secs2time(epoch_time.avg * (total_epoch - epoch - 1), True)
+ )
+ logger.log(
+ "{:} {:} epoch={:03d}/{:03d} :: Train [loss={:.5f}, acc@1={:.2f}%, acc@5={:.2f}%] Valid [loss={:.5f}, acc@1={:.2f}%, acc@5={:.2f}%]".format(
+ time_string(),
+ need_time,
+ epoch,
+ total_epoch,
+ train_loss,
+ train_acc1,
+ train_acc5,
+ valid_loss,
+ valid_acc1,
+ valid_acc5,
+ )
+ )
+ info_seed = {
+ "flop": flop,
+ "param": param,
+ "channel": arch_config["channel"],
+ "num_cells": arch_config["num_cells"],
+ "config": config._asdict(),
+ "total_epoch": total_epoch,
+ "train_losses": train_losses,
+ "train_acc1es": train_acc1es,
+ "train_acc5es": train_acc5es,
+ "train_times": train_times,
+ "valid_losses": valid_losses,
+ "valid_acc1es": valid_acc1es,
+ "valid_acc5es": valid_acc5es,
+ "valid_times": valid_times,
+ "net_state_dict": net.state_dict(),
+ "net_string": "{:}".format(net),
+ "finish-train": True,
+ }
+ return info_seed
diff --git a/AutoDL-Projects/exps/NAS-Bench-201/main.py b/AutoDL-Projects/exps/NAS-Bench-201/main.py
new file mode 100644
index 0000000..5b32850
--- /dev/null
+++ b/AutoDL-Projects/exps/NAS-Bench-201/main.py
@@ -0,0 +1,668 @@
+###############################################################
+# NAS-Bench-201, ICLR 2020 (https://arxiv.org/abs/2001.00326) #
+###############################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.08 #
+###############################################################
+import os, sys, time, torch, random, argparse
+from PIL import ImageFile
+
+ImageFile.LOAD_TRUNCATED_IMAGES = True
+from copy import deepcopy
+from pathlib import Path
+
+from xautodl.config_utils import load_config
+from xautodl.procedures import save_checkpoint, copy_checkpoint
+from xautodl.procedures import get_machine_info
+from xautodl.datasets import get_datasets
+from xautodl.log_utils import Logger, AverageMeter, time_string, convert_secs2time
+from xautodl.models import CellStructure, CellArchitectures, get_search_spaces
+from xautodl.functions import evaluate_for_seed
+
+
+def evaluate_all_datasets(
+ arch, datasets, xpaths, splits, use_less, seed, arch_config, workers, logger
+):
+ machine_info, arch_config = get_machine_info(), deepcopy(arch_config)
+ all_infos = {"info": machine_info}
+ all_dataset_keys = []
+ # look all the datasets
+ for dataset, xpath, split in zip(datasets, xpaths, splits):
+ # train valid data
+ train_data, valid_data, xshape, class_num = get_datasets(dataset, xpath, -1)
+ # load the configuration
+ if dataset == "cifar10" or dataset == "cifar100":
+ if use_less:
+ config_path = "configs/nas-benchmark/LESS.config"
+ else:
+ config_path = "configs/nas-benchmark/CIFAR.config"
+ split_info = load_config(
+ "configs/nas-benchmark/cifar-split.txt", None, None
+ )
+ elif dataset.startswith("ImageNet16"):
+ if use_less:
+ config_path = "configs/nas-benchmark/LESS.config"
+ else:
+ config_path = "configs/nas-benchmark/ImageNet-16.config"
+ split_info = load_config(
+ "configs/nas-benchmark/{:}-split.txt".format(dataset), None, None
+ )
+ else:
+ raise ValueError("invalid dataset : {:}".format(dataset))
+ config = load_config(
+ config_path, {"class_num": class_num, "xshape": xshape}, logger
+ )
+ # check whether use splited validation set
+ if bool(split):
+ assert dataset == "cifar10"
+ ValLoaders = {
+ "ori-test": torch.utils.data.DataLoader(
+ valid_data,
+ batch_size=config.batch_size,
+ shuffle=False,
+ num_workers=workers,
+ pin_memory=True,
+ )
+ }
+ assert len(train_data) == len(split_info.train) + len(
+ split_info.valid
+ ), "invalid length : {:} vs {:} + {:}".format(
+ len(train_data), len(split_info.train), len(split_info.valid)
+ )
+ train_data_v2 = deepcopy(train_data)
+ train_data_v2.transform = valid_data.transform
+ valid_data = train_data_v2
+ # data loader
+ train_loader = torch.utils.data.DataLoader(
+ train_data,
+ batch_size=config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(split_info.train),
+ num_workers=workers,
+ pin_memory=True,
+ )
+ valid_loader = torch.utils.data.DataLoader(
+ valid_data,
+ batch_size=config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(split_info.valid),
+ num_workers=workers,
+ pin_memory=True,
+ )
+ ValLoaders["x-valid"] = valid_loader
+ else:
+ # data loader
+ train_loader = torch.utils.data.DataLoader(
+ train_data,
+ batch_size=config.batch_size,
+ shuffle=True,
+ num_workers=workers,
+ pin_memory=True,
+ )
+ valid_loader = torch.utils.data.DataLoader(
+ valid_data,
+ batch_size=config.batch_size,
+ shuffle=False,
+ num_workers=workers,
+ pin_memory=True,
+ )
+ if dataset == "cifar10":
+ ValLoaders = {"ori-test": valid_loader}
+ elif dataset == "cifar100":
+ cifar100_splits = load_config(
+ "configs/nas-benchmark/cifar100-test-split.txt", None, None
+ )
+ ValLoaders = {
+ "ori-test": valid_loader,
+ "x-valid": torch.utils.data.DataLoader(
+ valid_data,
+ batch_size=config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(
+ cifar100_splits.xvalid
+ ),
+ num_workers=workers,
+ pin_memory=True,
+ ),
+ "x-test": torch.utils.data.DataLoader(
+ valid_data,
+ batch_size=config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(
+ cifar100_splits.xtest
+ ),
+ num_workers=workers,
+ pin_memory=True,
+ ),
+ }
+ elif dataset == "ImageNet16-120":
+ imagenet16_splits = load_config(
+ "configs/nas-benchmark/imagenet-16-120-test-split.txt", None, None
+ )
+ ValLoaders = {
+ "ori-test": valid_loader,
+ "x-valid": torch.utils.data.DataLoader(
+ valid_data,
+ batch_size=config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(
+ imagenet16_splits.xvalid
+ ),
+ num_workers=workers,
+ pin_memory=True,
+ ),
+ "x-test": torch.utils.data.DataLoader(
+ valid_data,
+ batch_size=config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(
+ imagenet16_splits.xtest
+ ),
+ num_workers=workers,
+ pin_memory=True,
+ ),
+ }
+ else:
+ raise ValueError("invalid dataset : {:}".format(dataset))
+
+ dataset_key = "{:}".format(dataset)
+ if bool(split):
+ dataset_key = dataset_key + "-valid"
+ logger.log(
+ "Evaluate ||||||| {:10s} ||||||| Train-Num={:}, Valid-Num={:}, Train-Loader-Num={:}, Valid-Loader-Num={:}, batch size={:}".format(
+ dataset_key,
+ len(train_data),
+ len(valid_data),
+ len(train_loader),
+ len(valid_loader),
+ config.batch_size,
+ )
+ )
+ logger.log(
+ "Evaluate ||||||| {:10s} ||||||| Config={:}".format(dataset_key, config)
+ )
+ for key, value in ValLoaders.items():
+ logger.log(
+ "Evaluate ---->>>> {:10s} with {:} batchs".format(key, len(value))
+ )
+ results = evaluate_for_seed(
+ arch_config, config, arch, train_loader, ValLoaders, seed, logger
+ )
+ all_infos[dataset_key] = results
+ all_dataset_keys.append(dataset_key)
+ all_infos["all_dataset_keys"] = all_dataset_keys
+ return all_infos
+
+
+def main(
+ save_dir,
+ workers,
+ datasets,
+ xpaths,
+ splits,
+ use_less,
+ srange,
+ arch_index,
+ seeds,
+ cover_mode,
+ meta_info,
+ arch_config,
+):
+ assert torch.cuda.is_available(), "CUDA is not available."
+ torch.backends.cudnn.enabled = True
+ # torch.backends.cudnn.benchmark = True
+ torch.backends.cudnn.deterministic = True
+ torch.set_num_threads(workers)
+
+ assert (
+ len(srange) == 2 and 0 <= srange[0] <= srange[1]
+ ), "invalid srange : {:}".format(srange)
+
+ if use_less:
+ sub_dir = Path(save_dir) / "{:06d}-{:06d}-C{:}-N{:}-LESS".format(
+ srange[0], srange[1], arch_config["channel"], arch_config["num_cells"]
+ )
+ else:
+ sub_dir = Path(save_dir) / "{:06d}-{:06d}-C{:}-N{:}".format(
+ srange[0], srange[1], arch_config["channel"], arch_config["num_cells"]
+ )
+ logger = Logger(str(sub_dir), 0, False)
+
+ all_archs = meta_info["archs"]
+ assert srange[1] < meta_info["total"], "invalid range : {:}-{:} vs. {:}".format(
+ srange[0], srange[1], meta_info["total"]
+ )
+ assert (
+ arch_index == -1 or srange[0] <= arch_index <= srange[1]
+ ), "invalid range : {:} vs. {:} vs. {:}".format(srange[0], arch_index, srange[1])
+ if arch_index == -1:
+ to_evaluate_indexes = list(range(srange[0], srange[1] + 1))
+ else:
+ to_evaluate_indexes = [arch_index]
+ logger.log("xargs : seeds = {:}".format(seeds))
+ logger.log("xargs : arch_index = {:}".format(arch_index))
+ logger.log("xargs : cover_mode = {:}".format(cover_mode))
+ logger.log("-" * 100)
+
+ logger.log(
+ "Start evaluating range =: {:06d} vs. {:06d} vs. {:06d} / {:06d} with cover-mode={:}".format(
+ srange[0], arch_index, srange[1], meta_info["total"], cover_mode
+ )
+ )
+ for i, (dataset, xpath, split) in enumerate(zip(datasets, xpaths, splits)):
+ logger.log(
+ "--->>> Evaluate {:}/{:} : dataset={:9s}, path={:}, split={:}".format(
+ i, len(datasets), dataset, xpath, split
+ )
+ )
+ logger.log("--->>> architecture config : {:}".format(arch_config))
+
+ start_time, epoch_time = time.time(), AverageMeter()
+ for i, index in enumerate(to_evaluate_indexes):
+ arch = all_archs[index]
+ logger.log(
+ "\n{:} evaluate {:06d}/{:06d} ({:06d}/{:06d})-th architecture [seeds={:}] {:}".format(
+ "-" * 15,
+ i,
+ len(to_evaluate_indexes),
+ index,
+ meta_info["total"],
+ seeds,
+ "-" * 15,
+ )
+ )
+ # logger.log('{:} {:} {:}'.format('-'*15, arch.tostr(), '-'*15))
+ logger.log("{:} {:} {:}".format("-" * 15, arch, "-" * 15))
+
+ # test this arch on different datasets with different seeds
+ has_continue = False
+ for seed in seeds:
+ to_save_name = sub_dir / "arch-{:06d}-seed-{:04d}.pth".format(index, seed)
+ if to_save_name.exists():
+ if cover_mode:
+ logger.log(
+ "Find existing file : {:}, remove it before evaluation".format(
+ to_save_name
+ )
+ )
+ os.remove(str(to_save_name))
+ else:
+ logger.log(
+ "Find existing file : {:}, skip this evaluation".format(
+ to_save_name
+ )
+ )
+ has_continue = True
+ continue
+ results = evaluate_all_datasets(
+ CellStructure.str2structure(arch),
+ datasets,
+ xpaths,
+ splits,
+ use_less,
+ seed,
+ arch_config,
+ workers,
+ logger,
+ )
+ torch.save(results, to_save_name)
+ logger.log(
+ "{:} --evaluate-- {:06d}/{:06d} ({:06d}/{:06d})-th seed={:} done, save into {:}".format(
+ "-" * 15,
+ i,
+ len(to_evaluate_indexes),
+ index,
+ meta_info["total"],
+ seed,
+ to_save_name,
+ )
+ )
+ # measure elapsed time
+ if not has_continue:
+ epoch_time.update(time.time() - start_time)
+ start_time = time.time()
+ need_time = "Time Left: {:}".format(
+ convert_secs2time(epoch_time.avg * (len(to_evaluate_indexes) - i - 1), True)
+ )
+ logger.log(
+ "This arch costs : {:}".format(convert_secs2time(epoch_time.val, True))
+ )
+ logger.log("{:}".format("*" * 100))
+ logger.log(
+ "{:} {:74s} {:}".format(
+ "*" * 10,
+ "{:06d}/{:06d} ({:06d}/{:06d})-th done, left {:}".format(
+ i, len(to_evaluate_indexes), index, meta_info["total"], need_time
+ ),
+ "*" * 10,
+ )
+ )
+ logger.log("{:}".format("*" * 100))
+
+ logger.close()
+
+
+def train_single_model(
+ save_dir, workers, datasets, xpaths, splits, use_less, seeds, model_str, arch_config
+):
+ assert torch.cuda.is_available(), "CUDA is not available."
+ torch.backends.cudnn.enabled = True
+ torch.backends.cudnn.deterministic = True
+ # torch.backends.cudnn.benchmark = True
+ torch.set_num_threads(workers)
+
+ save_dir = (
+ Path(save_dir)
+ / "specifics"
+ / "{:}-{:}-{:}-{:}".format(
+ "LESS" if use_less else "FULL",
+ model_str,
+ arch_config["channel"],
+ arch_config["num_cells"],
+ )
+ )
+ logger = Logger(str(save_dir), 0, False)
+ if model_str in CellArchitectures:
+ arch = CellArchitectures[model_str]
+ logger.log(
+ "The model string is found in pre-defined architecture dict : {:}".format(
+ model_str
+ )
+ )
+ else:
+ try:
+ arch = CellStructure.str2structure(model_str)
+ except:
+ raise ValueError(
+ "Invalid model string : {:}. It can not be found or parsed.".format(
+ model_str
+ )
+ )
+ assert arch.check_valid_op(
+ get_search_spaces("cell", "full")
+ ), "{:} has the invalid op.".format(arch)
+ logger.log("Start train-evaluate {:}".format(arch.tostr()))
+ logger.log("arch_config : {:}".format(arch_config))
+
+ start_time, seed_time = time.time(), AverageMeter()
+ for _is, seed in enumerate(seeds):
+ logger.log(
+ "\nThe {:02d}/{:02d}-th seed is {:} ----------------------<.>----------------------".format(
+ _is, len(seeds), seed
+ )
+ )
+ to_save_name = save_dir / "seed-{:04d}.pth".format(seed)
+ if to_save_name.exists():
+ logger.log(
+ "Find the existing file {:}, directly load!".format(to_save_name)
+ )
+ checkpoint = torch.load(to_save_name)
+ else:
+ logger.log(
+ "Does not find the existing file {:}, train and evaluate!".format(
+ to_save_name
+ )
+ )
+ checkpoint = evaluate_all_datasets(
+ arch,
+ datasets,
+ xpaths,
+ splits,
+ use_less,
+ seed,
+ arch_config,
+ workers,
+ logger,
+ )
+ torch.save(checkpoint, to_save_name)
+ # log information
+ logger.log("{:}".format(checkpoint["info"]))
+ all_dataset_keys = checkpoint["all_dataset_keys"]
+ for dataset_key in all_dataset_keys:
+ logger.log(
+ "\n{:} dataset : {:} {:}".format("-" * 15, dataset_key, "-" * 15)
+ )
+ dataset_info = checkpoint[dataset_key]
+ # logger.log('Network ==>\n{:}'.format( dataset_info['net_string'] ))
+ logger.log(
+ "Flops = {:} MB, Params = {:} MB".format(
+ dataset_info["flop"], dataset_info["param"]
+ )
+ )
+ logger.log("config : {:}".format(dataset_info["config"]))
+ logger.log(
+ "Training State (finish) = {:}".format(dataset_info["finish-train"])
+ )
+ last_epoch = dataset_info["total_epoch"] - 1
+ train_acc1es, train_acc5es = (
+ dataset_info["train_acc1es"],
+ dataset_info["train_acc5es"],
+ )
+ valid_acc1es, valid_acc5es = (
+ dataset_info["valid_acc1es"],
+ dataset_info["valid_acc5es"],
+ )
+ logger.log(
+ "Last Info : Train = Acc@1 {:.2f}% Acc@5 {:.2f}% Error@1 {:.2f}%, Test = Acc@1 {:.2f}% Acc@5 {:.2f}% Error@1 {:.2f}%".format(
+ train_acc1es[last_epoch],
+ train_acc5es[last_epoch],
+ 100 - train_acc1es[last_epoch],
+ valid_acc1es[last_epoch],
+ valid_acc5es[last_epoch],
+ 100 - valid_acc1es[last_epoch],
+ )
+ )
+ # measure elapsed time
+ seed_time.update(time.time() - start_time)
+ start_time = time.time()
+ need_time = "Time Left: {:}".format(
+ convert_secs2time(seed_time.avg * (len(seeds) - _is - 1), True)
+ )
+ logger.log(
+ "\n<<<***>>> The {:02d}/{:02d}-th seed is {:} other procedures need {:}".format(
+ _is, len(seeds), seed, need_time
+ )
+ )
+ logger.close()
+
+
+def generate_meta_info(save_dir, max_node, divide=40):
+ aa_nas_bench_ss = get_search_spaces("cell", "nas-bench-201")
+ archs = CellStructure.gen_all(aa_nas_bench_ss, max_node, False)
+ print(
+ "There are {:} archs vs {:}.".format(
+ len(archs), len(aa_nas_bench_ss) ** ((max_node - 1) * max_node / 2)
+ )
+ )
+
+ random.seed(88) # please do not change this line for reproducibility
+ random.shuffle(archs)
+ # to test fixed-random shuffle
+ # print ('arch [0] : {:}\n---->>>> {:}'.format( archs[0], archs[0].tostr() ))
+ # print ('arch [9] : {:}\n---->>>> {:}'.format( archs[9], archs[9].tostr() ))
+ assert (
+ archs[0].tostr()
+ == "|avg_pool_3x3~0|+|nor_conv_1x1~0|skip_connect~1|+|nor_conv_1x1~0|skip_connect~1|skip_connect~2|"
+ ), "please check the 0-th architecture : {:}".format(archs[0])
+ assert (
+ archs[9].tostr()
+ == "|avg_pool_3x3~0|+|none~0|none~1|+|skip_connect~0|none~1|nor_conv_3x3~2|"
+ ), "please check the 9-th architecture : {:}".format(archs[9])
+ assert (
+ archs[123].tostr()
+ == "|avg_pool_3x3~0|+|avg_pool_3x3~0|nor_conv_1x1~1|+|none~0|avg_pool_3x3~1|nor_conv_3x3~2|"
+ ), "please check the 123-th architecture : {:}".format(archs[123])
+ total_arch = len(archs)
+
+ num = 50000
+ indexes_5W = list(range(num))
+ random.seed(1021)
+ random.shuffle(indexes_5W)
+ train_split = sorted(list(set(indexes_5W[: num // 2])))
+ valid_split = sorted(list(set(indexes_5W[num // 2 :])))
+ assert len(train_split) + len(valid_split) == num
+ assert (
+ train_split[0] == 0
+ and train_split[10] == 26
+ and train_split[111] == 203
+ and valid_split[0] == 1
+ and valid_split[10] == 18
+ and valid_split[111] == 242
+ ), "{:} {:} {:} - {:} {:} {:}".format(
+ train_split[0],
+ train_split[10],
+ train_split[111],
+ valid_split[0],
+ valid_split[10],
+ valid_split[111],
+ )
+ splits = {num: {"train": train_split, "valid": valid_split}}
+
+ info = {
+ "archs": [x.tostr() for x in archs],
+ "total": total_arch,
+ "max_node": max_node,
+ "splits": splits,
+ }
+
+ save_dir = Path(save_dir)
+ save_dir.mkdir(parents=True, exist_ok=True)
+ save_name = save_dir / "meta-node-{:}.pth".format(max_node)
+ assert not save_name.exists(), "{:} already exist".format(save_name)
+ torch.save(info, save_name)
+ print("save the meta file into {:}".format(save_name))
+
+ script_name_full = save_dir / "BENCH-201-N{:}.opt-full.script".format(max_node)
+ script_name_less = save_dir / "BENCH-201-N{:}.opt-less.script".format(max_node)
+ full_file = open(str(script_name_full), "w")
+ less_file = open(str(script_name_less), "w")
+ gaps = total_arch // divide
+ for start in range(0, total_arch, gaps):
+ xend = min(start + gaps, total_arch)
+ full_file.write(
+ "bash ./scripts-search/NAS-Bench-201/train-models.sh 0 {:5d} {:5d} -1 '777 888 999'\n".format(
+ start, xend - 1
+ )
+ )
+ less_file.write(
+ "bash ./scripts-search/NAS-Bench-201/train-models.sh 1 {:5d} {:5d} -1 '777 888 999'\n".format(
+ start, xend - 1
+ )
+ )
+ print(
+ "save the training script into {:} and {:}".format(
+ script_name_full, script_name_less
+ )
+ )
+ full_file.close()
+ less_file.close()
+
+ script_name = save_dir / "meta-node-{:}.cal-script.txt".format(max_node)
+ macro = "OMP_NUM_THREADS=6 CUDA_VISIBLE_DEVICES=0"
+ with open(str(script_name), "w") as cfile:
+ for start in range(0, total_arch, gaps):
+ xend = min(start + gaps, total_arch)
+ cfile.write(
+ "{:} python exps/NAS-Bench-201/statistics.py --mode cal --target_dir {:06d}-{:06d}-C16-N5\n".format(
+ macro, start, xend - 1
+ )
+ )
+ print("save the post-processing script into {:}".format(script_name))
+
+
+if __name__ == "__main__":
+ # mode_choices = ['meta', 'new', 'cover'] + ['specific-{:}'.format(_) for _ in CellArchitectures.keys()]
+ # parser = argparse.ArgumentParser(description='Algorithm-Agnostic NAS Benchmark', formatter_class=argparse.ArgumentDefaultsHelpFormatter)
+ parser = argparse.ArgumentParser(
+ description="NAS-Bench-201",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ )
+ parser.add_argument("--mode", type=str, required=True, help="The script mode.")
+ parser.add_argument(
+ "--save_dir", type=str, help="Folder to save checkpoints and log."
+ )
+ parser.add_argument("--max_node", type=int, help="The maximum node in a cell.")
+ # use for train the model
+ parser.add_argument(
+ "--workers",
+ type=int,
+ default=8,
+ help="number of data loading workers (default: 2)",
+ )
+ parser.add_argument(
+ "--srange", type=int, nargs="+", help="The range of models to be evaluated"
+ )
+ parser.add_argument(
+ "--arch_index",
+ type=int,
+ default=-1,
+ help="The architecture index to be evaluated (cover mode).",
+ )
+ parser.add_argument("--datasets", type=str, nargs="+", help="The applied datasets.")
+ parser.add_argument(
+ "--xpaths", type=str, nargs="+", help="The root path for this dataset."
+ )
+ parser.add_argument(
+ "--splits", type=int, nargs="+", help="The root path for this dataset."
+ )
+ parser.add_argument(
+ "--use_less",
+ type=int,
+ default=0,
+ choices=[0, 1],
+ help="Using the less-training-epoch config.",
+ )
+ parser.add_argument(
+ "--seeds", type=int, nargs="+", help="The range of models to be evaluated"
+ )
+ parser.add_argument("--channel", type=int, help="The number of channels.")
+ parser.add_argument(
+ "--num_cells", type=int, help="The number of cells in one stage."
+ )
+ args = parser.parse_args()
+
+ assert args.mode in ["meta", "new", "cover"] or args.mode.startswith(
+ "specific-"
+ ), "invalid mode : {:}".format(args.mode)
+
+ if args.mode == "meta":
+ generate_meta_info(args.save_dir, args.max_node)
+ elif args.mode.startswith("specific"):
+ assert len(args.mode.split("-")) == 2, "invalid mode : {:}".format(args.mode)
+ model_str = args.mode.split("-")[1]
+ train_single_model(
+ args.save_dir,
+ args.workers,
+ args.datasets,
+ args.xpaths,
+ args.splits,
+ args.use_less > 0,
+ tuple(args.seeds),
+ model_str,
+ {"channel": args.channel, "num_cells": args.num_cells},
+ )
+ else:
+ meta_path = Path(args.save_dir) / "meta-node-{:}.pth".format(args.max_node)
+ assert meta_path.exists(), "{:} does not exist.".format(meta_path)
+ meta_info = torch.load(meta_path)
+ # check whether args is ok
+ assert (
+ len(args.srange) == 2 and args.srange[0] <= args.srange[1]
+ ), "invalid length of srange args: {:}".format(args.srange)
+ assert len(args.seeds) > 0, "invalid length of seeds args: {:}".format(
+ args.seeds
+ )
+ assert (
+ len(args.datasets) == len(args.xpaths) == len(args.splits)
+ ), "invalid infos : {:} vs {:} vs {:}".format(
+ len(args.datasets), len(args.xpaths), len(args.splits)
+ )
+ assert args.workers > 0, "invalid number of workers : {:}".format(args.workers)
+
+ main(
+ args.save_dir,
+ args.workers,
+ args.datasets,
+ args.xpaths,
+ args.splits,
+ args.use_less > 0,
+ tuple(args.srange),
+ args.arch_index,
+ tuple(args.seeds),
+ args.mode == "cover",
+ meta_info,
+ {"channel": args.channel, "num_cells": args.num_cells},
+ )
diff --git a/AutoDL-Projects/exps/NAS-Bench-201/show-best.py b/AutoDL-Projects/exps/NAS-Bench-201/show-best.py
new file mode 100644
index 0000000..814bdc4
--- /dev/null
+++ b/AutoDL-Projects/exps/NAS-Bench-201/show-best.py
@@ -0,0 +1,43 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020.01 #
+################################################################################################
+# python exps/NAS-Bench-201/show-best.py --api_path $HOME/.torch/NAS-Bench-201-v1_0-e61699.pth #
+################################################################################################
+import argparse
+from pathlib import Path
+
+from nas_201_api import NASBench201API as API
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser("Analysis of NAS-Bench-201")
+ parser.add_argument(
+ "--api_path",
+ type=str,
+ default=None,
+ help="The path to the NAS-Bench-201 benchmark file.",
+ )
+ args = parser.parse_args()
+
+ meta_file = Path(args.api_path)
+ assert meta_file.exists(), "invalid path for api : {:}".format(meta_file)
+
+ api = API(str(meta_file))
+
+ # This will show the results of the best architecture based on the validation set of each dataset.
+ arch_index, accuracy = api.find_best("cifar10-valid", "x-valid", None, None, False)
+ print("FOR CIFAR-010, using the hyper-parameters with 200 training epochs :::")
+ print("arch-index={:5d}, arch={:}".format(arch_index, api.arch(arch_index)))
+ api.show(arch_index)
+ print("")
+
+ arch_index, accuracy = api.find_best("cifar100", "x-valid", None, None, False)
+ print("FOR CIFAR-100, using the hyper-parameters with 200 training epochs :::")
+ print("arch-index={:5d}, arch={:}".format(arch_index, api.arch(arch_index)))
+ api.show(arch_index)
+ print("")
+
+ arch_index, accuracy = api.find_best("ImageNet16-120", "x-valid", None, None, False)
+ print("FOR ImageNet16-120, using the hyper-parameters with 200 training epochs :::")
+ print("arch-index={:5d}, arch={:}".format(arch_index, api.arch(arch_index)))
+ api.show(arch_index)
+ print("")
diff --git a/AutoDL-Projects/exps/NAS-Bench-201/statistics-v2.py b/AutoDL-Projects/exps/NAS-Bench-201/statistics-v2.py
new file mode 100644
index 0000000..d1a54a1
--- /dev/null
+++ b/AutoDL-Projects/exps/NAS-Bench-201/statistics-v2.py
@@ -0,0 +1,553 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.08 #
+#####################################################
+import os, sys, time, argparse, collections
+import numpy as np
+import torch
+from pathlib import Path
+from collections import defaultdict, OrderedDict
+from typing import Dict, Any, Text, List
+
+from xautodl.log_utils import AverageMeter, time_string, convert_secs2time
+from xautodl.config_utils import dict2config
+
+# NAS-Bench-201 related module or function
+from xautodl.models import CellStructure, get_cell_based_tiny_net
+from xautodl.procedures import (
+ bench_pure_evaluate as pure_evaluate,
+ get_nas_bench_loaders,
+)
+from nas_201_api import NASBench201API, ArchResults, ResultsCount
+
+api = NASBench201API(
+ "{:}/.torch/NAS-Bench-201-v1_0-e61699.pth".format(os.environ["HOME"])
+)
+
+
+def create_result_count(
+ used_seed: int,
+ dataset: Text,
+ arch_config: Dict[Text, Any],
+ results: Dict[Text, Any],
+ dataloader_dict: Dict[Text, Any],
+) -> ResultsCount:
+ xresult = ResultsCount(
+ dataset,
+ results["net_state_dict"],
+ results["train_acc1es"],
+ results["train_losses"],
+ results["param"],
+ results["flop"],
+ arch_config,
+ used_seed,
+ results["total_epoch"],
+ None,
+ )
+ net_config = dict2config(
+ {
+ "name": "infer.tiny",
+ "C": arch_config["channel"],
+ "N": arch_config["num_cells"],
+ "genotype": CellStructure.str2structure(arch_config["arch_str"]),
+ "num_classes": arch_config["class_num"],
+ },
+ None,
+ )
+ network = get_cell_based_tiny_net(net_config)
+ network.load_state_dict(xresult.get_net_param())
+ if "train_times" in results: # new version
+ xresult.update_train_info(
+ results["train_acc1es"],
+ results["train_acc5es"],
+ results["train_losses"],
+ results["train_times"],
+ )
+ xresult.update_eval(
+ results["valid_acc1es"], results["valid_losses"], results["valid_times"]
+ )
+ else:
+ if dataset == "cifar10-valid":
+ xresult.update_OLD_eval(
+ "x-valid", results["valid_acc1es"], results["valid_losses"]
+ )
+ loss, top1, top5, latencies = pure_evaluate(
+ dataloader_dict["{:}@{:}".format("cifar10", "test")], network.cuda()
+ )
+ xresult.update_OLD_eval(
+ "ori-test",
+ {results["total_epoch"] - 1: top1},
+ {results["total_epoch"] - 1: loss},
+ )
+ xresult.update_latency(latencies)
+ elif dataset == "cifar10":
+ xresult.update_OLD_eval(
+ "ori-test", results["valid_acc1es"], results["valid_losses"]
+ )
+ loss, top1, top5, latencies = pure_evaluate(
+ dataloader_dict["{:}@{:}".format(dataset, "test")], network.cuda()
+ )
+ xresult.update_latency(latencies)
+ elif dataset == "cifar100" or dataset == "ImageNet16-120":
+ xresult.update_OLD_eval(
+ "ori-test", results["valid_acc1es"], results["valid_losses"]
+ )
+ loss, top1, top5, latencies = pure_evaluate(
+ dataloader_dict["{:}@{:}".format(dataset, "valid")], network.cuda()
+ )
+ xresult.update_OLD_eval(
+ "x-valid",
+ {results["total_epoch"] - 1: top1},
+ {results["total_epoch"] - 1: loss},
+ )
+ loss, top1, top5, latencies = pure_evaluate(
+ dataloader_dict["{:}@{:}".format(dataset, "test")], network.cuda()
+ )
+ xresult.update_OLD_eval(
+ "x-test",
+ {results["total_epoch"] - 1: top1},
+ {results["total_epoch"] - 1: loss},
+ )
+ xresult.update_latency(latencies)
+ else:
+ raise ValueError("invalid dataset name : {:}".format(dataset))
+ return xresult
+
+
+def account_one_arch(
+ arch_index: int,
+ arch_str: Text,
+ checkpoints: List[Text],
+ datasets: List[Text],
+ dataloader_dict: Dict[Text, Any],
+) -> ArchResults:
+ information = ArchResults(arch_index, arch_str)
+
+ for checkpoint_path in checkpoints:
+ checkpoint = torch.load(checkpoint_path, map_location="cpu")
+ used_seed = checkpoint_path.name.split("-")[-1].split(".")[0]
+ ok_dataset = 0
+ for dataset in datasets:
+ if dataset not in checkpoint:
+ print(
+ "Can not find {:} in arch-{:} from {:}".format(
+ dataset, arch_index, checkpoint_path
+ )
+ )
+ continue
+ else:
+ ok_dataset += 1
+ results = checkpoint[dataset]
+ assert results[
+ "finish-train"
+ ], "This {:} arch seed={:} does not finish train on {:} ::: {:}".format(
+ arch_index, used_seed, dataset, checkpoint_path
+ )
+ arch_config = {
+ "channel": results["channel"],
+ "num_cells": results["num_cells"],
+ "arch_str": arch_str,
+ "class_num": results["config"]["class_num"],
+ }
+
+ xresult = create_result_count(
+ used_seed, dataset, arch_config, results, dataloader_dict
+ )
+ information.update(dataset, int(used_seed), xresult)
+ if ok_dataset == 0:
+ raise ValueError("{:} does not find any data".format(checkpoint_path))
+ return information
+
+
+def correct_time_related_info(
+ arch_index: int, arch_info_full: ArchResults, arch_info_less: ArchResults
+):
+ # calibrate the latency based on NAS-Bench-201-v1_0-e61699.pth
+ cifar010_latency = (
+ api.get_latency(arch_index, "cifar10-valid", hp="200")
+ + api.get_latency(arch_index, "cifar10", hp="200")
+ ) / 2
+ arch_info_full.reset_latency("cifar10-valid", None, cifar010_latency)
+ arch_info_full.reset_latency("cifar10", None, cifar010_latency)
+ arch_info_less.reset_latency("cifar10-valid", None, cifar010_latency)
+ arch_info_less.reset_latency("cifar10", None, cifar010_latency)
+
+ cifar100_latency = api.get_latency(arch_index, "cifar100", hp="200")
+ arch_info_full.reset_latency("cifar100", None, cifar100_latency)
+ arch_info_less.reset_latency("cifar100", None, cifar100_latency)
+
+ image_latency = api.get_latency(arch_index, "ImageNet16-120", hp="200")
+ arch_info_full.reset_latency("ImageNet16-120", None, image_latency)
+ arch_info_less.reset_latency("ImageNet16-120", None, image_latency)
+
+ train_per_epoch_time = list(
+ arch_info_less.query("cifar10-valid", 777).train_times.values()
+ )
+ train_per_epoch_time = sum(train_per_epoch_time) / len(train_per_epoch_time)
+ eval_ori_test_time, eval_x_valid_time = [], []
+ for key, value in arch_info_less.query("cifar10-valid", 777).eval_times.items():
+ if key.startswith("ori-test@"):
+ eval_ori_test_time.append(value)
+ elif key.startswith("x-valid@"):
+ eval_x_valid_time.append(value)
+ else:
+ raise ValueError("-- {:} --".format(key))
+ eval_ori_test_time, eval_x_valid_time = float(np.mean(eval_ori_test_time)), float(
+ np.mean(eval_x_valid_time)
+ )
+ nums = {
+ "ImageNet16-120-train": 151700,
+ "ImageNet16-120-valid": 3000,
+ "ImageNet16-120-test": 6000,
+ "cifar10-valid-train": 25000,
+ "cifar10-valid-valid": 25000,
+ "cifar10-train": 50000,
+ "cifar10-test": 10000,
+ "cifar100-train": 50000,
+ "cifar100-test": 10000,
+ "cifar100-valid": 5000,
+ }
+ eval_per_sample = (eval_ori_test_time + eval_x_valid_time) / (
+ nums["cifar10-valid-valid"] + nums["cifar10-test"]
+ )
+ for arch_info in [arch_info_less, arch_info_full]:
+ arch_info.reset_pseudo_train_times(
+ "cifar10-valid",
+ None,
+ train_per_epoch_time
+ / nums["cifar10-valid-train"]
+ * nums["cifar10-valid-train"],
+ )
+ arch_info.reset_pseudo_train_times(
+ "cifar10",
+ None,
+ train_per_epoch_time / nums["cifar10-valid-train"] * nums["cifar10-train"],
+ )
+ arch_info.reset_pseudo_train_times(
+ "cifar100",
+ None,
+ train_per_epoch_time / nums["cifar10-valid-train"] * nums["cifar100-train"],
+ )
+ arch_info.reset_pseudo_train_times(
+ "ImageNet16-120",
+ None,
+ train_per_epoch_time
+ / nums["cifar10-valid-train"]
+ * nums["ImageNet16-120-train"],
+ )
+ arch_info.reset_pseudo_eval_times(
+ "cifar10-valid",
+ None,
+ "x-valid",
+ eval_per_sample * nums["cifar10-valid-valid"],
+ )
+ arch_info.reset_pseudo_eval_times(
+ "cifar10-valid", None, "ori-test", eval_per_sample * nums["cifar10-test"]
+ )
+ arch_info.reset_pseudo_eval_times(
+ "cifar10", None, "ori-test", eval_per_sample * nums["cifar10-test"]
+ )
+ arch_info.reset_pseudo_eval_times(
+ "cifar100", None, "x-valid", eval_per_sample * nums["cifar100-valid"]
+ )
+ arch_info.reset_pseudo_eval_times(
+ "cifar100", None, "x-test", eval_per_sample * nums["cifar100-valid"]
+ )
+ arch_info.reset_pseudo_eval_times(
+ "cifar100", None, "ori-test", eval_per_sample * nums["cifar100-test"]
+ )
+ arch_info.reset_pseudo_eval_times(
+ "ImageNet16-120",
+ None,
+ "x-valid",
+ eval_per_sample * nums["ImageNet16-120-valid"],
+ )
+ arch_info.reset_pseudo_eval_times(
+ "ImageNet16-120",
+ None,
+ "x-test",
+ eval_per_sample * nums["ImageNet16-120-valid"],
+ )
+ arch_info.reset_pseudo_eval_times(
+ "ImageNet16-120",
+ None,
+ "ori-test",
+ eval_per_sample * nums["ImageNet16-120-test"],
+ )
+ # arch_info_full.debug_test()
+ # arch_info_less.debug_test()
+ return arch_info_full, arch_info_less
+
+
+def simplify(save_dir, meta_file, basestr, target_dir):
+ meta_infos = torch.load(meta_file, map_location="cpu")
+ meta_archs = meta_infos["archs"] # a list of architecture strings
+ meta_num_archs = meta_infos["total"]
+ assert meta_num_archs == len(
+ meta_archs
+ ), "invalid number of archs : {:} vs {:}".format(meta_num_archs, len(meta_archs))
+
+ sub_model_dirs = sorted(list(save_dir.glob("*-*-{:}".format(basestr))))
+ print(
+ "{:} find {:} directories used to save checkpoints".format(
+ time_string(), len(sub_model_dirs)
+ )
+ )
+
+ subdir2archs, num_evaluated_arch = collections.OrderedDict(), 0
+ num_seeds = defaultdict(lambda: 0)
+ for index, sub_dir in enumerate(sub_model_dirs):
+ xcheckpoints = list(sub_dir.glob("arch-*-seed-*.pth"))
+ arch_indexes = set()
+ for checkpoint in xcheckpoints:
+ temp_names = checkpoint.name.split("-")
+ assert (
+ len(temp_names) == 4
+ and temp_names[0] == "arch"
+ and temp_names[2] == "seed"
+ ), "invalid checkpoint name : {:}".format(checkpoint.name)
+ arch_indexes.add(temp_names[1])
+ subdir2archs[sub_dir] = sorted(list(arch_indexes))
+ num_evaluated_arch += len(arch_indexes)
+ # count number of seeds for each architecture
+ for arch_index in arch_indexes:
+ num_seeds[
+ len(list(sub_dir.glob("arch-{:}-seed-*.pth".format(arch_index))))
+ ] += 1
+ print(
+ "{:} There are {:5d} architectures that have been evaluated ({:} in total).".format(
+ time_string(), num_evaluated_arch, meta_num_archs
+ )
+ )
+ for key in sorted(list(num_seeds.keys())):
+ print(
+ "{:} There are {:5d} architectures that are evaluated {:} times.".format(
+ time_string(), num_seeds[key], key
+ )
+ )
+
+ dataloader_dict = get_nas_bench_loaders(6)
+ to_save_simply = save_dir / "simplifies"
+ to_save_allarc = save_dir / "simplifies" / "architectures"
+ if not to_save_simply.exists():
+ to_save_simply.mkdir(parents=True, exist_ok=True)
+ if not to_save_allarc.exists():
+ to_save_allarc.mkdir(parents=True, exist_ok=True)
+
+ assert (save_dir / target_dir) in subdir2archs, "can not find {:}".format(
+ target_dir
+ )
+ arch2infos, datasets = {}, (
+ "cifar10-valid",
+ "cifar10",
+ "cifar100",
+ "ImageNet16-120",
+ )
+ evaluated_indexes = set()
+ target_full_dir = save_dir / target_dir
+ target_less_dir = save_dir / "{:}-LESS".format(target_dir)
+ arch_indexes = subdir2archs[target_full_dir]
+ num_seeds = defaultdict(lambda: 0)
+ end_time = time.time()
+ arch_time = AverageMeter()
+ for idx, arch_index in enumerate(arch_indexes):
+ checkpoints = list(
+ target_full_dir.glob("arch-{:}-seed-*.pth".format(arch_index))
+ )
+ ckps_less = list(target_less_dir.glob("arch-{:}-seed-*.pth".format(arch_index)))
+ # create the arch info for each architecture
+ try:
+ arch_info_full = account_one_arch(
+ arch_index,
+ meta_archs[int(arch_index)],
+ checkpoints,
+ datasets,
+ dataloader_dict,
+ )
+ arch_info_less = account_one_arch(
+ arch_index,
+ meta_archs[int(arch_index)],
+ ckps_less,
+ datasets,
+ dataloader_dict,
+ )
+ num_seeds[len(checkpoints)] += 1
+ except:
+ print("Loading {:} failed, : {:}".format(arch_index, checkpoints))
+ continue
+ assert (
+ int(arch_index) not in evaluated_indexes
+ ), "conflict arch-index : {:}".format(arch_index)
+ assert (
+ 0 <= int(arch_index) < len(meta_archs)
+ ), "invalid arch-index {:} (not found in meta_archs)".format(arch_index)
+ arch_info = {"full": arch_info_full, "less": arch_info_less}
+ evaluated_indexes.add(int(arch_index))
+ arch2infos[int(arch_index)] = arch_info
+ # to correct the latency and training_time info.
+ arch_info_full, arch_info_less = correct_time_related_info(
+ int(arch_index), arch_info_full, arch_info_less
+ )
+ to_save_data = OrderedDict(
+ full=arch_info_full.state_dict(), less=arch_info_less.state_dict()
+ )
+ torch.save(to_save_data, to_save_allarc / "{:}-FULL.pth".format(arch_index))
+ arch_info["full"].clear_params()
+ arch_info["less"].clear_params()
+ torch.save(to_save_data, to_save_allarc / "{:}-SIMPLE.pth".format(arch_index))
+ # measure elapsed time
+ arch_time.update(time.time() - end_time)
+ end_time = time.time()
+ need_time = "{:}".format(
+ convert_secs2time(arch_time.avg * (len(arch_indexes) - idx - 1), True)
+ )
+ print(
+ "{:} {:} [{:03d}/{:03d}] : {:} still need {:}".format(
+ time_string(), target_dir, idx, len(arch_indexes), arch_index, need_time
+ )
+ )
+ # measure time
+ xstrs = [
+ "{:}:{:03d}".format(key, num_seeds[key])
+ for key in sorted(list(num_seeds.keys()))
+ ]
+ print("{:} {:} done : {:}".format(time_string(), target_dir, xstrs))
+ final_infos = {
+ "meta_archs": meta_archs,
+ "total_archs": meta_num_archs,
+ "basestr": basestr,
+ "arch2infos": arch2infos,
+ "evaluated_indexes": evaluated_indexes,
+ }
+ save_file_name = to_save_simply / "{:}.pth".format(target_dir)
+ torch.save(final_infos, save_file_name)
+ print(
+ "Save {:} / {:} architecture results into {:}.".format(
+ len(evaluated_indexes), meta_num_archs, save_file_name
+ )
+ )
+
+
+def merge_all(save_dir, meta_file, basestr):
+ meta_infos = torch.load(meta_file, map_location="cpu")
+ meta_archs = meta_infos["archs"]
+ meta_num_archs = meta_infos["total"]
+ assert meta_num_archs == len(
+ meta_archs
+ ), "invalid number of archs : {:} vs {:}".format(meta_num_archs, len(meta_archs))
+
+ sub_model_dirs = sorted(list(save_dir.glob("*-*-{:}".format(basestr))))
+ print(
+ "{:} find {:} directories used to save checkpoints".format(
+ time_string(), len(sub_model_dirs)
+ )
+ )
+ for index, sub_dir in enumerate(sub_model_dirs):
+ arch_info_files = sorted(list(sub_dir.glob("arch-*-seed-*.pth")))
+ print(
+ "The {:02d}/{:02d}-th directory : {:} : {:} runs.".format(
+ index, len(sub_model_dirs), sub_dir, len(arch_info_files)
+ )
+ )
+
+ arch2infos, evaluated_indexes = dict(), set()
+ for IDX, sub_dir in enumerate(sub_model_dirs):
+ ckp_path = sub_dir.parent / "simplifies" / "{:}.pth".format(sub_dir.name)
+ if ckp_path.exists():
+ sub_ckps = torch.load(ckp_path, map_location="cpu")
+ assert (
+ sub_ckps["total_archs"] == meta_num_archs
+ and sub_ckps["basestr"] == basestr
+ )
+ xarch2infos = sub_ckps["arch2infos"]
+ xevalindexs = sub_ckps["evaluated_indexes"]
+ for eval_index in xevalindexs:
+ assert (
+ eval_index not in evaluated_indexes and eval_index not in arch2infos
+ )
+ # arch2infos[eval_index] = xarch2infos[eval_index].state_dict()
+ arch2infos[eval_index] = {
+ "full": xarch2infos[eval_index]["full"].state_dict(),
+ "less": xarch2infos[eval_index]["less"].state_dict(),
+ }
+ evaluated_indexes.add(eval_index)
+ print(
+ "{:} [{:03d}/{:03d}] merge data from {:} with {:} models.".format(
+ time_string(), IDX, len(sub_model_dirs), ckp_path, len(xevalindexs)
+ )
+ )
+ else:
+ raise ValueError("Can not find {:}".format(ckp_path))
+ # print ('{:} [{:03d}/{:03d}] can not find {:}, skip.'.format(time_string(), IDX, len(subdir2archs), ckp_path))
+
+ evaluated_indexes = sorted(list(evaluated_indexes))
+ print(
+ "Finally, there are {:} architectures that have been trained and evaluated.".format(
+ len(evaluated_indexes)
+ )
+ )
+
+ to_save_simply = save_dir / "simplifies"
+ if not to_save_simply.exists():
+ to_save_simply.mkdir(parents=True, exist_ok=True)
+ final_infos = {
+ "meta_archs": meta_archs,
+ "total_archs": meta_num_archs,
+ "arch2infos": arch2infos,
+ "evaluated_indexes": evaluated_indexes,
+ }
+ save_file_name = to_save_simply / "{:}-final-infos.pth".format(basestr)
+ torch.save(final_infos, save_file_name)
+ print(
+ "Save {:} / {:} architecture results into {:}.".format(
+ len(evaluated_indexes), meta_num_archs, save_file_name
+ )
+ )
+
+
+if __name__ == "__main__":
+
+ parser = argparse.ArgumentParser(
+ description="NAS-BENCH-201",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ )
+ parser.add_argument(
+ "--mode",
+ type=str,
+ choices=["cal", "merge"],
+ help="The running mode for this script.",
+ )
+ parser.add_argument(
+ "--base_save_dir",
+ type=str,
+ default="./output/NAS-BENCH-201-4",
+ help="The base-name of folder to save checkpoints and log.",
+ )
+ parser.add_argument("--target_dir", type=str, help="The target directory.")
+ parser.add_argument(
+ "--max_node", type=int, default=4, help="The maximum node in a cell."
+ )
+ parser.add_argument(
+ "--channel", type=int, default=16, help="The number of channels."
+ )
+ parser.add_argument(
+ "--num_cells", type=int, default=5, help="The number of cells in one stage."
+ )
+ args = parser.parse_args()
+
+ save_dir = Path(args.base_save_dir)
+ meta_path = save_dir / "meta-node-{:}.pth".format(args.max_node)
+ assert save_dir.exists(), "invalid save dir path : {:}".format(save_dir)
+ assert meta_path.exists(), "invalid saved meta path : {:}".format(meta_path)
+ print(
+ "start the statistics of our nas-benchmark from {:} using {:}.".format(
+ save_dir, args.target_dir
+ )
+ )
+ basestr = "C{:}-N{:}".format(args.channel, args.num_cells)
+
+ if args.mode == "cal":
+ simplify(save_dir, meta_path, basestr, args.target_dir)
+ elif args.mode == "merge":
+ merge_all(save_dir, meta_path, basestr)
+ else:
+ raise ValueError("invalid mode : {:}".format(args.mode))
diff --git a/AutoDL-Projects/exps/NAS-Bench-201/statistics.py b/AutoDL-Projects/exps/NAS-Bench-201/statistics.py
new file mode 100644
index 0000000..7587b7a
--- /dev/null
+++ b/AutoDL-Projects/exps/NAS-Bench-201/statistics.py
@@ -0,0 +1,665 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.08 #
+#####################################################
+import os, sys, time, argparse, collections
+from copy import deepcopy
+import torch
+from pathlib import Path
+from collections import defaultdict
+
+from xautodl.log_utils import AverageMeter, time_string, convert_secs2time
+from xautodl.config_utils import load_config, dict2config
+from xautodl.datasets import get_datasets
+
+# NAS-Bench-201 related module or function
+from xautodl.models import CellStructure, get_cell_based_tiny_net
+from xautodl.procedures import bench_pure_evaluate as pure_evaluate
+from nas_201_api import ArchResults, ResultsCount
+
+
+def create_result_count(used_seed, dataset, arch_config, results, dataloader_dict):
+ xresult = ResultsCount(
+ dataset,
+ results["net_state_dict"],
+ results["train_acc1es"],
+ results["train_losses"],
+ results["param"],
+ results["flop"],
+ arch_config,
+ used_seed,
+ results["total_epoch"],
+ None,
+ )
+
+ net_config = dict2config(
+ {
+ "name": "infer.tiny",
+ "C": arch_config["channel"],
+ "N": arch_config["num_cells"],
+ "genotype": CellStructure.str2structure(arch_config["arch_str"]),
+ "num_classes": arch_config["class_num"],
+ },
+ None,
+ )
+ network = get_cell_based_tiny_net(net_config)
+ network.load_state_dict(xresult.get_net_param())
+ if "train_times" in results: # new version
+ xresult.update_train_info(
+ results["train_acc1es"],
+ results["train_acc5es"],
+ results["train_losses"],
+ results["train_times"],
+ )
+ xresult.update_eval(
+ results["valid_acc1es"], results["valid_losses"], results["valid_times"]
+ )
+ else:
+ if dataset == "cifar10-valid":
+ xresult.update_OLD_eval(
+ "x-valid", results["valid_acc1es"], results["valid_losses"]
+ )
+ loss, top1, top5, latencies = pure_evaluate(
+ dataloader_dict["{:}@{:}".format("cifar10", "test")], network.cuda()
+ )
+ xresult.update_OLD_eval(
+ "ori-test",
+ {results["total_epoch"] - 1: top1},
+ {results["total_epoch"] - 1: loss},
+ )
+ xresult.update_latency(latencies)
+ elif dataset == "cifar10":
+ xresult.update_OLD_eval(
+ "ori-test", results["valid_acc1es"], results["valid_losses"]
+ )
+ loss, top1, top5, latencies = pure_evaluate(
+ dataloader_dict["{:}@{:}".format(dataset, "test")], network.cuda()
+ )
+ xresult.update_latency(latencies)
+ elif dataset == "cifar100" or dataset == "ImageNet16-120":
+ xresult.update_OLD_eval(
+ "ori-test", results["valid_acc1es"], results["valid_losses"]
+ )
+ loss, top1, top5, latencies = pure_evaluate(
+ dataloader_dict["{:}@{:}".format(dataset, "valid")], network.cuda()
+ )
+ xresult.update_OLD_eval(
+ "x-valid",
+ {results["total_epoch"] - 1: top1},
+ {results["total_epoch"] - 1: loss},
+ )
+ loss, top1, top5, latencies = pure_evaluate(
+ dataloader_dict["{:}@{:}".format(dataset, "test")], network.cuda()
+ )
+ xresult.update_OLD_eval(
+ "x-test",
+ {results["total_epoch"] - 1: top1},
+ {results["total_epoch"] - 1: loss},
+ )
+ xresult.update_latency(latencies)
+ else:
+ raise ValueError("invalid dataset name : {:}".format(dataset))
+ return xresult
+
+
+def account_one_arch(arch_index, arch_str, checkpoints, datasets, dataloader_dict):
+ information = ArchResults(arch_index, arch_str)
+
+ for checkpoint_path in checkpoints:
+ checkpoint = torch.load(checkpoint_path, map_location="cpu")
+ used_seed = checkpoint_path.name.split("-")[-1].split(".")[0]
+ for dataset in datasets:
+ assert (
+ dataset in checkpoint
+ ), "Can not find {:} in arch-{:} from {:}".format(
+ dataset, arch_index, checkpoint_path
+ )
+ results = checkpoint[dataset]
+ assert results[
+ "finish-train"
+ ], "This {:} arch seed={:} does not finish train on {:} ::: {:}".format(
+ arch_index, used_seed, dataset, checkpoint_path
+ )
+ arch_config = {
+ "channel": results["channel"],
+ "num_cells": results["num_cells"],
+ "arch_str": arch_str,
+ "class_num": results["config"]["class_num"],
+ }
+
+ xresult = create_result_count(
+ used_seed, dataset, arch_config, results, dataloader_dict
+ )
+ information.update(dataset, int(used_seed), xresult)
+ return information
+
+
+def GET_DataLoaders(workers):
+
+ torch.set_num_threads(workers)
+
+ root_dir = (Path(__file__).parent / ".." / "..").resolve()
+ torch_dir = Path(os.environ["TORCH_HOME"])
+ # cifar
+ cifar_config_path = root_dir / "configs" / "nas-benchmark" / "CIFAR.config"
+ cifar_config = load_config(cifar_config_path, None, None)
+ print("{:} Create data-loader for all datasets".format(time_string()))
+ print("-" * 200)
+ TRAIN_CIFAR10, VALID_CIFAR10, xshape, class_num = get_datasets(
+ "cifar10", str(torch_dir / "cifar.python"), -1
+ )
+ print(
+ "original CIFAR-10 : {:} training images and {:} test images : {:} input shape : {:} number of classes".format(
+ len(TRAIN_CIFAR10), len(VALID_CIFAR10), xshape, class_num
+ )
+ )
+ cifar10_splits = load_config(
+ root_dir / "configs" / "nas-benchmark" / "cifar-split.txt", None, None
+ )
+ assert cifar10_splits.train[:10] == [
+ 0,
+ 5,
+ 7,
+ 11,
+ 13,
+ 15,
+ 16,
+ 17,
+ 20,
+ 24,
+ ] and cifar10_splits.valid[:10] == [
+ 1,
+ 2,
+ 3,
+ 4,
+ 6,
+ 8,
+ 9,
+ 10,
+ 12,
+ 14,
+ ]
+ temp_dataset = deepcopy(TRAIN_CIFAR10)
+ temp_dataset.transform = VALID_CIFAR10.transform
+ # data loader
+ trainval_cifar10_loader = torch.utils.data.DataLoader(
+ TRAIN_CIFAR10,
+ batch_size=cifar_config.batch_size,
+ shuffle=True,
+ num_workers=workers,
+ pin_memory=True,
+ )
+ train_cifar10_loader = torch.utils.data.DataLoader(
+ TRAIN_CIFAR10,
+ batch_size=cifar_config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(cifar10_splits.train),
+ num_workers=workers,
+ pin_memory=True,
+ )
+ valid_cifar10_loader = torch.utils.data.DataLoader(
+ temp_dataset,
+ batch_size=cifar_config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(cifar10_splits.valid),
+ num_workers=workers,
+ pin_memory=True,
+ )
+ test__cifar10_loader = torch.utils.data.DataLoader(
+ VALID_CIFAR10,
+ batch_size=cifar_config.batch_size,
+ shuffle=False,
+ num_workers=workers,
+ pin_memory=True,
+ )
+ print(
+ "CIFAR-10 : trval-loader has {:3d} batch with {:} per batch".format(
+ len(trainval_cifar10_loader), cifar_config.batch_size
+ )
+ )
+ print(
+ "CIFAR-10 : train-loader has {:3d} batch with {:} per batch".format(
+ len(train_cifar10_loader), cifar_config.batch_size
+ )
+ )
+ print(
+ "CIFAR-10 : valid-loader has {:3d} batch with {:} per batch".format(
+ len(valid_cifar10_loader), cifar_config.batch_size
+ )
+ )
+ print(
+ "CIFAR-10 : test--loader has {:3d} batch with {:} per batch".format(
+ len(test__cifar10_loader), cifar_config.batch_size
+ )
+ )
+ print("-" * 200)
+ # CIFAR-100
+ TRAIN_CIFAR100, VALID_CIFAR100, xshape, class_num = get_datasets(
+ "cifar100", str(torch_dir / "cifar.python"), -1
+ )
+ print(
+ "original CIFAR-100: {:} training images and {:} test images : {:} input shape : {:} number of classes".format(
+ len(TRAIN_CIFAR100), len(VALID_CIFAR100), xshape, class_num
+ )
+ )
+ cifar100_splits = load_config(
+ root_dir / "configs" / "nas-benchmark" / "cifar100-test-split.txt", None, None
+ )
+ assert cifar100_splits.xvalid[:10] == [
+ 1,
+ 3,
+ 4,
+ 5,
+ 8,
+ 10,
+ 13,
+ 14,
+ 15,
+ 16,
+ ] and cifar100_splits.xtest[:10] == [
+ 0,
+ 2,
+ 6,
+ 7,
+ 9,
+ 11,
+ 12,
+ 17,
+ 20,
+ 24,
+ ]
+ train_cifar100_loader = torch.utils.data.DataLoader(
+ TRAIN_CIFAR100,
+ batch_size=cifar_config.batch_size,
+ shuffle=True,
+ num_workers=workers,
+ pin_memory=True,
+ )
+ valid_cifar100_loader = torch.utils.data.DataLoader(
+ VALID_CIFAR100,
+ batch_size=cifar_config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(cifar100_splits.xvalid),
+ num_workers=workers,
+ pin_memory=True,
+ )
+ test__cifar100_loader = torch.utils.data.DataLoader(
+ VALID_CIFAR100,
+ batch_size=cifar_config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(cifar100_splits.xtest),
+ num_workers=workers,
+ pin_memory=True,
+ )
+ print(
+ "CIFAR-100 : train-loader has {:3d} batch".format(len(train_cifar100_loader))
+ )
+ print(
+ "CIFAR-100 : valid-loader has {:3d} batch".format(len(valid_cifar100_loader))
+ )
+ print(
+ "CIFAR-100 : test--loader has {:3d} batch".format(len(test__cifar100_loader))
+ )
+ print("-" * 200)
+
+ imagenet16_config_path = "configs/nas-benchmark/ImageNet-16.config"
+ imagenet16_config = load_config(imagenet16_config_path, None, None)
+ TRAIN_ImageNet16_120, VALID_ImageNet16_120, xshape, class_num = get_datasets(
+ "ImageNet16-120", str(torch_dir / "cifar.python" / "ImageNet16"), -1
+ )
+ print(
+ "original TRAIN_ImageNet16_120: {:} training images and {:} test images : {:} input shape : {:} number of classes".format(
+ len(TRAIN_ImageNet16_120), len(VALID_ImageNet16_120), xshape, class_num
+ )
+ )
+ imagenet_splits = load_config(
+ root_dir / "configs" / "nas-benchmark" / "imagenet-16-120-test-split.txt",
+ None,
+ None,
+ )
+ assert imagenet_splits.xvalid[:10] == [
+ 1,
+ 2,
+ 3,
+ 6,
+ 7,
+ 8,
+ 9,
+ 12,
+ 16,
+ 18,
+ ] and imagenet_splits.xtest[:10] == [
+ 0,
+ 4,
+ 5,
+ 10,
+ 11,
+ 13,
+ 14,
+ 15,
+ 17,
+ 20,
+ ]
+ train_imagenet_loader = torch.utils.data.DataLoader(
+ TRAIN_ImageNet16_120,
+ batch_size=imagenet16_config.batch_size,
+ shuffle=True,
+ num_workers=workers,
+ pin_memory=True,
+ )
+ valid_imagenet_loader = torch.utils.data.DataLoader(
+ VALID_ImageNet16_120,
+ batch_size=imagenet16_config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(imagenet_splits.xvalid),
+ num_workers=workers,
+ pin_memory=True,
+ )
+ test__imagenet_loader = torch.utils.data.DataLoader(
+ VALID_ImageNet16_120,
+ batch_size=imagenet16_config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(imagenet_splits.xtest),
+ num_workers=workers,
+ pin_memory=True,
+ )
+ print(
+ "ImageNet-16-120 : train-loader has {:3d} batch with {:} per batch".format(
+ len(train_imagenet_loader), imagenet16_config.batch_size
+ )
+ )
+ print(
+ "ImageNet-16-120 : valid-loader has {:3d} batch with {:} per batch".format(
+ len(valid_imagenet_loader), imagenet16_config.batch_size
+ )
+ )
+ print(
+ "ImageNet-16-120 : test--loader has {:3d} batch with {:} per batch".format(
+ len(test__imagenet_loader), imagenet16_config.batch_size
+ )
+ )
+
+ # 'cifar10', 'cifar100', 'ImageNet16-120'
+ loaders = {
+ "cifar10@trainval": trainval_cifar10_loader,
+ "cifar10@train": train_cifar10_loader,
+ "cifar10@valid": valid_cifar10_loader,
+ "cifar10@test": test__cifar10_loader,
+ "cifar100@train": train_cifar100_loader,
+ "cifar100@valid": valid_cifar100_loader,
+ "cifar100@test": test__cifar100_loader,
+ "ImageNet16-120@train": train_imagenet_loader,
+ "ImageNet16-120@valid": valid_imagenet_loader,
+ "ImageNet16-120@test": test__imagenet_loader,
+ }
+ return loaders
+
+
+def simplify(save_dir, meta_file, basestr, target_dir):
+ meta_infos = torch.load(meta_file, map_location="cpu")
+ meta_archs = meta_infos["archs"] # a list of architecture strings
+ meta_num_archs = meta_infos["total"]
+ meta_max_node = meta_infos["max_node"]
+ assert meta_num_archs == len(
+ meta_archs
+ ), "invalid number of archs : {:} vs {:}".format(meta_num_archs, len(meta_archs))
+
+ sub_model_dirs = sorted(list(save_dir.glob("*-*-{:}".format(basestr))))
+ print(
+ "{:} find {:} directories used to save checkpoints".format(
+ time_string(), len(sub_model_dirs)
+ )
+ )
+
+ subdir2archs, num_evaluated_arch = collections.OrderedDict(), 0
+ num_seeds = defaultdict(lambda: 0)
+ for index, sub_dir in enumerate(sub_model_dirs):
+ xcheckpoints = list(sub_dir.glob("arch-*-seed-*.pth"))
+ arch_indexes = set()
+ for checkpoint in xcheckpoints:
+ temp_names = checkpoint.name.split("-")
+ assert (
+ len(temp_names) == 4
+ and temp_names[0] == "arch"
+ and temp_names[2] == "seed"
+ ), "invalid checkpoint name : {:}".format(checkpoint.name)
+ arch_indexes.add(temp_names[1])
+ subdir2archs[sub_dir] = sorted(list(arch_indexes))
+ num_evaluated_arch += len(arch_indexes)
+ # count number of seeds for each architecture
+ for arch_index in arch_indexes:
+ num_seeds[
+ len(list(sub_dir.glob("arch-{:}-seed-*.pth".format(arch_index))))
+ ] += 1
+ print(
+ "{:} There are {:5d} architectures that have been evaluated ({:} in total).".format(
+ time_string(), num_evaluated_arch, meta_num_archs
+ )
+ )
+ for key in sorted(list(num_seeds.keys())):
+ print(
+ "{:} There are {:5d} architectures that are evaluated {:} times.".format(
+ time_string(), num_seeds[key], key
+ )
+ )
+
+ dataloader_dict = GET_DataLoaders(6)
+
+ to_save_simply = save_dir / "simplifies"
+ to_save_allarc = save_dir / "simplifies" / "architectures"
+ if not to_save_simply.exists():
+ to_save_simply.mkdir(parents=True, exist_ok=True)
+ if not to_save_allarc.exists():
+ to_save_allarc.mkdir(parents=True, exist_ok=True)
+
+ assert (save_dir / target_dir) in subdir2archs, "can not find {:}".format(
+ target_dir
+ )
+ arch2infos, datasets = {}, (
+ "cifar10-valid",
+ "cifar10",
+ "cifar100",
+ "ImageNet16-120",
+ )
+ evaluated_indexes = set()
+ target_directory = save_dir / target_dir
+ target_less_dir = save_dir / "{:}-LESS".format(target_dir)
+ arch_indexes = subdir2archs[target_directory]
+ num_seeds = defaultdict(lambda: 0)
+ end_time = time.time()
+ arch_time = AverageMeter()
+ for idx, arch_index in enumerate(arch_indexes):
+ checkpoints = list(
+ target_directory.glob("arch-{:}-seed-*.pth".format(arch_index))
+ )
+ ckps_less = list(target_less_dir.glob("arch-{:}-seed-*.pth".format(arch_index)))
+ # create the arch info for each architecture
+ try:
+ arch_info_full = account_one_arch(
+ arch_index,
+ meta_archs[int(arch_index)],
+ checkpoints,
+ datasets,
+ dataloader_dict,
+ )
+ arch_info_less = account_one_arch(
+ arch_index,
+ meta_archs[int(arch_index)],
+ ckps_less,
+ ["cifar10-valid"],
+ dataloader_dict,
+ )
+ num_seeds[len(checkpoints)] += 1
+ except:
+ print("Loading {:} failed, : {:}".format(arch_index, checkpoints))
+ continue
+ assert (
+ int(arch_index) not in evaluated_indexes
+ ), "conflict arch-index : {:}".format(arch_index)
+ assert (
+ 0 <= int(arch_index) < len(meta_archs)
+ ), "invalid arch-index {:} (not found in meta_archs)".format(arch_index)
+ arch_info = {"full": arch_info_full, "less": arch_info_less}
+ evaluated_indexes.add(int(arch_index))
+ arch2infos[int(arch_index)] = arch_info
+ torch.save(
+ {"full": arch_info_full.state_dict(), "less": arch_info_less.state_dict()},
+ to_save_allarc / "{:}-FULL.pth".format(arch_index),
+ )
+ arch_info["full"].clear_params()
+ arch_info["less"].clear_params()
+ torch.save(
+ {"full": arch_info_full.state_dict(), "less": arch_info_less.state_dict()},
+ to_save_allarc / "{:}-SIMPLE.pth".format(arch_index),
+ )
+ # measure elapsed time
+ arch_time.update(time.time() - end_time)
+ end_time = time.time()
+ need_time = "{:}".format(
+ convert_secs2time(arch_time.avg * (len(arch_indexes) - idx - 1), True)
+ )
+ print(
+ "{:} {:} [{:03d}/{:03d}] : {:} still need {:}".format(
+ time_string(), target_dir, idx, len(arch_indexes), arch_index, need_time
+ )
+ )
+ # measure time
+ xstrs = [
+ "{:}:{:03d}".format(key, num_seeds[key])
+ for key in sorted(list(num_seeds.keys()))
+ ]
+ print("{:} {:} done : {:}".format(time_string(), target_dir, xstrs))
+ final_infos = {
+ "meta_archs": meta_archs,
+ "total_archs": meta_num_archs,
+ "basestr": basestr,
+ "arch2infos": arch2infos,
+ "evaluated_indexes": evaluated_indexes,
+ }
+ save_file_name = to_save_simply / "{:}.pth".format(target_dir)
+ torch.save(final_infos, save_file_name)
+ print(
+ "Save {:} / {:} architecture results into {:}.".format(
+ len(evaluated_indexes), meta_num_archs, save_file_name
+ )
+ )
+
+
+def merge_all(save_dir, meta_file, basestr):
+ meta_infos = torch.load(meta_file, map_location="cpu")
+ meta_archs = meta_infos["archs"]
+ meta_num_archs = meta_infos["total"]
+ meta_max_node = meta_infos["max_node"]
+ assert meta_num_archs == len(
+ meta_archs
+ ), "invalid number of archs : {:} vs {:}".format(meta_num_archs, len(meta_archs))
+
+ sub_model_dirs = sorted(list(save_dir.glob("*-*-{:}".format(basestr))))
+ print(
+ "{:} find {:} directories used to save checkpoints".format(
+ time_string(), len(sub_model_dirs)
+ )
+ )
+ for index, sub_dir in enumerate(sub_model_dirs):
+ arch_info_files = sorted(list(sub_dir.glob("arch-*-seed-*.pth")))
+ print(
+ "The {:02d}/{:02d}-th directory : {:} : {:} runs.".format(
+ index, len(sub_model_dirs), sub_dir, len(arch_info_files)
+ )
+ )
+
+ arch2infos, evaluated_indexes = dict(), set()
+ for IDX, sub_dir in enumerate(sub_model_dirs):
+ ckp_path = sub_dir.parent / "simplifies" / "{:}.pth".format(sub_dir.name)
+ if ckp_path.exists():
+ sub_ckps = torch.load(ckp_path, map_location="cpu")
+ assert (
+ sub_ckps["total_archs"] == meta_num_archs
+ and sub_ckps["basestr"] == basestr
+ )
+ xarch2infos = sub_ckps["arch2infos"]
+ xevalindexs = sub_ckps["evaluated_indexes"]
+ for eval_index in xevalindexs:
+ assert (
+ eval_index not in evaluated_indexes and eval_index not in arch2infos
+ )
+ # arch2infos[eval_index] = xarch2infos[eval_index].state_dict()
+ arch2infos[eval_index] = {
+ "full": xarch2infos[eval_index]["full"].state_dict(),
+ "less": xarch2infos[eval_index]["less"].state_dict(),
+ }
+ evaluated_indexes.add(eval_index)
+ print(
+ "{:} [{:03d}/{:03d}] merge data from {:} with {:} models.".format(
+ time_string(), IDX, len(sub_model_dirs), ckp_path, len(xevalindexs)
+ )
+ )
+ else:
+ raise ValueError("Can not find {:}".format(ckp_path))
+ # print ('{:} [{:03d}/{:03d}] can not find {:}, skip.'.format(time_string(), IDX, len(subdir2archs), ckp_path))
+
+ evaluated_indexes = sorted(list(evaluated_indexes))
+ print(
+ "Finally, there are {:} architectures that have been trained and evaluated.".format(
+ len(evaluated_indexes)
+ )
+ )
+
+ to_save_simply = save_dir / "simplifies"
+ if not to_save_simply.exists():
+ to_save_simply.mkdir(parents=True, exist_ok=True)
+ final_infos = {
+ "meta_archs": meta_archs,
+ "total_archs": meta_num_archs,
+ "arch2infos": arch2infos,
+ "evaluated_indexes": evaluated_indexes,
+ }
+ save_file_name = to_save_simply / "{:}-final-infos.pth".format(basestr)
+ torch.save(final_infos, save_file_name)
+ print(
+ "Save {:} / {:} architecture results into {:}.".format(
+ len(evaluated_indexes), meta_num_archs, save_file_name
+ )
+ )
+
+
+if __name__ == "__main__":
+
+ parser = argparse.ArgumentParser(
+ description="NAS-BENCH-201",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ )
+ parser.add_argument(
+ "--mode",
+ type=str,
+ choices=["cal", "merge"],
+ help="The running mode for this script.",
+ )
+ parser.add_argument(
+ "--base_save_dir",
+ type=str,
+ default="./output/NAS-BENCH-201-4",
+ help="The base-name of folder to save checkpoints and log.",
+ )
+ parser.add_argument("--target_dir", type=str, help="The target directory.")
+ parser.add_argument(
+ "--max_node", type=int, default=4, help="The maximum node in a cell."
+ )
+ parser.add_argument(
+ "--channel", type=int, default=16, help="The number of channels."
+ )
+ parser.add_argument(
+ "--num_cells", type=int, default=5, help="The number of cells in one stage."
+ )
+ args = parser.parse_args()
+
+ save_dir = Path(args.base_save_dir)
+ meta_path = save_dir / "meta-node-{:}.pth".format(args.max_node)
+ assert save_dir.exists(), "invalid save dir path : {:}".format(save_dir)
+ assert meta_path.exists(), "invalid saved meta path : {:}".format(meta_path)
+ print(
+ "start the statistics of our nas-benchmark from {:} using {:}.".format(
+ save_dir, args.target_dir
+ )
+ )
+ basestr = "C{:}-N{:}".format(args.channel, args.num_cells)
+
+ if args.mode == "cal":
+ simplify(save_dir, meta_path, basestr, args.target_dir)
+ elif args.mode == "merge":
+ merge_all(save_dir, meta_path, basestr)
+ else:
+ raise ValueError("invalid mode : {:}".format(args.mode))
diff --git a/AutoDL-Projects/exps/NAS-Bench-201/test-correlation.py b/AutoDL-Projects/exps/NAS-Bench-201/test-correlation.py
new file mode 100644
index 0000000..ccc35a4
--- /dev/null
+++ b/AutoDL-Projects/exps/NAS-Bench-201/test-correlation.py
@@ -0,0 +1,197 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.08 #
+########################################################
+# python exps/NAS-Bench-201/test-correlation.py --api_path $HOME/.torch/NAS-Bench-201-v1_0-e61699.pth
+########################################################
+import sys, argparse
+import numpy as np
+from copy import deepcopy
+from tqdm import tqdm
+import torch
+from pathlib import Path
+
+from xautodl.log_utils import time_string
+from xautodl.models import CellStructure
+from nas_201_api import NASBench201API as API
+
+
+def check_unique_arch(meta_file):
+ api = API(str(meta_file))
+ arch_strs = deepcopy(api.meta_archs)
+ xarchs = [CellStructure.str2structure(x) for x in arch_strs]
+
+ def get_unique_matrix(archs, consider_zero):
+ UniquStrs = [arch.to_unique_str(consider_zero) for arch in archs]
+ print(
+ "{:} create unique-string ({:}/{:}) done".format(
+ time_string(), len(set(UniquStrs)), len(UniquStrs)
+ )
+ )
+ Unique2Index = dict()
+ for index, xstr in enumerate(UniquStrs):
+ if xstr not in Unique2Index:
+ Unique2Index[xstr] = list()
+ Unique2Index[xstr].append(index)
+ sm_matrix = torch.eye(len(archs)).bool()
+ for _, xlist in Unique2Index.items():
+ for i in xlist:
+ for j in xlist:
+ sm_matrix[i, j] = True
+ unique_ids, unique_num = [-1 for _ in archs], 0
+ for i in range(len(unique_ids)):
+ if unique_ids[i] > -1:
+ continue
+ neighbours = sm_matrix[i].nonzero().view(-1).tolist()
+ for nghb in neighbours:
+ assert unique_ids[nghb] == -1, "impossible"
+ unique_ids[nghb] = unique_num
+ unique_num += 1
+ return sm_matrix, unique_ids, unique_num
+
+ print(
+ "There are {:} valid-archs".format(sum(arch.check_valid() for arch in xarchs))
+ )
+ sm_matrix, uniqueIDs, unique_num = get_unique_matrix(xarchs, None)
+ print(
+ "{:} There are {:} unique architectures (considering nothing).".format(
+ time_string(), unique_num
+ )
+ )
+ sm_matrix, uniqueIDs, unique_num = get_unique_matrix(xarchs, False)
+ print(
+ "{:} There are {:} unique architectures (not considering zero).".format(
+ time_string(), unique_num
+ )
+ )
+ sm_matrix, uniqueIDs, unique_num = get_unique_matrix(xarchs, True)
+ print(
+ "{:} There are {:} unique architectures (considering zero).".format(
+ time_string(), unique_num
+ )
+ )
+
+
+def check_cor_for_bandit(
+ meta_file, test_epoch, use_less_or_not, is_rand=True, need_print=False
+):
+ if isinstance(meta_file, API):
+ api = meta_file
+ else:
+ api = API(str(meta_file))
+ cifar10_currs = []
+ cifar10_valid = []
+ cifar10_test = []
+ cifar100_valid = []
+ cifar100_test = []
+ imagenet_test = []
+ imagenet_valid = []
+ for idx, arch in enumerate(api):
+ results = api.get_more_info(
+ idx, "cifar10-valid", test_epoch - 1, use_less_or_not, is_rand
+ )
+ cifar10_currs.append(results["valid-accuracy"])
+ # --->>>>>
+ results = api.get_more_info(idx, "cifar10-valid", None, False, is_rand)
+ cifar10_valid.append(results["valid-accuracy"])
+ results = api.get_more_info(idx, "cifar10", None, False, is_rand)
+ cifar10_test.append(results["test-accuracy"])
+ results = api.get_more_info(idx, "cifar100", None, False, is_rand)
+ cifar100_test.append(results["test-accuracy"])
+ cifar100_valid.append(results["valid-accuracy"])
+ results = api.get_more_info(idx, "ImageNet16-120", None, False, is_rand)
+ imagenet_test.append(results["test-accuracy"])
+ imagenet_valid.append(results["valid-accuracy"])
+
+ def get_cor(A, B):
+ return float(np.corrcoef(A, B)[0, 1])
+
+ cors = []
+ for basestr, xlist in zip(
+ ["C-010-V", "C-010-T", "C-100-V", "C-100-T", "I16-V", "I16-T"],
+ [
+ cifar10_valid,
+ cifar10_test,
+ cifar100_valid,
+ cifar100_test,
+ imagenet_valid,
+ imagenet_test,
+ ],
+ ):
+ correlation = get_cor(cifar10_currs, xlist)
+ if need_print:
+ print(
+ "With {:3d}/{:}-epochs-training, the correlation between cifar10-valid and {:} is : {:}".format(
+ test_epoch,
+ "012" if use_less_or_not else "200",
+ basestr,
+ correlation,
+ )
+ )
+ cors.append(correlation)
+ # print ('With {:3d}/200-epochs-training, the correlation between cifar10-valid and {:} is : {:}'.format(test_epoch, basestr, get_cor(cifar10_valid_200, xlist)))
+ # print('-'*200)
+ # print('*'*230)
+ return cors
+
+
+def check_cor_for_bandit_v2(meta_file, test_epoch, use_less_or_not, is_rand):
+ corrs = []
+ for i in tqdm(range(100)):
+ x = check_cor_for_bandit(meta_file, test_epoch, use_less_or_not, is_rand, False)
+ corrs.append(x)
+ # xstrs = ['CIFAR-010', 'C-100-V', 'C-100-T', 'I16-V', 'I16-T']
+ xstrs = ["C-010-V", "C-010-T", "C-100-V", "C-100-T", "I16-V", "I16-T"]
+ correlations = np.array(corrs)
+ print(
+ "------>>>>>>>> {:03d}/{:} >>>>>>>> ------".format(
+ test_epoch, "012" if use_less_or_not else "200"
+ )
+ )
+ for idx, xstr in enumerate(xstrs):
+ print(
+ "{:8s} ::: mean={:.4f}, std={:.4f} :: {:.4f}\\pm{:.4f}".format(
+ xstr,
+ correlations[:, idx].mean(),
+ correlations[:, idx].std(),
+ correlations[:, idx].mean(),
+ correlations[:, idx].std(),
+ )
+ )
+ print("")
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser("Analysis of NAS-Bench-201")
+ parser.add_argument(
+ "--save_dir",
+ type=str,
+ default="./output/search-cell-nas-bench-201/visuals",
+ help="The base-name of folder to save checkpoints and log.",
+ )
+ parser.add_argument(
+ "--api_path",
+ type=str,
+ default=None,
+ help="The path to the NAS-Bench-201 benchmark file.",
+ )
+ args = parser.parse_args()
+
+ vis_save_dir = Path(args.save_dir)
+ vis_save_dir.mkdir(parents=True, exist_ok=True)
+ meta_file = Path(args.api_path)
+ assert meta_file.exists(), "invalid path for api : {:}".format(meta_file)
+
+ # check_unique_arch(meta_file)
+ api = API(str(meta_file))
+ # for iepoch in [11, 25, 50, 100, 150, 175, 200]:
+ # check_cor_for_bandit(api, 6, iepoch)
+ # check_cor_for_bandit(api, 12, iepoch)
+ check_cor_for_bandit_v2(api, 6, True, True)
+ check_cor_for_bandit_v2(api, 12, True, True)
+ check_cor_for_bandit_v2(api, 12, False, True)
+ check_cor_for_bandit_v2(api, 24, False, True)
+ check_cor_for_bandit_v2(api, 100, False, True)
+ check_cor_for_bandit_v2(api, 150, False, True)
+ check_cor_for_bandit_v2(api, 175, False, True)
+ check_cor_for_bandit_v2(api, 200, False, True)
+ print("----")
diff --git a/AutoDL-Projects/exps/NAS-Bench-201/visualize.py b/AutoDL-Projects/exps/NAS-Bench-201/visualize.py
new file mode 100644
index 0000000..9571251
--- /dev/null
+++ b/AutoDL-Projects/exps/NAS-Bench-201/visualize.py
@@ -0,0 +1,1259 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.08 #
+#####################################################
+# python exps/NAS-Bench-201/visualize.py --api_path $HOME/.torch/NAS-Bench-201-v1_0-e61699.pth
+#####################################################
+import sys, argparse
+from tqdm import tqdm
+from collections import OrderedDict
+import numpy as np
+import torch
+from pathlib import Path
+from collections import defaultdict
+import matplotlib
+import seaborn as sns
+from mpl_toolkits.mplot3d import Axes3D
+
+matplotlib.use("agg")
+import matplotlib.pyplot as plt
+
+from xautodl.log_utils import time_string
+from nas_201_api import NASBench201API as API
+
+
+def calculate_correlation(*vectors):
+ matrix = []
+ for i, vectori in enumerate(vectors):
+ x = []
+ for j, vectorj in enumerate(vectors):
+ x.append(np.corrcoef(vectori, vectorj)[0, 1])
+ matrix.append(x)
+ return np.array(matrix)
+
+
+def visualize_relative_ranking(vis_save_dir):
+ print("\n" + "-" * 100)
+ cifar010_cache_path = vis_save_dir / "{:}-cache-info.pth".format("cifar10")
+ cifar100_cache_path = vis_save_dir / "{:}-cache-info.pth".format("cifar100")
+ imagenet_cache_path = vis_save_dir / "{:}-cache-info.pth".format("ImageNet16-120")
+ cifar010_info = torch.load(cifar010_cache_path)
+ cifar100_info = torch.load(cifar100_cache_path)
+ imagenet_info = torch.load(imagenet_cache_path)
+ indexes = list(range(len(cifar010_info["params"])))
+
+ print("{:} start to visualize relative ranking".format(time_string()))
+ # maximum accuracy with ResNet-level params 11472
+ x_010_accs = [
+ cifar010_info["test_accs"][i]
+ if cifar010_info["params"][i] <= cifar010_info["params"][11472]
+ else -1
+ for i in indexes
+ ]
+ x_100_accs = [
+ cifar100_info["test_accs"][i]
+ if cifar100_info["params"][i] <= cifar100_info["params"][11472]
+ else -1
+ for i in indexes
+ ]
+ x_img_accs = [
+ imagenet_info["test_accs"][i]
+ if imagenet_info["params"][i] <= imagenet_info["params"][11472]
+ else -1
+ for i in indexes
+ ]
+
+ cifar010_ord_indexes = sorted(indexes, key=lambda i: cifar010_info["test_accs"][i])
+ cifar100_ord_indexes = sorted(indexes, key=lambda i: cifar100_info["test_accs"][i])
+ imagenet_ord_indexes = sorted(indexes, key=lambda i: imagenet_info["test_accs"][i])
+
+ cifar100_labels, imagenet_labels = [], []
+ for idx in cifar010_ord_indexes:
+ cifar100_labels.append(cifar100_ord_indexes.index(idx))
+ imagenet_labels.append(imagenet_ord_indexes.index(idx))
+ print("{:} prepare data done.".format(time_string()))
+
+ dpi, width, height = 300, 2600, 2600
+ figsize = width / float(dpi), height / float(dpi)
+ LabelSize, LegendFontsize = 18, 18
+ resnet_scale, resnet_alpha = 120, 0.5
+
+ fig = plt.figure(figsize=figsize)
+ ax = fig.add_subplot(111)
+ plt.xlim(min(indexes), max(indexes))
+ plt.ylim(min(indexes), max(indexes))
+ # plt.ylabel('y').set_rotation(0)
+ plt.yticks(
+ np.arange(min(indexes), max(indexes), max(indexes) // 6),
+ fontsize=LegendFontsize,
+ rotation="vertical",
+ )
+ plt.xticks(
+ np.arange(min(indexes), max(indexes), max(indexes) // 6),
+ fontsize=LegendFontsize,
+ )
+ # ax.scatter(indexes, cifar100_labels, marker='^', s=0.5, c='tab:green', alpha=0.8, label='CIFAR-100')
+ # ax.scatter(indexes, imagenet_labels, marker='*', s=0.5, c='tab:red' , alpha=0.8, label='ImageNet-16-120')
+ # ax.scatter(indexes, indexes , marker='o', s=0.5, c='tab:blue' , alpha=0.8, label='CIFAR-10')
+ ax.scatter(indexes, cifar100_labels, marker="^", s=0.5, c="tab:green", alpha=0.8)
+ ax.scatter(indexes, imagenet_labels, marker="*", s=0.5, c="tab:red", alpha=0.8)
+ ax.scatter(indexes, indexes, marker="o", s=0.5, c="tab:blue", alpha=0.8)
+ ax.scatter([-1], [-1], marker="o", s=100, c="tab:blue", label="CIFAR-10")
+ ax.scatter([-1], [-1], marker="^", s=100, c="tab:green", label="CIFAR-100")
+ ax.scatter([-1], [-1], marker="*", s=100, c="tab:red", label="ImageNet-16-120")
+ plt.grid(zorder=0)
+ ax.set_axisbelow(True)
+ plt.legend(loc=0, fontsize=LegendFontsize)
+ ax.set_xlabel("architecture ranking in CIFAR-10", fontsize=LabelSize)
+ ax.set_ylabel("architecture ranking", fontsize=LabelSize)
+ save_path = (vis_save_dir / "relative-rank.pdf").resolve()
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="pdf")
+ save_path = (vis_save_dir / "relative-rank.png").resolve()
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="png")
+ print("{:} save into {:}".format(time_string(), save_path))
+
+ # calculate correlation
+ sns_size = 15
+ CoRelMatrix = calculate_correlation(
+ cifar010_info["valid_accs"],
+ cifar010_info["test_accs"],
+ cifar100_info["valid_accs"],
+ cifar100_info["test_accs"],
+ imagenet_info["valid_accs"],
+ imagenet_info["test_accs"],
+ )
+ fig = plt.figure(figsize=figsize)
+ plt.axis("off")
+ h = sns.heatmap(
+ CoRelMatrix, annot=True, annot_kws={"size": sns_size}, fmt=".3f", linewidths=0.5
+ )
+ save_path = (vis_save_dir / "co-relation-all.pdf").resolve()
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="pdf")
+ print("{:} save into {:}".format(time_string(), save_path))
+
+ # calculate correlation
+ acc_bars = [92, 93]
+ for acc_bar in acc_bars:
+ selected_indexes = []
+ for i, acc in enumerate(cifar010_info["test_accs"]):
+ if acc > acc_bar:
+ selected_indexes.append(i)
+ print("select {:} architectures".format(len(selected_indexes)))
+ cifar010_valid_accs = np.array(cifar010_info["valid_accs"])[selected_indexes]
+ cifar010_test_accs = np.array(cifar010_info["test_accs"])[selected_indexes]
+ cifar100_valid_accs = np.array(cifar100_info["valid_accs"])[selected_indexes]
+ cifar100_test_accs = np.array(cifar100_info["test_accs"])[selected_indexes]
+ imagenet_valid_accs = np.array(imagenet_info["valid_accs"])[selected_indexes]
+ imagenet_test_accs = np.array(imagenet_info["test_accs"])[selected_indexes]
+ CoRelMatrix = calculate_correlation(
+ cifar010_valid_accs,
+ cifar010_test_accs,
+ cifar100_valid_accs,
+ cifar100_test_accs,
+ imagenet_valid_accs,
+ imagenet_test_accs,
+ )
+ fig = plt.figure(figsize=figsize)
+ plt.axis("off")
+ h = sns.heatmap(
+ CoRelMatrix,
+ annot=True,
+ annot_kws={"size": sns_size},
+ fmt=".3f",
+ linewidths=0.5,
+ )
+ save_path = (
+ vis_save_dir / "co-relation-top-{:}.pdf".format(len(selected_indexes))
+ ).resolve()
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="pdf")
+ print("{:} save into {:}".format(time_string(), save_path))
+ plt.close("all")
+
+
+def visualize_info(meta_file, dataset, vis_save_dir):
+ print("{:} start to visualize {:} information".format(time_string(), dataset))
+ cache_file_path = vis_save_dir / "{:}-cache-info.pth".format(dataset)
+ if not cache_file_path.exists():
+ print("Do not find cache file : {:}".format(cache_file_path))
+ nas_bench = API(str(meta_file))
+ params, flops, train_accs, valid_accs, test_accs, otest_accs = (
+ [],
+ [],
+ [],
+ [],
+ [],
+ [],
+ )
+ for index in range(len(nas_bench)):
+ info = nas_bench.query_by_index(index, use_12epochs_result=False)
+ resx = info.get_comput_costs(dataset)
+ flop, param = resx["flops"], resx["params"]
+ if dataset == "cifar10":
+ res = info.get_metrics("cifar10", "train")
+ train_acc = res["accuracy"]
+ res = info.get_metrics("cifar10-valid", "x-valid")
+ valid_acc = res["accuracy"]
+ res = info.get_metrics("cifar10", "ori-test")
+ test_acc = res["accuracy"]
+ res = info.get_metrics("cifar10", "ori-test")
+ otest_acc = res["accuracy"]
+ else:
+ res = info.get_metrics(dataset, "train")
+ train_acc = res["accuracy"]
+ res = info.get_metrics(dataset, "x-valid")
+ valid_acc = res["accuracy"]
+ res = info.get_metrics(dataset, "x-test")
+ test_acc = res["accuracy"]
+ res = info.get_metrics(dataset, "ori-test")
+ otest_acc = res["accuracy"]
+ if index == 11472: # resnet
+ resnet = {
+ "params": param,
+ "flops": flop,
+ "index": 11472,
+ "train_acc": train_acc,
+ "valid_acc": valid_acc,
+ "test_acc": test_acc,
+ "otest_acc": otest_acc,
+ }
+ flops.append(flop)
+ params.append(param)
+ train_accs.append(train_acc)
+ valid_accs.append(valid_acc)
+ test_accs.append(test_acc)
+ otest_accs.append(otest_acc)
+ # resnet = {'params': 0.559, 'flops': 78.56, 'index': 11472, 'train_acc': 99.99, 'valid_acc': 90.84, 'test_acc': 93.97}
+ info = {
+ "params": params,
+ "flops": flops,
+ "train_accs": train_accs,
+ "valid_accs": valid_accs,
+ "test_accs": test_accs,
+ "otest_accs": otest_accs,
+ }
+ info["resnet"] = resnet
+ torch.save(info, cache_file_path)
+ else:
+ print("Find cache file : {:}".format(cache_file_path))
+ info = torch.load(cache_file_path)
+ params, flops, train_accs, valid_accs, test_accs, otest_accs = (
+ info["params"],
+ info["flops"],
+ info["train_accs"],
+ info["valid_accs"],
+ info["test_accs"],
+ info["otest_accs"],
+ )
+ resnet = info["resnet"]
+ print("{:} collect data done.".format(time_string()))
+
+ indexes = list(range(len(params)))
+ dpi, width, height = 300, 2600, 2600
+ figsize = width / float(dpi), height / float(dpi)
+ LabelSize, LegendFontsize = 22, 22
+ resnet_scale, resnet_alpha = 120, 0.5
+
+ fig = plt.figure(figsize=figsize)
+ ax = fig.add_subplot(111)
+ plt.xticks(np.arange(0, 1.6, 0.3), fontsize=LegendFontsize)
+ if dataset == "cifar10":
+ plt.ylim(50, 100)
+ plt.yticks(np.arange(50, 101, 10), fontsize=LegendFontsize)
+ elif dataset == "cifar100":
+ plt.ylim(25, 75)
+ plt.yticks(np.arange(25, 76, 10), fontsize=LegendFontsize)
+ else:
+ plt.ylim(0, 50)
+ plt.yticks(np.arange(0, 51, 10), fontsize=LegendFontsize)
+ ax.scatter(params, valid_accs, marker="o", s=0.5, c="tab:blue")
+ ax.scatter(
+ [resnet["params"]],
+ [resnet["valid_acc"]],
+ marker="*",
+ s=resnet_scale,
+ c="tab:orange",
+ label="resnet",
+ alpha=0.4,
+ )
+ plt.grid(zorder=0)
+ ax.set_axisbelow(True)
+ plt.legend(loc=4, fontsize=LegendFontsize)
+ ax.set_xlabel("#parameters (MB)", fontsize=LabelSize)
+ ax.set_ylabel("the validation accuracy (%)", fontsize=LabelSize)
+ save_path = (vis_save_dir / "{:}-param-vs-valid.pdf".format(dataset)).resolve()
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="pdf")
+ save_path = (vis_save_dir / "{:}-param-vs-valid.png".format(dataset)).resolve()
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="png")
+ print("{:} save into {:}".format(time_string(), save_path))
+
+ fig = plt.figure(figsize=figsize)
+ ax = fig.add_subplot(111)
+ plt.xticks(np.arange(0, 1.6, 0.3), fontsize=LegendFontsize)
+ if dataset == "cifar10":
+ plt.ylim(50, 100)
+ plt.yticks(np.arange(50, 101, 10), fontsize=LegendFontsize)
+ elif dataset == "cifar100":
+ plt.ylim(25, 75)
+ plt.yticks(np.arange(25, 76, 10), fontsize=LegendFontsize)
+ else:
+ plt.ylim(0, 50)
+ plt.yticks(np.arange(0, 51, 10), fontsize=LegendFontsize)
+ ax.scatter(params, test_accs, marker="o", s=0.5, c="tab:blue")
+ ax.scatter(
+ [resnet["params"]],
+ [resnet["test_acc"]],
+ marker="*",
+ s=resnet_scale,
+ c="tab:orange",
+ label="resnet",
+ alpha=resnet_alpha,
+ )
+ plt.grid()
+ ax.set_axisbelow(True)
+ plt.legend(loc=4, fontsize=LegendFontsize)
+ ax.set_xlabel("#parameters (MB)", fontsize=LabelSize)
+ ax.set_ylabel("the test accuracy (%)", fontsize=LabelSize)
+ save_path = (vis_save_dir / "{:}-param-vs-test.pdf".format(dataset)).resolve()
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="pdf")
+ save_path = (vis_save_dir / "{:}-param-vs-test.png".format(dataset)).resolve()
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="png")
+ print("{:} save into {:}".format(time_string(), save_path))
+
+ fig = plt.figure(figsize=figsize)
+ ax = fig.add_subplot(111)
+ plt.xticks(np.arange(0, 1.6, 0.3), fontsize=LegendFontsize)
+ if dataset == "cifar10":
+ plt.ylim(50, 100)
+ plt.yticks(np.arange(50, 101, 10), fontsize=LegendFontsize)
+ elif dataset == "cifar100":
+ plt.ylim(20, 100)
+ plt.yticks(np.arange(20, 101, 10), fontsize=LegendFontsize)
+ else:
+ plt.ylim(25, 76)
+ plt.yticks(np.arange(25, 76, 10), fontsize=LegendFontsize)
+ ax.scatter(params, train_accs, marker="o", s=0.5, c="tab:blue")
+ ax.scatter(
+ [resnet["params"]],
+ [resnet["train_acc"]],
+ marker="*",
+ s=resnet_scale,
+ c="tab:orange",
+ label="resnet",
+ alpha=resnet_alpha,
+ )
+ plt.grid()
+ ax.set_axisbelow(True)
+ plt.legend(loc=4, fontsize=LegendFontsize)
+ ax.set_xlabel("#parameters (MB)", fontsize=LabelSize)
+ ax.set_ylabel("the trarining accuracy (%)", fontsize=LabelSize)
+ save_path = (vis_save_dir / "{:}-param-vs-train.pdf".format(dataset)).resolve()
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="pdf")
+ save_path = (vis_save_dir / "{:}-param-vs-train.png".format(dataset)).resolve()
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="png")
+ print("{:} save into {:}".format(time_string(), save_path))
+
+ fig = plt.figure(figsize=figsize)
+ ax = fig.add_subplot(111)
+ plt.xlim(0, max(indexes))
+ plt.xticks(
+ np.arange(min(indexes), max(indexes), max(indexes) // 5),
+ fontsize=LegendFontsize,
+ )
+ if dataset == "cifar10":
+ plt.ylim(50, 100)
+ plt.yticks(np.arange(50, 101, 10), fontsize=LegendFontsize)
+ elif dataset == "cifar100":
+ plt.ylim(25, 75)
+ plt.yticks(np.arange(25, 76, 10), fontsize=LegendFontsize)
+ else:
+ plt.ylim(0, 50)
+ plt.yticks(np.arange(0, 51, 10), fontsize=LegendFontsize)
+ ax.scatter(indexes, test_accs, marker="o", s=0.5, c="tab:blue")
+ ax.scatter(
+ [resnet["index"]],
+ [resnet["test_acc"]],
+ marker="*",
+ s=resnet_scale,
+ c="tab:orange",
+ label="resnet",
+ alpha=resnet_alpha,
+ )
+ plt.grid()
+ ax.set_axisbelow(True)
+ plt.legend(loc=4, fontsize=LegendFontsize)
+ ax.set_xlabel("architecture ID", fontsize=LabelSize)
+ ax.set_ylabel("the test accuracy (%)", fontsize=LabelSize)
+ save_path = (vis_save_dir / "{:}-test-over-ID.pdf".format(dataset)).resolve()
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="pdf")
+ save_path = (vis_save_dir / "{:}-test-over-ID.png".format(dataset)).resolve()
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="png")
+ print("{:} save into {:}".format(time_string(), save_path))
+ plt.close("all")
+
+
+def visualize_rank_over_time(meta_file, vis_save_dir):
+ print("\n" + "-" * 150)
+ vis_save_dir.mkdir(parents=True, exist_ok=True)
+ print(
+ "{:} start to visualize rank-over-time into {:}".format(
+ time_string(), vis_save_dir
+ )
+ )
+ cache_file_path = vis_save_dir / "rank-over-time-cache-info.pth"
+ if not cache_file_path.exists():
+ print("Do not find cache file : {:}".format(cache_file_path))
+ nas_bench = API(str(meta_file))
+ print("{:} load nas_bench done".format(time_string()))
+ params, flops, train_accs, valid_accs, test_accs, otest_accs = (
+ [],
+ [],
+ defaultdict(list),
+ defaultdict(list),
+ defaultdict(list),
+ defaultdict(list),
+ )
+ # for iepoch in range(200): for index in range( len(nas_bench) ):
+ for index in tqdm(range(len(nas_bench))):
+ info = nas_bench.query_by_index(index, use_12epochs_result=False)
+ for iepoch in range(200):
+ res = info.get_metrics("cifar10", "train", iepoch)
+ train_acc = res["accuracy"]
+ res = info.get_metrics("cifar10-valid", "x-valid", iepoch)
+ valid_acc = res["accuracy"]
+ res = info.get_metrics("cifar10", "ori-test", iepoch)
+ test_acc = res["accuracy"]
+ res = info.get_metrics("cifar10", "ori-test", iepoch)
+ otest_acc = res["accuracy"]
+ train_accs[iepoch].append(train_acc)
+ valid_accs[iepoch].append(valid_acc)
+ test_accs[iepoch].append(test_acc)
+ otest_accs[iepoch].append(otest_acc)
+ if iepoch == 0:
+ res = info.get_comput_costs("cifar10")
+ flop, param = res["flops"], res["params"]
+ flops.append(flop)
+ params.append(param)
+ info = {
+ "params": params,
+ "flops": flops,
+ "train_accs": train_accs,
+ "valid_accs": valid_accs,
+ "test_accs": test_accs,
+ "otest_accs": otest_accs,
+ }
+ torch.save(info, cache_file_path)
+ else:
+ print("Find cache file : {:}".format(cache_file_path))
+ info = torch.load(cache_file_path)
+ params, flops, train_accs, valid_accs, test_accs, otest_accs = (
+ info["params"],
+ info["flops"],
+ info["train_accs"],
+ info["valid_accs"],
+ info["test_accs"],
+ info["otest_accs"],
+ )
+ print("{:} collect data done.".format(time_string()))
+ # selected_epochs = [0, 100, 150, 180, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199]
+ selected_epochs = list(range(200))
+ x_xtests = test_accs[199]
+ indexes = list(range(len(x_xtests)))
+ ord_idxs = sorted(indexes, key=lambda i: x_xtests[i])
+ for sepoch in selected_epochs:
+ x_valids = valid_accs[sepoch]
+ valid_ord_idxs = sorted(indexes, key=lambda i: x_valids[i])
+ valid_ord_lbls = []
+ for idx in ord_idxs:
+ valid_ord_lbls.append(valid_ord_idxs.index(idx))
+ # labeled data
+ dpi, width, height = 300, 2600, 2600
+ figsize = width / float(dpi), height / float(dpi)
+ LabelSize, LegendFontsize = 18, 18
+
+ fig = plt.figure(figsize=figsize)
+ ax = fig.add_subplot(111)
+ plt.xlim(min(indexes), max(indexes))
+ plt.ylim(min(indexes), max(indexes))
+ plt.yticks(
+ np.arange(min(indexes), max(indexes), max(indexes) // 6),
+ fontsize=LegendFontsize,
+ rotation="vertical",
+ )
+ plt.xticks(
+ np.arange(min(indexes), max(indexes), max(indexes) // 6),
+ fontsize=LegendFontsize,
+ )
+ ax.scatter(indexes, valid_ord_lbls, marker="^", s=0.5, c="tab:green", alpha=0.8)
+ ax.scatter(indexes, indexes, marker="o", s=0.5, c="tab:blue", alpha=0.8)
+ ax.scatter(
+ [-1], [-1], marker="^", s=100, c="tab:green", label="CIFAR-10 validation"
+ )
+ ax.scatter([-1], [-1], marker="o", s=100, c="tab:blue", label="CIFAR-10 test")
+ plt.grid(zorder=0)
+ ax.set_axisbelow(True)
+ plt.legend(loc="upper left", fontsize=LegendFontsize)
+ ax.set_xlabel(
+ "architecture ranking in the final test accuracy", fontsize=LabelSize
+ )
+ ax.set_ylabel("architecture ranking in the validation set", fontsize=LabelSize)
+ save_path = (vis_save_dir / "time-{:03d}.pdf".format(sepoch)).resolve()
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="pdf")
+ save_path = (vis_save_dir / "time-{:03d}.png".format(sepoch)).resolve()
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="png")
+ print("{:} save into {:}".format(time_string(), save_path))
+ plt.close("all")
+
+
+def write_video(save_dir):
+ import cv2
+
+ video_save_path = save_dir / "time.avi"
+ print("{:} start create video for {:}".format(time_string(), video_save_path))
+ images = sorted(list(save_dir.glob("time-*.png")))
+ ximage = cv2.imread(str(images[0]))
+ # shape = (ximage.shape[1], ximage.shape[0])
+ shape = (1000, 1000)
+ # writer = cv2.VideoWriter(str(video_save_path), cv2.VideoWriter_fourcc(*"MJPG"), 25, shape)
+ writer = cv2.VideoWriter(
+ str(video_save_path), cv2.VideoWriter_fourcc(*"MJPG"), 5, shape
+ )
+ for idx, image in enumerate(images):
+ ximage = cv2.imread(str(image))
+ _image = cv2.resize(ximage, shape)
+ writer.write(_image)
+ writer.release()
+ print("write video [{:} frames] into {:}".format(len(images), video_save_path))
+
+
+def plot_results_nas_v2(api, dataset_xset_a, dataset_xset_b, root, file_name, y_lims):
+ # print ('root-path={:}, dataset={:}, xset={:}'.format(root, dataset, xset))
+ print("root-path : {:} and {:}".format(dataset_xset_a, dataset_xset_b))
+ checkpoints = [
+ "./output/search-cell-nas-bench-201/R-EA-cifar10/results.pth",
+ "./output/search-cell-nas-bench-201/REINFORCE-cifar10/results.pth",
+ "./output/search-cell-nas-bench-201/RAND-cifar10/results.pth",
+ "./output/search-cell-nas-bench-201/BOHB-cifar10/results.pth",
+ ]
+ legends, indexes = ["REA", "REINFORCE", "RANDOM", "BOHB"], None
+ All_Accs_A, All_Accs_B = OrderedDict(), OrderedDict()
+ for legend, checkpoint in zip(legends, checkpoints):
+ all_indexes = torch.load(checkpoint, map_location="cpu")
+ accuracies_A, accuracies_B = [], []
+ accuracies = []
+ for x in all_indexes:
+ info = api.arch2infos_full[x]
+ metrics = info.get_metrics(
+ dataset_xset_a[0], dataset_xset_a[1], None, False
+ )
+ accuracies_A.append(metrics["accuracy"])
+ metrics = info.get_metrics(
+ dataset_xset_b[0], dataset_xset_b[1], None, False
+ )
+ accuracies_B.append(metrics["accuracy"])
+ accuracies.append((accuracies_A[-1], accuracies_B[-1]))
+ if indexes is None:
+ indexes = list(range(len(all_indexes)))
+ accuracies = sorted(accuracies)
+ All_Accs_A[legend] = [x[0] for x in accuracies]
+ All_Accs_B[legend] = [x[1] for x in accuracies]
+
+ color_set = ["r", "b", "g", "c", "m", "y", "k"]
+ dpi, width, height = 300, 3400, 2600
+ LabelSize, LegendFontsize = 28, 28
+ figsize = width / float(dpi), height / float(dpi)
+ fig = plt.figure(figsize=figsize)
+ x_axis = np.arange(0, 600)
+ plt.xlim(0, max(indexes))
+ plt.ylim(y_lims[0], y_lims[1])
+ interval_x, interval_y = 100, y_lims[2]
+ plt.xticks(np.arange(0, max(indexes), interval_x), fontsize=LegendFontsize)
+ plt.yticks(np.arange(y_lims[0], y_lims[1], interval_y), fontsize=LegendFontsize)
+ plt.grid()
+ plt.xlabel("The index of runs", fontsize=LabelSize)
+ plt.ylabel("The accuracy (%)", fontsize=LabelSize)
+
+ for idx, legend in enumerate(legends):
+ plt.plot(
+ indexes,
+ All_Accs_B[legend],
+ color=color_set[idx],
+ linestyle="--",
+ label="{:}".format(legend),
+ lw=1,
+ alpha=0.5,
+ )
+ plt.plot(indexes, All_Accs_A[legend], color=color_set[idx], linestyle="-", lw=1)
+ for All_Accs in [All_Accs_A, All_Accs_B]:
+ print(
+ "{:} : mean = {:}, std = {:} :: {:.2f}$\\pm${:.2f}".format(
+ legend,
+ np.mean(All_Accs[legend]),
+ np.std(All_Accs[legend]),
+ np.mean(All_Accs[legend]),
+ np.std(All_Accs[legend]),
+ )
+ )
+ plt.legend(loc=4, fontsize=LegendFontsize)
+ save_path = root / "{:}".format(file_name)
+ print("save figure into {:}\n".format(save_path))
+ fig.savefig(str(save_path), dpi=dpi, bbox_inches="tight", format="pdf")
+
+
+def plot_results_nas(api, dataset, xset, root, file_name, y_lims):
+ print("root-path={:}, dataset={:}, xset={:}".format(root, dataset, xset))
+ checkpoints = [
+ "./output/search-cell-nas-bench-201/R-EA-cifar10/results.pth",
+ "./output/search-cell-nas-bench-201/REINFORCE-cifar10/results.pth",
+ "./output/search-cell-nas-bench-201/RAND-cifar10/results.pth",
+ "./output/search-cell-nas-bench-201/BOHB-cifar10/results.pth",
+ ]
+ legends, indexes = ["REA", "REINFORCE", "RANDOM", "BOHB"], None
+ All_Accs = OrderedDict()
+ for legend, checkpoint in zip(legends, checkpoints):
+ all_indexes = torch.load(checkpoint, map_location="cpu")
+ accuracies = []
+ for x in all_indexes:
+ info = api.arch2infos_full[x]
+ metrics = info.get_metrics(dataset, xset, None, False)
+ accuracies.append(metrics["accuracy"])
+ if indexes is None:
+ indexes = list(range(len(all_indexes)))
+ All_Accs[legend] = sorted(accuracies)
+
+ color_set = ["r", "b", "g", "c", "m", "y", "k"]
+ dpi, width, height = 300, 3400, 2600
+ LabelSize, LegendFontsize = 28, 28
+ figsize = width / float(dpi), height / float(dpi)
+ fig = plt.figure(figsize=figsize)
+ x_axis = np.arange(0, 600)
+ plt.xlim(0, max(indexes))
+ plt.ylim(y_lims[0], y_lims[1])
+ interval_x, interval_y = 100, y_lims[2]
+ plt.xticks(np.arange(0, max(indexes), interval_x), fontsize=LegendFontsize)
+ plt.yticks(np.arange(y_lims[0], y_lims[1], interval_y), fontsize=LegendFontsize)
+ plt.grid()
+ plt.xlabel("The index of runs", fontsize=LabelSize)
+ plt.ylabel("The accuracy (%)", fontsize=LabelSize)
+
+ for idx, legend in enumerate(legends):
+ plt.plot(
+ indexes,
+ All_Accs[legend],
+ color=color_set[idx],
+ linestyle="-",
+ label="{:}".format(legend),
+ lw=2,
+ )
+ print(
+ "{:} : mean = {:}, std = {:} :: {:.2f}$\\pm${:.2f}".format(
+ legend,
+ np.mean(All_Accs[legend]),
+ np.std(All_Accs[legend]),
+ np.mean(All_Accs[legend]),
+ np.std(All_Accs[legend]),
+ )
+ )
+ plt.legend(loc=4, fontsize=LegendFontsize)
+ save_path = root / "{:}-{:}-{:}".format(dataset, xset, file_name)
+ print("save figure into {:}\n".format(save_path))
+ fig.savefig(str(save_path), dpi=dpi, bbox_inches="tight", format="pdf")
+
+
+def just_show(api):
+ xtimes = {
+ "RSPS": [8082.5, 7794.2, 8144.7],
+ "DARTS-V1": [11582.1, 11347.0, 11948.2],
+ "DARTS-V2": [35694.7, 36132.7, 35518.0],
+ "GDAS": [31334.1, 31478.6, 32016.7],
+ "SETN": [33528.8, 33831.5, 35058.3],
+ "ENAS": [14340.2, 13817.3, 14018.9],
+ }
+ for xkey, xlist in xtimes.items():
+ xlist = np.array(xlist)
+ print("{:4s} : mean-time={:.2f} s".format(xkey, xlist.mean()))
+
+ xpaths = {
+ "RSPS": "output/search-cell-nas-bench-201/RANDOM-NAS-cifar10/checkpoint/",
+ "DARTS-V1": "output/search-cell-nas-bench-201/DARTS-V1-cifar10/checkpoint/",
+ "DARTS-V2": "output/search-cell-nas-bench-201/DARTS-V2-cifar10/checkpoint/",
+ "GDAS": "output/search-cell-nas-bench-201/GDAS-cifar10/checkpoint/",
+ "SETN": "output/search-cell-nas-bench-201/SETN-cifar10/checkpoint/",
+ "ENAS": "output/search-cell-nas-bench-201/ENAS-cifar10/checkpoint/",
+ }
+ xseeds = {
+ "RSPS": [5349, 59613, 5983],
+ "DARTS-V1": [11416, 72873, 81184],
+ "DARTS-V2": [43330, 79405, 79423],
+ "GDAS": [19677, 884, 95950],
+ "SETN": [20518, 61817, 89144],
+ "ENAS": [3231, 34238, 96929],
+ }
+
+ def get_accs(xdata, index=-1):
+ if index == -1:
+ epochs = xdata["epoch"]
+ genotype = xdata["genotypes"][epochs - 1]
+ index = api.query_index_by_arch(genotype)
+ pairs = [
+ ("cifar10-valid", "x-valid"),
+ ("cifar10", "ori-test"),
+ ("cifar100", "x-valid"),
+ ("cifar100", "x-test"),
+ ("ImageNet16-120", "x-valid"),
+ ("ImageNet16-120", "x-test"),
+ ]
+ xresults = []
+ for dataset, xset in pairs:
+ metrics = api.arch2infos_full[index].get_metrics(dataset, xset, None, False)
+ xresults.append(metrics["accuracy"])
+ return xresults
+
+ for xkey in xpaths.keys():
+ all_paths = [
+ "{:}/seed-{:}-basic.pth".format(xpaths[xkey], seed) for seed in xseeds[xkey]
+ ]
+ all_datas = [torch.load(xpath) for xpath in all_paths]
+ accyss = [get_accs(xdatas) for xdatas in all_datas]
+ accyss = np.array(accyss)
+ print("\nxkey = {:}".format(xkey))
+ for i in range(accyss.shape[1]):
+ print(
+ "---->>>> {:.2f}$\\pm${:.2f}".format(
+ accyss[:, i].mean(), accyss[:, i].std()
+ )
+ )
+
+ print("\n{:}".format(get_accs(None, 11472))) # resnet
+ pairs = [
+ ("cifar10-valid", "x-valid"),
+ ("cifar10", "ori-test"),
+ ("cifar100", "x-valid"),
+ ("cifar100", "x-test"),
+ ("ImageNet16-120", "x-valid"),
+ ("ImageNet16-120", "x-test"),
+ ]
+ for dataset, metric_on_set in pairs:
+ arch_index, highest_acc = api.find_best(dataset, metric_on_set)
+ print(
+ "[{:10s}-{:10s} ::: index={:5d}, accuracy={:.2f}".format(
+ dataset, metric_on_set, arch_index, highest_acc
+ )
+ )
+
+
+def show_nas_sharing_w(
+ api, dataset, subset, vis_save_dir, sufix, file_name, y_lims, x_maxs
+):
+ color_set = ["r", "b", "g", "c", "m", "y", "k"]
+ dpi, width, height = 300, 3400, 2600
+ LabelSize, LegendFontsize = 28, 28
+ figsize = width / float(dpi), height / float(dpi)
+ fig = plt.figure(figsize=figsize)
+ # x_maxs = 250
+ plt.xlim(0, x_maxs + 1)
+ plt.ylim(y_lims[0], y_lims[1])
+ interval_x, interval_y = x_maxs // 5, y_lims[2]
+ plt.xticks(np.arange(0, x_maxs + 1, interval_x), fontsize=LegendFontsize)
+ plt.yticks(np.arange(y_lims[0], y_lims[1], interval_y), fontsize=LegendFontsize)
+ plt.grid()
+ plt.xlabel("The searching epoch", fontsize=LabelSize)
+ plt.ylabel("The accuracy (%)", fontsize=LabelSize)
+
+ xpaths = {
+ "RSPS": "output/search-cell-nas-bench-201/RANDOM-NAS-cifar10-{:}/checkpoint/".format(
+ sufix
+ ),
+ "DARTS-V1": "output/search-cell-nas-bench-201/DARTS-V1-cifar10-{:}/checkpoint/".format(
+ sufix
+ ),
+ "DARTS-V2": "output/search-cell-nas-bench-201/DARTS-V2-cifar10-{:}/checkpoint/".format(
+ sufix
+ ),
+ "GDAS": "output/search-cell-nas-bench-201/GDAS-cifar10-{:}/checkpoint/".format(
+ sufix
+ ),
+ "SETN": "output/search-cell-nas-bench-201/SETN-cifar10-{:}/checkpoint/".format(
+ sufix
+ ),
+ "ENAS": "output/search-cell-nas-bench-201/ENAS-cifar10-{:}/checkpoint/".format(
+ sufix
+ ),
+ }
+ """
+ xseeds = {'RSPS' : [5349, 59613, 5983],
+ 'DARTS-V1': [11416, 72873, 81184, 28640],
+ 'DARTS-V2': [43330, 79405, 79423],
+ 'GDAS' : [19677, 884, 95950],
+ 'SETN' : [20518, 61817, 89144],
+ 'ENAS' : [3231, 34238, 96929],
+ }
+ """
+ xseeds = {
+ "RSPS": [23814, 28015, 95809],
+ "DARTS-V1": [48349, 80877, 81920],
+ "DARTS-V2": [61712, 7941, 87041],
+ "GDAS": [72818, 72996, 78877],
+ "SETN": [26985, 55206, 95404],
+ "ENAS": [21792, 36605, 45029],
+ }
+
+ def get_accs(xdata):
+ epochs, xresults = xdata["epoch"], []
+ if -1 in xdata["genotypes"]:
+ metrics = api.arch2infos_full[
+ api.query_index_by_arch(xdata["genotypes"][-1])
+ ].get_metrics(dataset, subset, None, False)
+ else:
+ metrics = api.arch2infos_full[api.random()].get_metrics(
+ dataset, subset, None, False
+ )
+ xresults.append(metrics["accuracy"])
+ for iepoch in range(epochs):
+ genotype = xdata["genotypes"][iepoch]
+ index = api.query_index_by_arch(genotype)
+ metrics = api.arch2infos_full[index].get_metrics(
+ dataset, subset, None, False
+ )
+ xresults.append(metrics["accuracy"])
+ return xresults
+
+ if x_maxs == 50:
+ xox, xxxstrs = "v2", ["DARTS-V1", "DARTS-V2"]
+ elif x_maxs == 250:
+ xox, xxxstrs = "v1", ["RSPS", "GDAS", "SETN", "ENAS"]
+ else:
+ raise ValueError("invalid x_maxs={:}".format(x_maxs))
+
+ for idx, method in enumerate(xxxstrs):
+ xkey = method
+ all_paths = [
+ "{:}/seed-{:}-basic.pth".format(xpaths[xkey], seed) for seed in xseeds[xkey]
+ ]
+ all_datas = [torch.load(xpath, map_location="cpu") for xpath in all_paths]
+ accyss = [get_accs(xdatas) for xdatas in all_datas]
+ accyss = np.array(accyss)
+ epochs = list(range(accyss.shape[1]))
+ plt.plot(
+ epochs,
+ [accyss[:, i].mean() for i in epochs],
+ color=color_set[idx],
+ linestyle="-",
+ label="{:}".format(method),
+ lw=2,
+ )
+ plt.fill_between(
+ epochs,
+ [accyss[:, i].mean() - accyss[:, i].std() for i in epochs],
+ [accyss[:, i].mean() + accyss[:, i].std() for i in epochs],
+ alpha=0.2,
+ color=color_set[idx],
+ )
+ # plt.legend(loc=4, fontsize=LegendFontsize)
+ plt.legend(loc=0, fontsize=LegendFontsize)
+ save_path = vis_save_dir / "{:}.pdf".format(file_name)
+ print("save figure into {:}\n".format(save_path))
+ fig.savefig(str(save_path), dpi=dpi, bbox_inches="tight", format="pdf")
+
+
+def show_nas_sharing_w_v2(
+ api, data_sub_a, data_sub_b, vis_save_dir, sufix, file_name, y_lims, x_maxs
+):
+ color_set = ["r", "b", "g", "c", "m", "y", "k"]
+ dpi, width, height = 300, 3400, 2600
+ LabelSize, LegendFontsize = 28, 28
+ figsize = width / float(dpi), height / float(dpi)
+ fig = plt.figure(figsize=figsize)
+ # x_maxs = 250
+ plt.xlim(0, x_maxs + 1)
+ plt.ylim(y_lims[0], y_lims[1])
+ interval_x, interval_y = x_maxs // 5, y_lims[2]
+ plt.xticks(np.arange(0, x_maxs + 1, interval_x), fontsize=LegendFontsize)
+ plt.yticks(np.arange(y_lims[0], y_lims[1], interval_y), fontsize=LegendFontsize)
+ plt.grid()
+ plt.xlabel("The searching epoch", fontsize=LabelSize)
+ plt.ylabel("The accuracy (%)", fontsize=LabelSize)
+
+ xpaths = {
+ "RSPS": "output/search-cell-nas-bench-201/RANDOM-NAS-cifar10-{:}/checkpoint/".format(
+ sufix
+ ),
+ "DARTS-V1": "output/search-cell-nas-bench-201/DARTS-V1-cifar10-{:}/checkpoint/".format(
+ sufix
+ ),
+ "DARTS-V2": "output/search-cell-nas-bench-201/DARTS-V2-cifar10-{:}/checkpoint/".format(
+ sufix
+ ),
+ "GDAS": "output/search-cell-nas-bench-201/GDAS-cifar10-{:}/checkpoint/".format(
+ sufix
+ ),
+ "SETN": "output/search-cell-nas-bench-201/SETN-cifar10-{:}/checkpoint/".format(
+ sufix
+ ),
+ "ENAS": "output/search-cell-nas-bench-201/ENAS-cifar10-{:}/checkpoint/".format(
+ sufix
+ ),
+ }
+ """
+ xseeds = {'RSPS' : [5349, 59613, 5983],
+ 'DARTS-V1': [11416, 72873, 81184, 28640],
+ 'DARTS-V2': [43330, 79405, 79423],
+ 'GDAS' : [19677, 884, 95950],
+ 'SETN' : [20518, 61817, 89144],
+ 'ENAS' : [3231, 34238, 96929],
+ }
+ """
+ xseeds = {
+ "RSPS": [23814, 28015, 95809],
+ "DARTS-V1": [48349, 80877, 81920],
+ "DARTS-V2": [61712, 7941, 87041],
+ "GDAS": [72818, 72996, 78877],
+ "SETN": [26985, 55206, 95404],
+ "ENAS": [21792, 36605, 45029],
+ }
+
+ def get_accs(xdata, dataset, subset):
+ epochs, xresults = xdata["epoch"], []
+ if -1 in xdata["genotypes"]:
+ metrics = api.arch2infos_full[
+ api.query_index_by_arch(xdata["genotypes"][-1])
+ ].get_metrics(dataset, subset, None, False)
+ else:
+ metrics = api.arch2infos_full[api.random()].get_metrics(
+ dataset, subset, None, False
+ )
+ xresults.append(metrics["accuracy"])
+ for iepoch in range(epochs):
+ genotype = xdata["genotypes"][iepoch]
+ index = api.query_index_by_arch(genotype)
+ metrics = api.arch2infos_full[index].get_metrics(
+ dataset, subset, None, False
+ )
+ xresults.append(metrics["accuracy"])
+ return xresults
+
+ if x_maxs == 50:
+ xox, xxxstrs = "v2", ["DARTS-V1", "DARTS-V2"]
+ elif x_maxs == 250:
+ xox, xxxstrs = "v1", ["RSPS", "GDAS", "SETN", "ENAS"]
+ else:
+ raise ValueError("invalid x_maxs={:}".format(x_maxs))
+
+ for idx, method in enumerate(xxxstrs):
+ xkey = method
+ all_paths = [
+ "{:}/seed-{:}-basic.pth".format(xpaths[xkey], seed) for seed in xseeds[xkey]
+ ]
+ all_datas = [torch.load(xpath, map_location="cpu") for xpath in all_paths]
+ accyss_A = np.array(
+ [get_accs(xdatas, data_sub_a[0], data_sub_a[1]) for xdatas in all_datas]
+ )
+ accyss_B = np.array(
+ [get_accs(xdatas, data_sub_b[0], data_sub_b[1]) for xdatas in all_datas]
+ )
+ epochs = list(range(accyss_A.shape[1]))
+ for j, accyss in enumerate([accyss_A, accyss_B]):
+ if x_maxs == 50:
+ color, line = color_set[idx * 2 + j], "-" if j == 0 else "--"
+ elif x_maxs == 250:
+ color, line = color_set[idx], "-" if j == 0 else "--"
+ else:
+ raise ValueError("invalid x-maxs={:}".format(x_maxs))
+ plt.plot(
+ epochs,
+ [accyss[:, i].mean() for i in epochs],
+ color=color,
+ linestyle=line,
+ label="{:} ({:})".format(method, "VALID" if j == 0 else "TEST"),
+ lw=2,
+ alpha=0.9,
+ )
+ plt.fill_between(
+ epochs,
+ [accyss[:, i].mean() - accyss[:, i].std() for i in epochs],
+ [accyss[:, i].mean() + accyss[:, i].std() for i in epochs],
+ alpha=0.2,
+ color=color,
+ )
+ setname = data_sub_a if j == 0 else data_sub_b
+ print(
+ "{:} -- {:} ---- {:.2f}$\\pm${:.2f}".format(
+ method, setname, accyss[:, -1].mean(), accyss[:, -1].std()
+ )
+ )
+ # plt.legend(loc=4, fontsize=LegendFontsize)
+ plt.legend(loc=0, fontsize=LegendFontsize)
+ save_path = vis_save_dir / "{:}-{:}".format(xox, file_name)
+ print("save figure into {:}\n".format(save_path))
+ fig.savefig(str(save_path), dpi=dpi, bbox_inches="tight", format="pdf")
+
+
+def show_reinforce(api, root, dataset, xset, file_name, y_lims):
+ print("root-path={:}, dataset={:}, xset={:}".format(root, dataset, xset))
+ LRs = ["0.01", "0.02", "0.1", "0.2", "0.5"]
+ checkpoints = [
+ "./output/search-cell-nas-bench-201/REINFORCE-cifar10-{:}/results.pth".format(x)
+ for x in LRs
+ ]
+ acc_lr_dict, indexes = {}, None
+ for lr, checkpoint in zip(LRs, checkpoints):
+ all_indexes, accuracies = torch.load(checkpoint, map_location="cpu"), []
+ for x in all_indexes:
+ info = api.arch2infos_full[x]
+ metrics = info.get_metrics(dataset, xset, None, False)
+ accuracies.append(metrics["accuracy"])
+ if indexes is None:
+ indexes = list(range(len(accuracies)))
+ acc_lr_dict[lr] = np.array(sorted(accuracies))
+ print(
+ "LR={:.3f}, mean={:}, std={:}".format(
+ float(lr), acc_lr_dict[lr].mean(), acc_lr_dict[lr].std()
+ )
+ )
+
+ color_set = ["r", "b", "g", "c", "m", "y", "k"]
+ dpi, width, height = 300, 3400, 2600
+ LabelSize, LegendFontsize = 28, 22
+ figsize = width / float(dpi), height / float(dpi)
+ fig = plt.figure(figsize=figsize)
+ x_axis = np.arange(0, 600)
+ plt.xlim(0, max(indexes))
+ plt.ylim(y_lims[0], y_lims[1])
+ interval_x, interval_y = 100, y_lims[2]
+ plt.xticks(np.arange(0, max(indexes), interval_x), fontsize=LegendFontsize)
+ plt.yticks(np.arange(y_lims[0], y_lims[1], interval_y), fontsize=LegendFontsize)
+ plt.grid()
+ plt.xlabel("The index of runs", fontsize=LabelSize)
+ plt.ylabel("The accuracy (%)", fontsize=LabelSize)
+
+ for idx, LR in enumerate(LRs):
+ legend = "LR={:.2f}".format(float(LR))
+ # color, linestyle = color_set[idx // 2], '-' if idx % 2 == 0 else '-.'
+ color, linestyle = color_set[idx], "-"
+ plt.plot(
+ indexes,
+ acc_lr_dict[LR],
+ color=color,
+ linestyle=linestyle,
+ label=legend,
+ lw=2,
+ alpha=0.8,
+ )
+ print(
+ "{:} : mean = {:}, std = {:} :: {:.2f}$\\pm${:.2f}".format(
+ legend,
+ np.mean(acc_lr_dict[LR]),
+ np.std(acc_lr_dict[LR]),
+ np.mean(acc_lr_dict[LR]),
+ np.std(acc_lr_dict[LR]),
+ )
+ )
+ plt.legend(loc=4, fontsize=LegendFontsize)
+ save_path = root / "{:}-{:}-{:}.pdf".format(dataset, xset, file_name)
+ print("save figure into {:}\n".format(save_path))
+ fig.savefig(str(save_path), dpi=dpi, bbox_inches="tight", format="pdf")
+
+
+def show_rea(api, root, dataset, xset, file_name, y_lims):
+ print("root-path={:}, dataset={:}, xset={:}".format(root, dataset, xset))
+ SSs = [3, 5, 10]
+ checkpoints = [
+ "./output/search-cell-nas-bench-201/R-EA-cifar10-SS{:}/results.pth".format(x)
+ for x in SSs
+ ]
+ acc_ss_dict, indexes = {}, None
+ for ss, checkpoint in zip(SSs, checkpoints):
+ all_indexes, accuracies = torch.load(checkpoint, map_location="cpu"), []
+ for x in all_indexes:
+ info = api.arch2infos_full[x]
+ metrics = info.get_metrics(dataset, xset, None, False)
+ accuracies.append(metrics["accuracy"])
+ if indexes is None:
+ indexes = list(range(len(accuracies)))
+ acc_ss_dict[ss] = np.array(sorted(accuracies))
+ print(
+ "Sample-Size={:2d}, mean={:}, std={:}".format(
+ ss, acc_ss_dict[ss].mean(), acc_ss_dict[ss].std()
+ )
+ )
+
+ color_set = ["r", "b", "g", "c", "m", "y", "k"]
+ dpi, width, height = 300, 3400, 2600
+ LabelSize, LegendFontsize = 28, 22
+ figsize = width / float(dpi), height / float(dpi)
+ fig = plt.figure(figsize=figsize)
+ x_axis = np.arange(0, 600)
+ plt.xlim(0, max(indexes))
+ plt.ylim(y_lims[0], y_lims[1])
+ interval_x, interval_y = 100, y_lims[2]
+ plt.xticks(np.arange(0, max(indexes), interval_x), fontsize=LegendFontsize)
+ plt.yticks(np.arange(y_lims[0], y_lims[1], interval_y), fontsize=LegendFontsize)
+ plt.grid()
+ plt.xlabel("The index of runs", fontsize=LabelSize)
+ plt.ylabel("The accuracy (%)", fontsize=LabelSize)
+
+ for idx, ss in enumerate(SSs):
+ legend = "sample-size={:2d}".format(ss)
+ # color, linestyle = color_set[idx // 2], '-' if idx % 2 == 0 else '-.'
+ color, linestyle = color_set[idx], "-"
+ plt.plot(
+ indexes,
+ acc_ss_dict[ss],
+ color=color,
+ linestyle=linestyle,
+ label=legend,
+ lw=2,
+ alpha=0.8,
+ )
+ print(
+ "{:} : mean = {:}, std = {:} :: {:.2f}$\\pm${:.2f}".format(
+ legend,
+ np.mean(acc_ss_dict[ss]),
+ np.std(acc_ss_dict[ss]),
+ np.mean(acc_ss_dict[ss]),
+ np.std(acc_ss_dict[ss]),
+ )
+ )
+ plt.legend(loc=4, fontsize=LegendFontsize)
+ save_path = root / "{:}-{:}-{:}.pdf".format(dataset, xset, file_name)
+ print("save figure into {:}\n".format(save_path))
+ fig.savefig(str(save_path), dpi=dpi, bbox_inches="tight", format="pdf")
+
+
+if __name__ == "__main__":
+
+ parser = argparse.ArgumentParser(
+ description="NAS-Bench-201",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ )
+ parser.add_argument(
+ "--save_dir",
+ type=str,
+ default="./output/search-cell-nas-bench-201/visuals",
+ help="The base-name of folder to save checkpoints and log.",
+ )
+ parser.add_argument(
+ "--api_path",
+ type=str,
+ default=None,
+ help="The path to the NAS-Bench-201 benchmark file.",
+ )
+ args = parser.parse_args()
+
+ vis_save_dir = Path(args.save_dir)
+ vis_save_dir.mkdir(parents=True, exist_ok=True)
+ meta_file = Path(args.api_path)
+ assert meta_file.exists(), "invalid path for api : {:}".format(meta_file)
+ # visualize_rank_over_time(str(meta_file), vis_save_dir / 'over-time')
+ # write_video(vis_save_dir / 'over-time')
+ # visualize_info(str(meta_file), 'cifar10' , vis_save_dir)
+ # visualize_info(str(meta_file), 'cifar100', vis_save_dir)
+ # visualize_info(str(meta_file), 'ImageNet16-120', vis_save_dir)
+ # visualize_relative_ranking(vis_save_dir)
+
+ api = API(args.api_path)
+ # show_reinforce(api, vis_save_dir, 'cifar10-valid' , 'x-valid', 'REINFORCE-CIFAR-10', (85, 92, 2))
+ # show_rea (api, vis_save_dir, 'cifar10-valid' , 'x-valid', 'REA-CIFAR-10', (88, 92, 1))
+
+ # plot_results_nas_v2(api, ('cifar10-valid' , 'x-valid'), ('cifar10' , 'ori-test'), vis_save_dir, 'nas-com-v2-cifar010.pdf', (85,95, 1))
+ # plot_results_nas_v2(api, ('cifar100' , 'x-valid'), ('cifar100' , 'x-test' ), vis_save_dir, 'nas-com-v2-cifar100.pdf', (60,75, 3))
+ # plot_results_nas_v2(api, ('ImageNet16-120', 'x-valid'), ('ImageNet16-120', 'x-test' ), vis_save_dir, 'nas-com-v2-imagenet.pdf', (35,48, 2))
+
+ show_nas_sharing_w_v2(
+ api,
+ ("cifar10-valid", "x-valid"),
+ ("cifar10", "ori-test"),
+ vis_save_dir,
+ "BN0",
+ "BN0-DARTS-CIFAR010.pdf",
+ (0, 100, 10),
+ 50,
+ )
+ show_nas_sharing_w_v2(
+ api,
+ ("cifar100", "x-valid"),
+ ("cifar100", "x-test"),
+ vis_save_dir,
+ "BN0",
+ "BN0-DARTS-CIFAR100.pdf",
+ (0, 100, 10),
+ 50,
+ )
+ show_nas_sharing_w_v2(
+ api,
+ ("ImageNet16-120", "x-valid"),
+ ("ImageNet16-120", "x-test"),
+ vis_save_dir,
+ "BN0",
+ "BN0-DARTS-ImageNet.pdf",
+ (0, 100, 10),
+ 50,
+ )
+
+ show_nas_sharing_w_v2(
+ api,
+ ("cifar10-valid", "x-valid"),
+ ("cifar10", "ori-test"),
+ vis_save_dir,
+ "BN0",
+ "BN0-OTHER-CIFAR010.pdf",
+ (0, 100, 10),
+ 250,
+ )
+ show_nas_sharing_w_v2(
+ api,
+ ("cifar100", "x-valid"),
+ ("cifar100", "x-test"),
+ vis_save_dir,
+ "BN0",
+ "BN0-OTHER-CIFAR100.pdf",
+ (0, 100, 10),
+ 250,
+ )
+ show_nas_sharing_w_v2(
+ api,
+ ("ImageNet16-120", "x-valid"),
+ ("ImageNet16-120", "x-test"),
+ vis_save_dir,
+ "BN0",
+ "BN0-OTHER-ImageNet.pdf",
+ (0, 100, 10),
+ 250,
+ )
+
+ show_nas_sharing_w(
+ api,
+ "cifar10-valid",
+ "x-valid",
+ vis_save_dir,
+ "BN0",
+ "BN0-XX-CIFAR010-VALID.pdf",
+ (0, 100, 10),
+ 250,
+ )
+ show_nas_sharing_w(
+ api,
+ "cifar10",
+ "ori-test",
+ vis_save_dir,
+ "BN0",
+ "BN0-XX-CIFAR010-TEST.pdf",
+ (0, 100, 10),
+ 250,
+ )
+ """
+ for x_maxs in [50, 250]:
+ show_nas_sharing_w(api, 'cifar10-valid' , 'x-valid' , vis_save_dir, 'nas-plot.pdf', (0, 100,10), x_maxs)
+ show_nas_sharing_w(api, 'cifar10' , 'ori-test', vis_save_dir, 'nas-plot.pdf', (0, 100,10), x_maxs)
+ show_nas_sharing_w(api, 'cifar100' , 'x-valid' , vis_save_dir, 'nas-plot.pdf', (0, 100,10), x_maxs)
+ show_nas_sharing_w(api, 'cifar100' , 'x-test' , vis_save_dir, 'nas-plot.pdf', (0, 100,10), x_maxs)
+ show_nas_sharing_w(api, 'ImageNet16-120', 'x-valid' , vis_save_dir, 'nas-plot.pdf', (0, 100,10), x_maxs)
+ show_nas_sharing_w(api, 'ImageNet16-120', 'x-test' , vis_save_dir, 'nas-plot.pdf', (0, 100,10), x_maxs)
+
+ show_nas_sharing_w_v2(api, ('cifar10-valid' , 'x-valid'), ('cifar10' , 'ori-test') , vis_save_dir, 'DARTS-CIFAR010.pdf', (0, 100,10), 50)
+ just_show(api)
+ plot_results_nas(api, 'cifar10-valid' , 'x-valid' , vis_save_dir, 'nas-com.pdf', (85,95, 1))
+ plot_results_nas(api, 'cifar10' , 'ori-test', vis_save_dir, 'nas-com.pdf', (85,95, 1))
+ plot_results_nas(api, 'cifar100' , 'x-valid' , vis_save_dir, 'nas-com.pdf', (55,75, 3))
+ plot_results_nas(api, 'cifar100' , 'x-test' , vis_save_dir, 'nas-com.pdf', (55,75, 3))
+ plot_results_nas(api, 'ImageNet16-120', 'x-valid' , vis_save_dir, 'nas-com.pdf', (35,50, 3))
+ plot_results_nas(api, 'ImageNet16-120', 'x-test' , vis_save_dir, 'nas-com.pdf', (35,50, 3))
+ """
diff --git a/AutoDL-Projects/exps/NATS-Bench/Analyze-time.py b/AutoDL-Projects/exps/NATS-Bench/Analyze-time.py
new file mode 100644
index 0000000..e9b0c6e
--- /dev/null
+++ b/AutoDL-Projects/exps/NATS-Bench/Analyze-time.py
@@ -0,0 +1,53 @@
+##############################################################################
+# NATS-Bench: Benchmarking NAS Algorithms for Architecture Topology and Size #
+##############################################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020.07 #
+##############################################################################
+# python ./exps/NATS-Bench/Analyze-time.py #
+##############################################################################
+import os, sys, time, tqdm, argparse
+from pathlib import Path
+
+from xautodl.config_utils import dict2config, load_config
+from xautodl.datasets import get_datasets
+from nats_bench import create
+
+
+def show_time(api, epoch=12):
+ print("Show the time for {:} with {:}-epoch-training".format(api, epoch))
+ all_cifar10_time, all_cifar100_time, all_imagenet_time = 0, 0, 0
+ for index in tqdm.tqdm(range(len(api))):
+ info = api.get_more_info(index, "ImageNet16-120", hp=epoch)
+ imagenet_time = info["train-all-time"]
+ info = api.get_more_info(index, "cifar10-valid", hp=epoch)
+ cifar10_time = info["train-all-time"]
+ info = api.get_more_info(index, "cifar100", hp=epoch)
+ cifar100_time = info["train-all-time"]
+ # accumulate the time
+ all_cifar10_time += cifar10_time
+ all_cifar100_time += cifar100_time
+ all_imagenet_time += imagenet_time
+ print(
+ "The total training time for CIFAR-10 (held-out train set) is {:} seconds".format(
+ all_cifar10_time
+ )
+ )
+ print(
+ "The total training time for CIFAR-100 (held-out train set) is {:} seconds, {:.2f} times longer than that on CIFAR-10".format(
+ all_cifar100_time, all_cifar100_time / all_cifar10_time
+ )
+ )
+ print(
+ "The total training time for ImageNet-16-120 (held-out train set) is {:} seconds, {:.2f} times longer than that on CIFAR-10".format(
+ all_imagenet_time, all_imagenet_time / all_cifar10_time
+ )
+ )
+
+
+if __name__ == "__main__":
+
+ api_nats_tss = create(None, "tss", fast_mode=True, verbose=False)
+ show_time(api_nats_tss, 12)
+
+ api_nats_sss = create(None, "sss", fast_mode=True, verbose=False)
+ show_time(api_nats_sss, 12)
diff --git a/AutoDL-Projects/exps/NATS-Bench/draw-correlations.py b/AutoDL-Projects/exps/NATS-Bench/draw-correlations.py
new file mode 100644
index 0000000..db34a2d
--- /dev/null
+++ b/AutoDL-Projects/exps/NATS-Bench/draw-correlations.py
@@ -0,0 +1,123 @@
+###############################################################
+# NATS-Bench (arxiv.org/pdf/2009.00437.pdf), IEEE TPAMI 2021 #
+###############################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020.06 #
+###############################################################
+# Usage: python exps/NATS-Bench/draw-correlations.py #
+###############################################################
+import os, gc, sys, time, scipy, torch, argparse
+import numpy as np
+from typing import List, Text, Dict, Any
+from shutil import copyfile
+from collections import defaultdict, OrderedDict
+from copy import deepcopy
+from pathlib import Path
+import matplotlib
+import seaborn as sns
+
+matplotlib.use("agg")
+import matplotlib.pyplot as plt
+import matplotlib.ticker as ticker
+
+from xautodl.config_utils import dict2config, load_config
+from xautodl.log_utils import time_string
+from nats_bench import create
+
+
+def get_valid_test_acc(api, arch, dataset):
+ is_size_space = api.search_space_name == "size"
+ if dataset == "cifar10":
+ xinfo = api.get_more_info(
+ arch, dataset=dataset, hp=90 if is_size_space else 200, is_random=False
+ )
+ test_acc = xinfo["test-accuracy"]
+ xinfo = api.get_more_info(
+ arch,
+ dataset="cifar10-valid",
+ hp=90 if is_size_space else 200,
+ is_random=False,
+ )
+ valid_acc = xinfo["valid-accuracy"]
+ else:
+ xinfo = api.get_more_info(
+ arch, dataset=dataset, hp=90 if is_size_space else 200, is_random=False
+ )
+ valid_acc = xinfo["valid-accuracy"]
+ test_acc = xinfo["test-accuracy"]
+ return (
+ valid_acc,
+ test_acc,
+ "validation = {:.2f}, test = {:.2f}\n".format(valid_acc, test_acc),
+ )
+
+
+def compute_kendalltau(vectori, vectorj):
+ # indexes = list(range(len(vectori)))
+ # rank_1 = sorted(indexes, key=lambda i: vectori[i])
+ # rank_2 = sorted(indexes, key=lambda i: vectorj[i])
+ # import pdb; pdb.set_trace()
+ coef, p = scipy.stats.kendalltau(vectori, vectorj)
+ return coef
+
+
+def compute_spearmanr(vectori, vectorj):
+ coef, p = scipy.stats.spearmanr(vectori, vectorj)
+ return coef
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(
+ description="NATS-Bench: Benchmarking NAS Algorithms for Architecture Topology and Size",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ )
+ parser.add_argument(
+ "--save_dir",
+ type=str,
+ default="output/vis-nas-bench/nas-algos",
+ help="Folder to save checkpoints and log.",
+ )
+ parser.add_argument(
+ "--search_space",
+ type=str,
+ choices=["tss", "sss"],
+ help="Choose the search space.",
+ )
+ args = parser.parse_args()
+
+ save_dir = Path(args.save_dir)
+
+ api = create(None, "tss", fast_mode=True, verbose=False)
+ indexes = list(range(1, 10000, 300))
+ scores_1 = []
+ scores_2 = []
+ for index in indexes:
+ valid_acc, test_acc, _ = get_valid_test_acc(api, index, "cifar10")
+ scores_1.append(valid_acc)
+ scores_2.append(test_acc)
+ correlation = compute_kendalltau(scores_1, scores_2)
+ print(
+ "The kendall tau correlation of {:} samples : {:}".format(
+ len(indexes), correlation
+ )
+ )
+ correlation = compute_spearmanr(scores_1, scores_2)
+ print(
+ "The spearmanr correlation of {:} samples : {:}".format(
+ len(indexes), correlation
+ )
+ )
+ # scores_1 = ['{:.2f}'.format(x) for x in scores_1]
+ # scores_2 = ['{:.2f}'.format(x) for x in scores_2]
+ # print(', '.join(scores_1))
+ # print(', '.join(scores_2))
+
+ dpi, width, height = 250, 1000, 1000
+ figsize = width / float(dpi), height / float(dpi)
+ LabelSize, LegendFontsize = 14, 14
+
+ fig, ax = plt.subplots(1, 1, figsize=figsize)
+ ax.scatter(scores_1, scores_2, marker="^", s=0.5, c="tab:green", alpha=0.8)
+
+ save_path = "/Users/xuanyidong/Desktop/test-temp-rank.png"
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="png")
+ plt.close("all")
diff --git a/AutoDL-Projects/exps/NATS-Bench/draw-fig2_5.py b/AutoDL-Projects/exps/NATS-Bench/draw-fig2_5.py
new file mode 100644
index 0000000..779d18d
--- /dev/null
+++ b/AutoDL-Projects/exps/NATS-Bench/draw-fig2_5.py
@@ -0,0 +1,651 @@
+###############################################################
+# NATS-Bench (arxiv.org/pdf/2009.00437.pdf), IEEE TPAMI 2021 #
+# The code to draw Figure 2 / 3 / 4 / 5 in our paper. #
+###############################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020.06 #
+###############################################################
+# Usage: python exps/NATS-Bench/draw-fig2_5.py #
+###############################################################
+import os, sys, time, torch, argparse
+import scipy
+import numpy as np
+from typing import List, Text, Dict, Any
+from shutil import copyfile
+from collections import defaultdict
+from copy import deepcopy
+from pathlib import Path
+import matplotlib
+import seaborn as sns
+
+matplotlib.use("agg")
+import matplotlib.pyplot as plt
+import matplotlib.ticker as ticker
+from xautodl.config_utils import dict2config, load_config
+from xautodl.log_utils import time_string
+from xautodl.models import get_cell_based_tiny_net
+from nats_bench import create
+
+
+def visualize_relative_info(api, vis_save_dir, indicator):
+ vis_save_dir = vis_save_dir.resolve()
+ # print ('{:} start to visualize {:} information'.format(time_string(), api))
+ vis_save_dir.mkdir(parents=True, exist_ok=True)
+
+ cifar010_cache_path = vis_save_dir / "{:}-cache-{:}-info.pth".format(
+ "cifar10", indicator
+ )
+ cifar100_cache_path = vis_save_dir / "{:}-cache-{:}-info.pth".format(
+ "cifar100", indicator
+ )
+ imagenet_cache_path = vis_save_dir / "{:}-cache-{:}-info.pth".format(
+ "ImageNet16-120", indicator
+ )
+ cifar010_info = torch.load(cifar010_cache_path)
+ cifar100_info = torch.load(cifar100_cache_path)
+ imagenet_info = torch.load(imagenet_cache_path)
+ indexes = list(range(len(cifar010_info["params"])))
+
+ print("{:} start to visualize relative ranking".format(time_string()))
+
+ cifar010_ord_indexes = sorted(indexes, key=lambda i: cifar010_info["test_accs"][i])
+ cifar100_ord_indexes = sorted(indexes, key=lambda i: cifar100_info["test_accs"][i])
+ imagenet_ord_indexes = sorted(indexes, key=lambda i: imagenet_info["test_accs"][i])
+
+ cifar100_labels, imagenet_labels = [], []
+ for idx in cifar010_ord_indexes:
+ cifar100_labels.append(cifar100_ord_indexes.index(idx))
+ imagenet_labels.append(imagenet_ord_indexes.index(idx))
+ print("{:} prepare data done.".format(time_string()))
+
+ dpi, width, height = 200, 1400, 800
+ figsize = width / float(dpi), height / float(dpi)
+ LabelSize, LegendFontsize = 18, 12
+ resnet_scale, resnet_alpha = 120, 0.5
+
+ fig = plt.figure(figsize=figsize)
+ ax = fig.add_subplot(111)
+ plt.xlim(min(indexes), max(indexes))
+ plt.ylim(min(indexes), max(indexes))
+ # plt.ylabel('y').set_rotation(30)
+ plt.yticks(
+ np.arange(min(indexes), max(indexes), max(indexes) // 3),
+ fontsize=LegendFontsize,
+ rotation="vertical",
+ )
+ plt.xticks(
+ np.arange(min(indexes), max(indexes), max(indexes) // 5),
+ fontsize=LegendFontsize,
+ )
+ ax.scatter(indexes, cifar100_labels, marker="^", s=0.5, c="tab:green", alpha=0.8)
+ ax.scatter(indexes, imagenet_labels, marker="*", s=0.5, c="tab:red", alpha=0.8)
+ ax.scatter(indexes, indexes, marker="o", s=0.5, c="tab:blue", alpha=0.8)
+ ax.scatter([-1], [-1], marker="o", s=100, c="tab:blue", label="CIFAR-10")
+ ax.scatter([-1], [-1], marker="^", s=100, c="tab:green", label="CIFAR-100")
+ ax.scatter([-1], [-1], marker="*", s=100, c="tab:red", label="ImageNet-16-120")
+ plt.grid(zorder=0)
+ ax.set_axisbelow(True)
+ plt.legend(loc=0, fontsize=LegendFontsize)
+ ax.set_xlabel("architecture ranking in CIFAR-10", fontsize=LabelSize)
+ ax.set_ylabel("architecture ranking", fontsize=LabelSize)
+ save_path = (vis_save_dir / "{:}-relative-rank.pdf".format(indicator)).resolve()
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="pdf")
+ save_path = (vis_save_dir / "{:}-relative-rank.png".format(indicator)).resolve()
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="png")
+ print("{:} save into {:}".format(time_string(), save_path))
+
+
+def visualize_sss_info(api, dataset, vis_save_dir):
+ vis_save_dir = vis_save_dir.resolve()
+ print("{:} start to visualize {:} information".format(time_string(), dataset))
+ vis_save_dir.mkdir(parents=True, exist_ok=True)
+ cache_file_path = vis_save_dir / "{:}-cache-sss-info.pth".format(dataset)
+ if not cache_file_path.exists():
+ print("Do not find cache file : {:}".format(cache_file_path))
+ params, flops, train_accs, valid_accs, test_accs = [], [], [], [], []
+ for index in range(len(api)):
+ cost_info = api.get_cost_info(index, dataset, hp="90")
+ params.append(cost_info["params"])
+ flops.append(cost_info["flops"])
+ # accuracy
+ info = api.get_more_info(index, dataset, hp="90", is_random=False)
+ train_accs.append(info["train-accuracy"])
+ test_accs.append(info["test-accuracy"])
+ if dataset == "cifar10":
+ info = api.get_more_info(
+ index, "cifar10-valid", hp="90", is_random=False
+ )
+ valid_accs.append(info["valid-accuracy"])
+ else:
+ valid_accs.append(info["valid-accuracy"])
+ info = {
+ "params": params,
+ "flops": flops,
+ "train_accs": train_accs,
+ "valid_accs": valid_accs,
+ "test_accs": test_accs,
+ }
+ torch.save(info, cache_file_path)
+ else:
+ print("Find cache file : {:}".format(cache_file_path))
+ info = torch.load(cache_file_path)
+ params, flops, train_accs, valid_accs, test_accs = (
+ info["params"],
+ info["flops"],
+ info["train_accs"],
+ info["valid_accs"],
+ info["test_accs"],
+ )
+ print("{:} collect data done.".format(time_string()))
+
+ # pyramid = ['8:16:32:48:64', '8:8:16:32:48', '8:8:16:16:32', '8:8:16:16:48', '8:8:16:16:64', '16:16:32:32:64', '32:32:64:64:64']
+ pyramid = ["8:16:24:32:40", "8:16:32:48:64", "32:40:48:56:64"]
+ pyramid_indexes = [api.query_index_by_arch(x) for x in pyramid]
+ largest_indexes = [api.query_index_by_arch("64:64:64:64:64")]
+
+ indexes = list(range(len(params)))
+ dpi, width, height = 250, 8500, 1300
+ figsize = width / float(dpi), height / float(dpi)
+ LabelSize, LegendFontsize = 24, 24
+ # resnet_scale, resnet_alpha = 120, 0.5
+ xscale, xalpha = 120, 0.8
+
+ fig, axs = plt.subplots(1, 4, figsize=figsize)
+ # ax1, ax2, ax3, ax4, ax5 = axs
+ for ax in axs:
+ for tick in ax.xaxis.get_major_ticks():
+ tick.label.set_fontsize(LabelSize)
+ ax.yaxis.set_major_formatter(ticker.FormatStrFormatter("%.0f"))
+ for tick in ax.yaxis.get_major_ticks():
+ tick.label.set_fontsize(LabelSize)
+ ax1, ax2, ax3, ax4 = axs
+
+ ax1.scatter(params, train_accs, marker="o", s=0.5, c="tab:blue")
+ ax1.scatter(
+ [params[x] for x in pyramid_indexes],
+ [train_accs[x] for x in pyramid_indexes],
+ marker="*",
+ s=xscale,
+ c="tab:orange",
+ label="Pyramid Structure",
+ alpha=xalpha,
+ )
+ ax1.scatter(
+ [params[x] for x in largest_indexes],
+ [train_accs[x] for x in largest_indexes],
+ marker="x",
+ s=xscale,
+ c="tab:green",
+ label="Largest Candidate",
+ alpha=xalpha,
+ )
+ ax1.set_xlabel("#parameters (MB)", fontsize=LabelSize)
+ ax1.set_ylabel("train accuracy (%)", fontsize=LabelSize)
+ ax1.legend(loc=4, fontsize=LegendFontsize)
+
+ ax2.scatter(flops, train_accs, marker="o", s=0.5, c="tab:blue")
+ ax2.scatter(
+ [flops[x] for x in pyramid_indexes],
+ [train_accs[x] for x in pyramid_indexes],
+ marker="*",
+ s=xscale,
+ c="tab:orange",
+ label="Pyramid Structure",
+ alpha=xalpha,
+ )
+ ax2.scatter(
+ [flops[x] for x in largest_indexes],
+ [train_accs[x] for x in largest_indexes],
+ marker="x",
+ s=xscale,
+ c="tab:green",
+ label="Largest Candidate",
+ alpha=xalpha,
+ )
+ ax2.set_xlabel("#FLOPs (M)", fontsize=LabelSize)
+ # ax2.set_ylabel('train accuracy (%)', fontsize=LabelSize)
+ ax2.legend(loc=4, fontsize=LegendFontsize)
+
+ ax3.scatter(params, test_accs, marker="o", s=0.5, c="tab:blue")
+ ax3.scatter(
+ [params[x] for x in pyramid_indexes],
+ [test_accs[x] for x in pyramid_indexes],
+ marker="*",
+ s=xscale,
+ c="tab:orange",
+ label="Pyramid Structure",
+ alpha=xalpha,
+ )
+ ax3.scatter(
+ [params[x] for x in largest_indexes],
+ [test_accs[x] for x in largest_indexes],
+ marker="x",
+ s=xscale,
+ c="tab:green",
+ label="Largest Candidate",
+ alpha=xalpha,
+ )
+ ax3.set_xlabel("#parameters (MB)", fontsize=LabelSize)
+ ax3.set_ylabel("test accuracy (%)", fontsize=LabelSize)
+ ax3.legend(loc=4, fontsize=LegendFontsize)
+
+ ax4.scatter(flops, test_accs, marker="o", s=0.5, c="tab:blue")
+ ax4.scatter(
+ [flops[x] for x in pyramid_indexes],
+ [test_accs[x] for x in pyramid_indexes],
+ marker="*",
+ s=xscale,
+ c="tab:orange",
+ label="Pyramid Structure",
+ alpha=xalpha,
+ )
+ ax4.scatter(
+ [flops[x] for x in largest_indexes],
+ [test_accs[x] for x in largest_indexes],
+ marker="x",
+ s=xscale,
+ c="tab:green",
+ label="Largest Candidate",
+ alpha=xalpha,
+ )
+ ax4.set_xlabel("#FLOPs (M)", fontsize=LabelSize)
+ # ax4.set_ylabel('test accuracy (%)', fontsize=LabelSize)
+ ax4.legend(loc=4, fontsize=LegendFontsize)
+
+ save_path = vis_save_dir / "sss-{:}.png".format(dataset.lower())
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="png")
+ print("{:} save into {:}".format(time_string(), save_path))
+ plt.close("all")
+
+
+def visualize_tss_info(api, dataset, vis_save_dir):
+ vis_save_dir = vis_save_dir.resolve()
+ print("{:} start to visualize {:} information".format(time_string(), dataset))
+ vis_save_dir.mkdir(parents=True, exist_ok=True)
+ cache_file_path = vis_save_dir / "{:}-cache-tss-info.pth".format(dataset)
+ if not cache_file_path.exists():
+ print("Do not find cache file : {:}".format(cache_file_path))
+ params, flops, train_accs, valid_accs, test_accs = [], [], [], [], []
+ for index in range(len(api)):
+ cost_info = api.get_cost_info(index, dataset, hp="12")
+ params.append(cost_info["params"])
+ flops.append(cost_info["flops"])
+ # accuracy
+ info = api.get_more_info(index, dataset, hp="200", is_random=False)
+ train_accs.append(info["train-accuracy"])
+ test_accs.append(info["test-accuracy"])
+ if dataset == "cifar10":
+ info = api.get_more_info(
+ index, "cifar10-valid", hp="200", is_random=False
+ )
+ valid_accs.append(info["valid-accuracy"])
+ else:
+ valid_accs.append(info["valid-accuracy"])
+ print("")
+ info = {
+ "params": params,
+ "flops": flops,
+ "train_accs": train_accs,
+ "valid_accs": valid_accs,
+ "test_accs": test_accs,
+ }
+ torch.save(info, cache_file_path)
+ else:
+ print("Find cache file : {:}".format(cache_file_path))
+ info = torch.load(cache_file_path)
+ params, flops, train_accs, valid_accs, test_accs = (
+ info["params"],
+ info["flops"],
+ info["train_accs"],
+ info["valid_accs"],
+ info["test_accs"],
+ )
+ print("{:} collect data done.".format(time_string()))
+
+ resnet = [
+ "|nor_conv_3x3~0|+|none~0|nor_conv_3x3~1|+|skip_connect~0|none~1|skip_connect~2|"
+ ]
+ resnet_indexes = [api.query_index_by_arch(x) for x in resnet]
+ largest_indexes = [
+ api.query_index_by_arch(
+ "|nor_conv_3x3~0|+|nor_conv_3x3~0|nor_conv_3x3~1|+|nor_conv_3x3~0|nor_conv_3x3~1|nor_conv_3x3~2|"
+ )
+ ]
+
+ indexes = list(range(len(params)))
+ dpi, width, height = 250, 8500, 1300
+ figsize = width / float(dpi), height / float(dpi)
+ LabelSize, LegendFontsize = 24, 24
+ # resnet_scale, resnet_alpha = 120, 0.5
+ xscale, xalpha = 120, 0.8
+
+ fig, axs = plt.subplots(1, 4, figsize=figsize)
+ for ax in axs:
+ for tick in ax.xaxis.get_major_ticks():
+ tick.label.set_fontsize(LabelSize)
+ ax.yaxis.set_major_formatter(ticker.FormatStrFormatter("%.0f"))
+ for tick in ax.yaxis.get_major_ticks():
+ tick.label.set_fontsize(LabelSize)
+ ax1, ax2, ax3, ax4 = axs
+
+ ax1.scatter(params, train_accs, marker="o", s=0.5, c="tab:blue")
+ ax1.scatter(
+ [params[x] for x in resnet_indexes],
+ [train_accs[x] for x in resnet_indexes],
+ marker="*",
+ s=xscale,
+ c="tab:orange",
+ label="ResNet",
+ alpha=xalpha,
+ )
+ ax1.scatter(
+ [params[x] for x in largest_indexes],
+ [train_accs[x] for x in largest_indexes],
+ marker="x",
+ s=xscale,
+ c="tab:green",
+ label="Largest Candidate",
+ alpha=xalpha,
+ )
+ ax1.set_xlabel("#parameters (MB)", fontsize=LabelSize)
+ ax1.set_ylabel("train accuracy (%)", fontsize=LabelSize)
+ ax1.legend(loc=4, fontsize=LegendFontsize)
+
+ ax2.scatter(flops, train_accs, marker="o", s=0.5, c="tab:blue")
+ ax2.scatter(
+ [flops[x] for x in resnet_indexes],
+ [train_accs[x] for x in resnet_indexes],
+ marker="*",
+ s=xscale,
+ c="tab:orange",
+ label="ResNet",
+ alpha=xalpha,
+ )
+ ax2.scatter(
+ [flops[x] for x in largest_indexes],
+ [train_accs[x] for x in largest_indexes],
+ marker="x",
+ s=xscale,
+ c="tab:green",
+ label="Largest Candidate",
+ alpha=xalpha,
+ )
+ ax2.set_xlabel("#FLOPs (M)", fontsize=LabelSize)
+ # ax2.set_ylabel('train accuracy (%)', fontsize=LabelSize)
+ ax2.legend(loc=4, fontsize=LegendFontsize)
+
+ ax3.scatter(params, test_accs, marker="o", s=0.5, c="tab:blue")
+ ax3.scatter(
+ [params[x] for x in resnet_indexes],
+ [test_accs[x] for x in resnet_indexes],
+ marker="*",
+ s=xscale,
+ c="tab:orange",
+ label="ResNet",
+ alpha=xalpha,
+ )
+ ax3.scatter(
+ [params[x] for x in largest_indexes],
+ [test_accs[x] for x in largest_indexes],
+ marker="x",
+ s=xscale,
+ c="tab:green",
+ label="Largest Candidate",
+ alpha=xalpha,
+ )
+ ax3.set_xlabel("#parameters (MB)", fontsize=LabelSize)
+ ax3.set_ylabel("test accuracy (%)", fontsize=LabelSize)
+ ax3.legend(loc=4, fontsize=LegendFontsize)
+
+ ax4.scatter(flops, test_accs, marker="o", s=0.5, c="tab:blue")
+ ax4.scatter(
+ [flops[x] for x in resnet_indexes],
+ [test_accs[x] for x in resnet_indexes],
+ marker="*",
+ s=xscale,
+ c="tab:orange",
+ label="ResNet",
+ alpha=xalpha,
+ )
+ ax4.scatter(
+ [flops[x] for x in largest_indexes],
+ [test_accs[x] for x in largest_indexes],
+ marker="x",
+ s=xscale,
+ c="tab:green",
+ label="Largest Candidate",
+ alpha=xalpha,
+ )
+ ax4.set_xlabel("#FLOPs (M)", fontsize=LabelSize)
+ # ax4.set_ylabel('test accuracy (%)', fontsize=LabelSize)
+ ax4.legend(loc=4, fontsize=LegendFontsize)
+
+ save_path = vis_save_dir / "tss-{:}.png".format(dataset.lower())
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="png")
+ print("{:} save into {:}".format(time_string(), save_path))
+ plt.close("all")
+
+
+def visualize_rank_info(api, vis_save_dir, indicator):
+ vis_save_dir = vis_save_dir.resolve()
+ # print ('{:} start to visualize {:} information'.format(time_string(), api))
+ vis_save_dir.mkdir(parents=True, exist_ok=True)
+
+ cifar010_cache_path = vis_save_dir / "{:}-cache-{:}-info.pth".format(
+ "cifar10", indicator
+ )
+ cifar100_cache_path = vis_save_dir / "{:}-cache-{:}-info.pth".format(
+ "cifar100", indicator
+ )
+ imagenet_cache_path = vis_save_dir / "{:}-cache-{:}-info.pth".format(
+ "ImageNet16-120", indicator
+ )
+ cifar010_info = torch.load(cifar010_cache_path)
+ cifar100_info = torch.load(cifar100_cache_path)
+ imagenet_info = torch.load(imagenet_cache_path)
+ indexes = list(range(len(cifar010_info["params"])))
+
+ print("{:} start to visualize relative ranking".format(time_string()))
+
+ dpi, width, height = 250, 3800, 1200
+ figsize = width / float(dpi), height / float(dpi)
+ LabelSize, LegendFontsize = 14, 14
+
+ fig, axs = plt.subplots(1, 3, figsize=figsize)
+ ax1, ax2, ax3 = axs
+
+ def get_labels(info):
+ ord_test_indexes = sorted(indexes, key=lambda i: info["test_accs"][i])
+ ord_valid_indexes = sorted(indexes, key=lambda i: info["valid_accs"][i])
+ labels = []
+ for idx in ord_test_indexes:
+ labels.append(ord_valid_indexes.index(idx))
+ return labels
+
+ def plot_ax(labels, ax, name):
+ for tick in ax.xaxis.get_major_ticks():
+ tick.label.set_fontsize(LabelSize)
+ for tick in ax.yaxis.get_major_ticks():
+ tick.label.set_fontsize(LabelSize)
+ tick.label.set_rotation(90)
+ ax.set_xlim(min(indexes), max(indexes))
+ ax.set_ylim(min(indexes), max(indexes))
+ ax.yaxis.set_ticks(np.arange(min(indexes), max(indexes), max(indexes) // 3))
+ ax.xaxis.set_ticks(np.arange(min(indexes), max(indexes), max(indexes) // 5))
+ ax.scatter(indexes, labels, marker="^", s=0.5, c="tab:green", alpha=0.8)
+ ax.scatter(indexes, indexes, marker="o", s=0.5, c="tab:blue", alpha=0.8)
+ ax.scatter(
+ [-1], [-1], marker="^", s=100, c="tab:green", label="{:} test".format(name)
+ )
+ ax.scatter(
+ [-1],
+ [-1],
+ marker="o",
+ s=100,
+ c="tab:blue",
+ label="{:} validation".format(name),
+ )
+ ax.legend(loc=4, fontsize=LegendFontsize)
+ ax.set_xlabel("ranking on the {:} validation".format(name), fontsize=LabelSize)
+ ax.set_ylabel("architecture ranking", fontsize=LabelSize)
+
+ labels = get_labels(cifar010_info)
+ plot_ax(labels, ax1, "CIFAR-10")
+ labels = get_labels(cifar100_info)
+ plot_ax(labels, ax2, "CIFAR-100")
+ labels = get_labels(imagenet_info)
+ plot_ax(labels, ax3, "ImageNet-16-120")
+
+ save_path = (
+ vis_save_dir / "{:}-same-relative-rank.pdf".format(indicator)
+ ).resolve()
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="pdf")
+ save_path = (
+ vis_save_dir / "{:}-same-relative-rank.png".format(indicator)
+ ).resolve()
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="png")
+ print("{:} save into {:}".format(time_string(), save_path))
+ plt.close("all")
+
+
+def compute_kendalltau(vectori, vectorj):
+ # indexes = list(range(len(vectori)))
+ # rank_1 = sorted(indexes, key=lambda i: vectori[i])
+ # rank_2 = sorted(indexes, key=lambda i: vectorj[i])
+ return scipy.stats.kendalltau(vectori, vectorj).correlation
+
+
+def calculate_correlation(*vectors):
+ matrix = []
+ for i, vectori in enumerate(vectors):
+ x = []
+ for j, vectorj in enumerate(vectors):
+ # x.append(np.corrcoef(vectori, vectorj)[0,1])
+ x.append(compute_kendalltau(vectori, vectorj))
+ matrix.append(x)
+ return np.array(matrix)
+
+
+def visualize_all_rank_info(api, vis_save_dir, indicator):
+ vis_save_dir = vis_save_dir.resolve()
+ # print ('{:} start to visualize {:} information'.format(time_string(), api))
+ vis_save_dir.mkdir(parents=True, exist_ok=True)
+
+ cifar010_cache_path = vis_save_dir / "{:}-cache-{:}-info.pth".format(
+ "cifar10", indicator
+ )
+ cifar100_cache_path = vis_save_dir / "{:}-cache-{:}-info.pth".format(
+ "cifar100", indicator
+ )
+ imagenet_cache_path = vis_save_dir / "{:}-cache-{:}-info.pth".format(
+ "ImageNet16-120", indicator
+ )
+ cifar010_info = torch.load(cifar010_cache_path)
+ cifar100_info = torch.load(cifar100_cache_path)
+ imagenet_info = torch.load(imagenet_cache_path)
+ indexes = list(range(len(cifar010_info["params"])))
+
+ print("{:} start to visualize relative ranking".format(time_string()))
+
+ dpi, width, height = 250, 3200, 1400
+ figsize = width / float(dpi), height / float(dpi)
+ LabelSize, LegendFontsize = 14, 14
+
+ fig, axs = plt.subplots(1, 2, figsize=figsize)
+ ax1, ax2 = axs
+
+ sns_size, xformat = 15, ".2f"
+ CoRelMatrix = calculate_correlation(
+ cifar010_info["valid_accs"],
+ cifar010_info["test_accs"],
+ cifar100_info["valid_accs"],
+ cifar100_info["test_accs"],
+ imagenet_info["valid_accs"],
+ imagenet_info["test_accs"],
+ )
+
+ sns.heatmap(
+ CoRelMatrix,
+ annot=True,
+ annot_kws={"size": sns_size},
+ fmt=xformat,
+ linewidths=0.5,
+ ax=ax1,
+ xticklabels=["C10-V", "C10-T", "C100-V", "C100-T", "I120-V", "I120-T"],
+ yticklabels=["C10-V", "C10-T", "C100-V", "C100-T", "I120-V", "I120-T"],
+ )
+
+ selected_indexes, acc_bar = [], 92
+ for i, acc in enumerate(cifar010_info["test_accs"]):
+ if acc > acc_bar:
+ selected_indexes.append(i)
+ cifar010_valid_accs = np.array(cifar010_info["valid_accs"])[selected_indexes]
+ cifar010_test_accs = np.array(cifar010_info["test_accs"])[selected_indexes]
+ cifar100_valid_accs = np.array(cifar100_info["valid_accs"])[selected_indexes]
+ cifar100_test_accs = np.array(cifar100_info["test_accs"])[selected_indexes]
+ imagenet_valid_accs = np.array(imagenet_info["valid_accs"])[selected_indexes]
+ imagenet_test_accs = np.array(imagenet_info["test_accs"])[selected_indexes]
+ CoRelMatrix = calculate_correlation(
+ cifar010_valid_accs,
+ cifar010_test_accs,
+ cifar100_valid_accs,
+ cifar100_test_accs,
+ imagenet_valid_accs,
+ imagenet_test_accs,
+ )
+
+ sns.heatmap(
+ CoRelMatrix,
+ annot=True,
+ annot_kws={"size": sns_size},
+ fmt=xformat,
+ linewidths=0.5,
+ ax=ax2,
+ xticklabels=["C10-V", "C10-T", "C100-V", "C100-T", "I120-V", "I120-T"],
+ yticklabels=["C10-V", "C10-T", "C100-V", "C100-T", "I120-V", "I120-T"],
+ )
+ ax1.set_title("Correlation coefficient over ALL candidates")
+ ax2.set_title(
+ "Correlation coefficient over candidates with accuracy > {:}%".format(acc_bar)
+ )
+ save_path = (vis_save_dir / "{:}-all-relative-rank.png".format(indicator)).resolve()
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="png")
+ print("{:} save into {:}".format(time_string(), save_path))
+ plt.close("all")
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(
+ description="NATS-Bench", formatter_class=argparse.ArgumentDefaultsHelpFormatter
+ )
+ parser.add_argument(
+ "--save_dir",
+ type=str,
+ default="output/vis-nas-bench",
+ help="Folder to save checkpoints and log.",
+ )
+ # use for train the model
+ args = parser.parse_args()
+
+ to_save_dir = Path(args.save_dir)
+
+ datasets = ["cifar10", "cifar100", "ImageNet16-120"]
+ # Figure 3 (a-c)
+ api_tss = create(None, "tss", verbose=True)
+ for xdata in datasets:
+ visualize_tss_info(api_tss, xdata, to_save_dir)
+ # Figure 3 (d-f)
+ api_sss = create(None, "size", verbose=True)
+ for xdata in datasets:
+ visualize_sss_info(api_sss, xdata, to_save_dir)
+
+ # Figure 2
+ visualize_relative_info(None, to_save_dir, "tss")
+ visualize_relative_info(None, to_save_dir, "sss")
+
+ # Figure 4
+ visualize_rank_info(None, to_save_dir, "tss")
+ visualize_rank_info(None, to_save_dir, "sss")
+
+ # Figure 5
+ visualize_all_rank_info(None, to_save_dir, "tss")
+ visualize_all_rank_info(None, to_save_dir, "sss")
diff --git a/AutoDL-Projects/exps/NATS-Bench/draw-fig6.py b/AutoDL-Projects/exps/NATS-Bench/draw-fig6.py
new file mode 100644
index 0000000..10ef260
--- /dev/null
+++ b/AutoDL-Projects/exps/NATS-Bench/draw-fig6.py
@@ -0,0 +1,225 @@
+###############################################################
+# NATS-Bench (arxiv.org/pdf/2009.00437.pdf), IEEE TPAMI 2021 #
+# The code to draw Figure 6 in our paper. #
+###############################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020.06 #
+###############################################################
+# Usage: python exps/NATS-Bench/draw-fig6.py --search_space tss
+# Usage: python exps/NATS-Bench/draw-fig6.py --search_space sss
+###############################################################
+import os, gc, sys, time, torch, argparse
+import numpy as np
+from typing import List, Text, Dict, Any
+from shutil import copyfile
+from collections import defaultdict, OrderedDict
+from copy import deepcopy
+from pathlib import Path
+import matplotlib
+import seaborn as sns
+
+matplotlib.use("agg")
+import matplotlib.pyplot as plt
+import matplotlib.ticker as ticker
+
+from xautodl.config_utils import dict2config, load_config
+from xautodl.log_utils import time_string
+from nats_bench import create
+
+
+def fetch_data(root_dir="./output/search", search_space="tss", dataset=None):
+ ss_dir = "{:}-{:}".format(root_dir, search_space)
+ alg2name, alg2path = OrderedDict(), OrderedDict()
+ alg2name["REA"] = "R-EA-SS3"
+ alg2name["REINFORCE"] = "REINFORCE-0.01"
+ alg2name["RANDOM"] = "RANDOM"
+ alg2name["BOHB"] = "BOHB"
+ for alg, name in alg2name.items():
+ alg2path[alg] = os.path.join(ss_dir, dataset, name, "results.pth")
+ assert os.path.isfile(alg2path[alg]), "invalid path : {:}".format(alg2path[alg])
+ alg2data = OrderedDict()
+ for alg, path in alg2path.items():
+ data = torch.load(path)
+ for index, info in data.items():
+ info["time_w_arch"] = [
+ (x, y) for x, y in zip(info["all_total_times"], info["all_archs"])
+ ]
+ for j, arch in enumerate(info["all_archs"]):
+ assert arch != -1, "invalid arch from {:} {:} {:} ({:}, {:})".format(
+ alg, search_space, dataset, index, j
+ )
+ alg2data[alg] = data
+ return alg2data
+
+
+def query_performance(api, data, dataset, ticket):
+ results, is_size_space = [], api.search_space_name == "size"
+ for i, info in data.items():
+ time_w_arch = sorted(info["time_w_arch"], key=lambda x: abs(x[0] - ticket))
+ time_a, arch_a = time_w_arch[0]
+ time_b, arch_b = time_w_arch[1]
+ info_a = api.get_more_info(
+ arch_a, dataset=dataset, hp=90 if is_size_space else 200, is_random=False
+ )
+ info_b = api.get_more_info(
+ arch_b, dataset=dataset, hp=90 if is_size_space else 200, is_random=False
+ )
+ accuracy_a, accuracy_b = info_a["test-accuracy"], info_b["test-accuracy"]
+ interplate = (time_b - ticket) / (time_b - time_a) * accuracy_a + (
+ ticket - time_a
+ ) / (time_b - time_a) * accuracy_b
+ results.append(interplate)
+ # return sum(results) / len(results)
+ return np.mean(results), np.std(results)
+
+
+def show_valid_test(api, data, dataset):
+ valid_accs, test_accs, is_size_space = [], [], api.search_space_name == "size"
+ for i, info in data.items():
+ time, arch = info["time_w_arch"][-1]
+ if dataset == "cifar10":
+ xinfo = api.get_more_info(
+ arch, dataset=dataset, hp=90 if is_size_space else 200, is_random=False
+ )
+ test_accs.append(xinfo["test-accuracy"])
+ xinfo = api.get_more_info(
+ arch,
+ dataset="cifar10-valid",
+ hp=90 if is_size_space else 200,
+ is_random=False,
+ )
+ valid_accs.append(xinfo["valid-accuracy"])
+ else:
+ xinfo = api.get_more_info(
+ arch, dataset=dataset, hp=90 if is_size_space else 200, is_random=False
+ )
+ valid_accs.append(xinfo["valid-accuracy"])
+ test_accs.append(xinfo["test-accuracy"])
+ valid_str = "{:.2f}$\pm${:.2f}".format(np.mean(valid_accs), np.std(valid_accs))
+ test_str = "{:.2f}$\pm${:.2f}".format(np.mean(test_accs), np.std(test_accs))
+ return valid_str, test_str
+
+
+y_min_s = {
+ ("cifar10", "tss"): 90,
+ ("cifar10", "sss"): 92,
+ ("cifar100", "tss"): 65,
+ ("cifar100", "sss"): 65,
+ ("ImageNet16-120", "tss"): 36,
+ ("ImageNet16-120", "sss"): 40,
+}
+
+y_max_s = {
+ ("cifar10", "tss"): 94.3,
+ ("cifar10", "sss"): 93.3,
+ ("cifar100", "tss"): 72.5,
+ ("cifar100", "sss"): 70.5,
+ ("ImageNet16-120", "tss"): 46,
+ ("ImageNet16-120", "sss"): 46,
+}
+
+x_axis_s = {
+ ("cifar10", "tss"): 200,
+ ("cifar10", "sss"): 200,
+ ("cifar100", "tss"): 400,
+ ("cifar100", "sss"): 400,
+ ("ImageNet16-120", "tss"): 1200,
+ ("ImageNet16-120", "sss"): 600,
+}
+
+name2label = {
+ "cifar10": "CIFAR-10",
+ "cifar100": "CIFAR-100",
+ "ImageNet16-120": "ImageNet-16-120",
+}
+
+
+def visualize_curve(api, vis_save_dir, search_space):
+ vis_save_dir = vis_save_dir.resolve()
+ vis_save_dir.mkdir(parents=True, exist_ok=True)
+
+ dpi, width, height = 250, 5200, 1400
+ figsize = width / float(dpi), height / float(dpi)
+ LabelSize, LegendFontsize = 16, 16
+
+ def sub_plot_fn(ax, dataset):
+ xdataset, max_time = dataset.split("-T")
+ alg2data = fetch_data(search_space=search_space, dataset=dataset)
+ alg2accuracies = OrderedDict()
+ total_tickets = 150
+ time_tickets = [
+ float(i) / total_tickets * int(max_time) for i in range(total_tickets)
+ ]
+ colors = ["b", "g", "c", "m", "y"]
+ ax.set_xlim(0, x_axis_s[(xdataset, search_space)])
+ ax.set_ylim(
+ y_min_s[(xdataset, search_space)], y_max_s[(xdataset, search_space)]
+ )
+ for idx, (alg, data) in enumerate(alg2data.items()):
+ accuracies = []
+ for ticket in time_tickets:
+ accuracy, accuracy_std = query_performance(api, data, xdataset, ticket)
+ accuracies.append(accuracy)
+ valid_str, test_str = show_valid_test(api, data, xdataset)
+ # print('{:} plot alg : {:10s}, final accuracy = {:.2f}$\pm${:.2f}'.format(time_string(), alg, accuracy, accuracy_std))
+ print(
+ "{:} plot alg : {:10s} | validation = {:} | test = {:}".format(
+ time_string(), alg, valid_str, test_str
+ )
+ )
+ alg2accuracies[alg] = accuracies
+ ax.plot(
+ [x / 100 for x in time_tickets],
+ accuracies,
+ c=colors[idx],
+ label="{:}".format(alg),
+ )
+ ax.set_xlabel("Estimated wall-clock time (1e2 seconds)", fontsize=LabelSize)
+ ax.set_ylabel(
+ "Test accuracy on {:}".format(name2label[xdataset]), fontsize=LabelSize
+ )
+ ax.set_title(
+ "Searching results on {:}".format(name2label[xdataset]),
+ fontsize=LabelSize + 4,
+ )
+ ax.legend(loc=4, fontsize=LegendFontsize)
+
+ fig, axs = plt.subplots(1, 3, figsize=figsize)
+ # datasets = ['cifar10', 'cifar100', 'ImageNet16-120']
+ if search_space == "tss":
+ datasets = ["cifar10-T20000", "cifar100-T40000", "ImageNet16-120-T120000"]
+ elif search_space == "sss":
+ datasets = ["cifar10-T20000", "cifar100-T40000", "ImageNet16-120-T60000"]
+ else:
+ raise ValueError("Unknown search space: {:}".format(search_space))
+ for dataset, ax in zip(datasets, axs):
+ sub_plot_fn(ax, dataset)
+ print("sub-plot {:} on {:} done.".format(dataset, search_space))
+ save_path = (vis_save_dir / "{:}-curve.png".format(search_space)).resolve()
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="png")
+ print("{:} save into {:}".format(time_string(), save_path))
+ plt.close("all")
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(
+ description="NATS-Bench: Benchmarking NAS Algorithms for Architecture Topology and Size",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ )
+ parser.add_argument(
+ "--save_dir",
+ type=str,
+ default="output/vis-nas-bench/nas-algos",
+ help="Folder to save checkpoints and log.",
+ )
+ parser.add_argument(
+ "--search_space",
+ type=str,
+ choices=["tss", "sss"],
+ help="Choose the search space.",
+ )
+ args = parser.parse_args()
+
+ save_dir = Path(args.save_dir)
+
+ api = create(None, args.search_space, fast_mode=True, verbose=False)
+ visualize_curve(api, save_dir, args.search_space)
diff --git a/AutoDL-Projects/exps/NATS-Bench/draw-fig7.py b/AutoDL-Projects/exps/NATS-Bench/draw-fig7.py
new file mode 100644
index 0000000..e156af9
--- /dev/null
+++ b/AutoDL-Projects/exps/NATS-Bench/draw-fig7.py
@@ -0,0 +1,250 @@
+###############################################################
+# NATS-Bench (arxiv.org/pdf/2009.00437.pdf), IEEE TPAMI 2021 #
+# The code to draw Figure 7 in our paper. #
+###############################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020.06 #
+###############################################################
+# Usage: python exps/NATS-Bench/draw-fig7.py #
+###############################################################
+import os, gc, sys, time, torch, argparse
+import numpy as np
+from typing import List, Text, Dict, Any
+from shutil import copyfile
+from collections import defaultdict, OrderedDict
+from copy import deepcopy
+from pathlib import Path
+import matplotlib
+import seaborn as sns
+
+matplotlib.use("agg")
+import matplotlib.pyplot as plt
+import matplotlib.ticker as ticker
+
+from xautodl.config_utils import dict2config, load_config
+from xautodl.log_utils import time_string
+from nats_bench import create
+
+
+def get_valid_test_acc(api, arch, dataset):
+ is_size_space = api.search_space_name == "size"
+ if dataset == "cifar10":
+ xinfo = api.get_more_info(
+ arch, dataset=dataset, hp=90 if is_size_space else 200, is_random=False
+ )
+ test_acc = xinfo["test-accuracy"]
+ xinfo = api.get_more_info(
+ arch,
+ dataset="cifar10-valid",
+ hp=90 if is_size_space else 200,
+ is_random=False,
+ )
+ valid_acc = xinfo["valid-accuracy"]
+ else:
+ xinfo = api.get_more_info(
+ arch, dataset=dataset, hp=90 if is_size_space else 200, is_random=False
+ )
+ valid_acc = xinfo["valid-accuracy"]
+ test_acc = xinfo["test-accuracy"]
+ return (
+ valid_acc,
+ test_acc,
+ "validation = {:.2f}, test = {:.2f}\n".format(valid_acc, test_acc),
+ )
+
+
+def fetch_data(
+ root_dir="./output/search", search_space="tss", dataset=None, suffix="-WARM0.3"
+):
+ ss_dir = "{:}-{:}".format(root_dir, search_space)
+ alg2name, alg2path = OrderedDict(), OrderedDict()
+ seeds = [777, 888, 999]
+ print("\n[fetch data] from {:} on {:}".format(search_space, dataset))
+ if search_space == "tss":
+ alg2name["GDAS"] = "gdas-affine0_BN0-None"
+ alg2name["RSPS"] = "random-affine0_BN0-None"
+ alg2name["DARTS (1st)"] = "darts-v1-affine0_BN0-None"
+ alg2name["DARTS (2nd)"] = "darts-v2-affine0_BN0-None"
+ alg2name["ENAS"] = "enas-affine0_BN0-None"
+ alg2name["SETN"] = "setn-affine0_BN0-None"
+ else:
+ alg2name["channel-wise interpolation"] = "tas-affine0_BN0-AWD0.001{:}".format(
+ suffix
+ )
+ alg2name[
+ "masking + Gumbel-Softmax"
+ ] = "mask_gumbel-affine0_BN0-AWD0.001{:}".format(suffix)
+ alg2name["masking + sampling"] = "mask_rl-affine0_BN0-AWD0.0{:}".format(suffix)
+ for alg, name in alg2name.items():
+ alg2path[alg] = os.path.join(ss_dir, dataset, name, "seed-{:}-last-info.pth")
+ alg2data = OrderedDict()
+ for alg, path in alg2path.items():
+ alg2data[alg], ok_num = [], 0
+ for seed in seeds:
+ xpath = path.format(seed)
+ if os.path.isfile(xpath):
+ ok_num += 1
+ else:
+ print("This is an invalid path : {:}".format(xpath))
+ continue
+ data = torch.load(xpath, map_location=torch.device("cpu"))
+ try:
+ data = torch.load(
+ data["last_checkpoint"], map_location=torch.device("cpu")
+ )
+ except:
+ xpath = str(data["last_checkpoint"]).split("E100-")
+ if len(xpath) == 2 and os.path.isfile(xpath[0] + xpath[1]):
+ xpath = xpath[0] + xpath[1]
+ elif "fbv2" in str(data["last_checkpoint"]):
+ xpath = str(data["last_checkpoint"]).replace("fbv2", "mask_gumbel")
+ elif "tunas" in str(data["last_checkpoint"]):
+ xpath = str(data["last_checkpoint"]).replace("tunas", "mask_rl")
+ else:
+ raise ValueError(
+ "Invalid path: {:}".format(data["last_checkpoint"])
+ )
+ data = torch.load(xpath, map_location=torch.device("cpu"))
+ alg2data[alg].append(data["genotypes"])
+ print("This algorithm : {:} has {:} valid ckps.".format(alg, ok_num))
+ assert ok_num > 0, "Must have at least 1 valid ckps."
+ return alg2data
+
+
+y_min_s = {
+ ("cifar10", "tss"): 90,
+ ("cifar10", "sss"): 92,
+ ("cifar100", "tss"): 65,
+ ("cifar100", "sss"): 65,
+ ("ImageNet16-120", "tss"): 36,
+ ("ImageNet16-120", "sss"): 40,
+}
+
+y_max_s = {
+ ("cifar10", "tss"): 94.5,
+ ("cifar10", "sss"): 93.3,
+ ("cifar100", "tss"): 72,
+ ("cifar100", "sss"): 70,
+ ("ImageNet16-120", "tss"): 44,
+ ("ImageNet16-120", "sss"): 46,
+}
+
+name2label = {
+ "cifar10": "CIFAR-10",
+ "cifar100": "CIFAR-100",
+ "ImageNet16-120": "ImageNet-16-120",
+}
+
+name2suffix = {
+ ("sss", "warm"): "-WARM0.3",
+ ("sss", "none"): "-WARMNone",
+ ("tss", "none"): None,
+ ("tss", None): None,
+}
+
+
+def visualize_curve(api, vis_save_dir, search_space, suffix):
+ vis_save_dir = vis_save_dir.resolve()
+ vis_save_dir.mkdir(parents=True, exist_ok=True)
+
+ dpi, width, height = 250, 5200, 1400
+ figsize = width / float(dpi), height / float(dpi)
+ LabelSize, LegendFontsize = 16, 16
+
+ def sub_plot_fn(ax, dataset):
+ print("{:} plot {:10s}".format(time_string(), dataset))
+ alg2data = fetch_data(
+ search_space=search_space,
+ dataset=dataset,
+ suffix=name2suffix[(search_space, suffix)],
+ )
+ alg2accuracies = OrderedDict()
+ epochs = 100
+ colors = ["b", "g", "c", "m", "y", "r"]
+ ax.set_xlim(0, epochs)
+ # ax.set_ylim(y_min_s[(dataset, search_space)], y_max_s[(dataset, search_space)])
+ for idx, (alg, data) in enumerate(alg2data.items()):
+ xs, accuracies = [], []
+ for iepoch in range(epochs + 1):
+ try:
+ structures, accs = [_[iepoch - 1] for _ in data], []
+ except:
+ raise ValueError(
+ "This alg {:} on {:} has invalid checkpoints.".format(
+ alg, dataset
+ )
+ )
+ for structure in structures:
+ info = api.get_more_info(
+ structure,
+ dataset=dataset,
+ hp=90 if api.search_space_name == "size" else 200,
+ is_random=False,
+ )
+ accs.append(info["test-accuracy"])
+ accuracies.append(sum(accs) / len(accs))
+ xs.append(iepoch)
+ alg2accuracies[alg] = accuracies
+ ax.plot(xs, accuracies, c=colors[idx], label="{:}".format(alg))
+ ax.set_xlabel("The searching epoch", fontsize=LabelSize)
+ ax.set_ylabel(
+ "Test accuracy on {:}".format(name2label[dataset]), fontsize=LabelSize
+ )
+ ax.set_title(
+ "Searching results on {:}".format(name2label[dataset]),
+ fontsize=LabelSize + 4,
+ )
+ structures, valid_accs, test_accs = [_[epochs - 1] for _ in data], [], []
+ print(
+ "{:} plot alg : {:} -- final {:} architectures.".format(
+ time_string(), alg, len(structures)
+ )
+ )
+ for arch in structures:
+ valid_acc, test_acc, _ = get_valid_test_acc(api, arch, dataset)
+ test_accs.append(test_acc)
+ valid_accs.append(valid_acc)
+ print(
+ "{:} plot alg : {:} -- validation: {:.2f}$\pm${:.2f} -- test: {:.2f}$\pm${:.2f}".format(
+ time_string(),
+ alg,
+ np.mean(valid_accs),
+ np.std(valid_accs),
+ np.mean(test_accs),
+ np.std(test_accs),
+ )
+ )
+ ax.legend(loc=4, fontsize=LegendFontsize)
+
+ fig, axs = plt.subplots(1, 3, figsize=figsize)
+ datasets = ["cifar10", "cifar100", "ImageNet16-120"]
+ for dataset, ax in zip(datasets, axs):
+ sub_plot_fn(ax, dataset)
+ print("sub-plot {:} on {:} done.".format(dataset, search_space))
+ save_path = (
+ vis_save_dir / "{:}-ws-{:}-curve.png".format(search_space, suffix)
+ ).resolve()
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="png")
+ print("{:} save into {:}".format(time_string(), save_path))
+ plt.close("all")
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(
+ description="NATS-Bench", formatter_class=argparse.ArgumentDefaultsHelpFormatter
+ )
+ parser.add_argument(
+ "--save_dir",
+ type=str,
+ default="output/vis-nas-bench/nas-algos",
+ help="Folder to save checkpoints and log.",
+ )
+ args = parser.parse_args()
+
+ save_dir = Path(args.save_dir)
+
+ api_tss = create(None, "tss", fast_mode=True, verbose=False)
+ visualize_curve(api_tss, save_dir, "tss", None)
+
+ api_sss = create(None, "sss", fast_mode=True, verbose=False)
+ visualize_curve(api_sss, save_dir, "sss", "warm")
+ visualize_curve(api_sss, save_dir, "sss", "none")
diff --git a/AutoDL-Projects/exps/NATS-Bench/draw-fig8.py b/AutoDL-Projects/exps/NATS-Bench/draw-fig8.py
new file mode 100644
index 0000000..f8b4011
--- /dev/null
+++ b/AutoDL-Projects/exps/NATS-Bench/draw-fig8.py
@@ -0,0 +1,232 @@
+###############################################################
+# NATS-Bench (arxiv.org/pdf/2009.00437.pdf), IEEE TPAMI 2021 #
+# The code to draw Figure 6 in our paper. #
+###############################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020.06 #
+###############################################################
+# Usage: python exps/NATS-Bench/draw-fig8.py #
+###############################################################
+import os, gc, sys, time, torch, argparse
+import numpy as np
+from typing import List, Text, Dict, Any
+from shutil import copyfile
+from collections import defaultdict, OrderedDict
+from copy import deepcopy
+from pathlib import Path
+import matplotlib
+import seaborn as sns
+
+matplotlib.use("agg")
+import matplotlib.pyplot as plt
+import matplotlib.ticker as ticker
+
+from xautodl.config_utils import dict2config, load_config
+from xautodl.log_utils import time_string
+from nats_bench import create
+
+
+plt.rcParams.update(
+ {"text.usetex": True, "font.family": "sans-serif", "font.sans-serif": ["Helvetica"]}
+)
+## for Palatino and other serif fonts use:
+plt.rcParams.update(
+ {
+ "text.usetex": True,
+ "font.family": "serif",
+ "font.serif": ["Palatino"],
+ }
+)
+
+
+def fetch_data(root_dir="./output/search", search_space="tss", dataset=None):
+ ss_dir = "{:}-{:}".format(root_dir, search_space)
+ alg2all = OrderedDict()
+ # alg2name['REINFORCE'] = 'REINFORCE-0.01'
+ # alg2name['RANDOM'] = 'RANDOM'
+ # alg2name['BOHB'] = 'BOHB'
+ if search_space == "tss":
+ hp = "$\mathcal{H}^{1}$"
+ if dataset == "cifar10":
+ suffixes = ["-T1200000", "-T1200000-FULL"]
+ elif search_space == "sss":
+ hp = "$\mathcal{H}^{2}$"
+ if dataset == "cifar10":
+ suffixes = ["-T200000", "-T200000-FULL"]
+ else:
+ raise ValueError("Unkonwn search space: {:}".format(search_space))
+
+ alg2all[r"REA ($\mathcal{H}^{0}$)"] = dict(
+ path=os.path.join(ss_dir, dataset + suffixes[0], "R-EA-SS3", "results.pth"),
+ color="b",
+ linestyle="-",
+ )
+ alg2all[r"REA ({:})".format(hp)] = dict(
+ path=os.path.join(ss_dir, dataset + suffixes[1], "R-EA-SS3", "results.pth"),
+ color="b",
+ linestyle="--",
+ )
+
+ for alg, xdata in alg2all.items():
+ data = torch.load(xdata["path"])
+ for index, info in data.items():
+ info["time_w_arch"] = [
+ (x, y) for x, y in zip(info["all_total_times"], info["all_archs"])
+ ]
+ for j, arch in enumerate(info["all_archs"]):
+ assert arch != -1, "invalid arch from {:} {:} {:} ({:}, {:})".format(
+ alg, search_space, dataset, index, j
+ )
+ xdata["data"] = data
+ return alg2all
+
+
+def query_performance(api, data, dataset, ticket):
+ results, is_size_space = [], api.search_space_name == "size"
+ for i, info in data.items():
+ time_w_arch = sorted(info["time_w_arch"], key=lambda x: abs(x[0] - ticket))
+ time_a, arch_a = time_w_arch[0]
+ time_b, arch_b = time_w_arch[1]
+ info_a = api.get_more_info(
+ arch_a, dataset=dataset, hp=90 if is_size_space else 200, is_random=False
+ )
+ info_b = api.get_more_info(
+ arch_b, dataset=dataset, hp=90 if is_size_space else 200, is_random=False
+ )
+ accuracy_a, accuracy_b = info_a["test-accuracy"], info_b["test-accuracy"]
+ interplate = (time_b - ticket) / (time_b - time_a) * accuracy_a + (
+ ticket - time_a
+ ) / (time_b - time_a) * accuracy_b
+ results.append(interplate)
+ # return sum(results) / len(results)
+ return np.mean(results), np.std(results)
+
+
+y_min_s = {
+ ("cifar10", "tss"): 91,
+ ("cifar10", "sss"): 91,
+ ("cifar100", "tss"): 65,
+ ("cifar100", "sss"): 65,
+ ("ImageNet16-120", "tss"): 36,
+ ("ImageNet16-120", "sss"): 40,
+}
+
+y_max_s = {
+ ("cifar10", "tss"): 94.5,
+ ("cifar10", "sss"): 93.5,
+ ("cifar100", "tss"): 72.5,
+ ("cifar100", "sss"): 70.5,
+ ("ImageNet16-120", "tss"): 46,
+ ("ImageNet16-120", "sss"): 46,
+}
+
+x_axis_s = {
+ ("cifar10", "tss"): 1200000,
+ ("cifar10", "sss"): 200000,
+ ("cifar100", "tss"): 400,
+ ("cifar100", "sss"): 400,
+ ("ImageNet16-120", "tss"): 1200,
+ ("ImageNet16-120", "sss"): 600,
+}
+
+name2label = {
+ "cifar10": "CIFAR-10",
+ "cifar100": "CIFAR-100",
+ "ImageNet16-120": "ImageNet-16-120",
+}
+
+spaces2latex = {
+ "tss": r"$\mathcal{S}_{t}$",
+ "sss": r"$\mathcal{S}_{s}$",
+}
+
+
+# FuncFormatter can be used as a decorator
+@ticker.FuncFormatter
+def major_formatter(x, pos):
+ if x == 0:
+ return "0"
+ else:
+ return "{:.2f}e5".format(x / 1e5)
+
+
+def visualize_curve(api_dict, vis_save_dir):
+ vis_save_dir = vis_save_dir.resolve()
+ vis_save_dir.mkdir(parents=True, exist_ok=True)
+
+ dpi, width, height = 250, 5000, 2000
+ figsize = width / float(dpi), height / float(dpi)
+ LabelSize, LegendFontsize = 28, 28
+
+ def sub_plot_fn(ax, search_space, dataset):
+ max_time = x_axis_s[(dataset, search_space)]
+ alg2data = fetch_data(search_space=search_space, dataset=dataset)
+ alg2accuracies = OrderedDict()
+ total_tickets = 200
+ time_tickets = [
+ float(i) / total_tickets * int(max_time) for i in range(total_tickets)
+ ]
+ ax.set_xlim(0, x_axis_s[(dataset, search_space)])
+ ax.set_ylim(y_min_s[(dataset, search_space)], y_max_s[(dataset, search_space)])
+ for tick in ax.get_xticklabels():
+ tick.set_rotation(25)
+ tick.set_fontsize(LabelSize - 6)
+ for tick in ax.get_yticklabels():
+ tick.set_fontsize(LabelSize - 6)
+ ax.xaxis.set_major_formatter(major_formatter)
+ for idx, (alg, xdata) in enumerate(alg2data.items()):
+ accuracies = []
+ for ticket in time_tickets:
+ # import pdb; pdb.set_trace()
+ accuracy, accuracy_std = query_performance(
+ api_dict[search_space], xdata["data"], dataset, ticket
+ )
+ accuracies.append(accuracy)
+ # print('{:} plot alg : {:10s}, final accuracy = {:.2f}$\pm${:.2f}'.format(time_string(), alg, accuracy, accuracy_std))
+ print(
+ "{:} plot alg : {:10s} on {:}".format(time_string(), alg, search_space)
+ )
+ alg2accuracies[alg] = accuracies
+ ax.plot(
+ time_tickets,
+ accuracies,
+ c=xdata["color"],
+ linestyle=xdata["linestyle"],
+ label="{:}".format(alg),
+ )
+ ax.set_xlabel("Estimated wall-clock time", fontsize=LabelSize)
+ ax.set_ylabel("Test accuracy", fontsize=LabelSize)
+ ax.set_title(
+ r"Results on {:} over {:}".format(
+ name2label[dataset], spaces2latex[search_space]
+ ),
+ fontsize=LabelSize,
+ )
+ ax.legend(loc=4, fontsize=LegendFontsize)
+
+ fig, axs = plt.subplots(1, 2, figsize=figsize)
+ sub_plot_fn(axs[0], "tss", "cifar10")
+ sub_plot_fn(axs[1], "sss", "cifar10")
+ save_path = (vis_save_dir / "full-curve.png").resolve()
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="png")
+ print("{:} save into {:}".format(time_string(), save_path))
+ plt.close("all")
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(
+ description="NATS-Bench: Benchmarking NAS Algorithms for Architecture Topology and Size",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ )
+ parser.add_argument(
+ "--save_dir",
+ type=str,
+ default="output/vis-nas-bench/nas-algos-vs-h",
+ help="Folder to save checkpoints and log.",
+ )
+ args = parser.parse_args()
+
+ save_dir = Path(args.save_dir)
+
+ api_tss = create(None, "tss", fast_mode=True, verbose=False)
+ api_sss = create(None, "sss", fast_mode=True, verbose=False)
+ visualize_curve(dict(tss=api_tss, sss=api_sss), save_dir)
diff --git a/AutoDL-Projects/exps/NATS-Bench/draw-ranks.py b/AutoDL-Projects/exps/NATS-Bench/draw-ranks.py
new file mode 100644
index 0000000..1ce9f75
--- /dev/null
+++ b/AutoDL-Projects/exps/NATS-Bench/draw-ranks.py
@@ -0,0 +1,185 @@
+###############################################################
+# NATS-Bench (arxiv.org/pdf/2009.00437.pdf), IEEE TPAMI 2021 #
+# The code to draw Figure 2 / 3 / 4 / 5 in our paper. #
+###############################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020.06 #
+###############################################################
+# Usage: python exps/NATS-Bench/draw-ranks.py #
+###############################################################
+import os, sys, time, torch, argparse
+import scipy
+import numpy as np
+from typing import List, Text, Dict, Any
+from shutil import copyfile
+from collections import defaultdict, OrderedDict
+from copy import deepcopy
+from pathlib import Path
+import matplotlib
+import seaborn as sns
+
+matplotlib.use("agg")
+import matplotlib.pyplot as plt
+import matplotlib.ticker as ticker
+
+from xautodl.config_utils import dict2config, load_config
+from xautodl.log_utils import time_string
+from xautodl.models import get_cell_based_tiny_net
+from nats_bench import create
+
+
+name2label = {
+ "cifar10": "CIFAR-10",
+ "cifar100": "CIFAR-100",
+ "ImageNet16-120": "ImageNet-16-120",
+}
+
+
+def visualize_relative_info(vis_save_dir, search_space, indicator, topk):
+ vis_save_dir = vis_save_dir.resolve()
+ print(
+ "{:} start to visualize {:} with top-{:} information".format(
+ time_string(), search_space, topk
+ )
+ )
+ vis_save_dir.mkdir(parents=True, exist_ok=True)
+ cache_file_path = vis_save_dir / "cache-{:}-info.pth".format(search_space)
+ datasets = ["cifar10", "cifar100", "ImageNet16-120"]
+ if not cache_file_path.exists():
+ api = create(None, search_space, fast_mode=False, verbose=False)
+ all_infos = OrderedDict()
+ for index in range(len(api)):
+ all_info = OrderedDict()
+ for dataset in datasets:
+ info_less = api.get_more_info(index, dataset, hp="12", is_random=False)
+ info_more = api.get_more_info(
+ index, dataset, hp=api.full_train_epochs, is_random=False
+ )
+ all_info[dataset] = dict(
+ less=info_less["test-accuracy"], more=info_more["test-accuracy"]
+ )
+ all_infos[index] = all_info
+ torch.save(all_infos, cache_file_path)
+ print("{:} save all cache data into {:}".format(time_string(), cache_file_path))
+ else:
+ api = create(None, search_space, fast_mode=True, verbose=False)
+ all_infos = torch.load(cache_file_path)
+
+ dpi, width, height = 250, 5000, 1300
+ figsize = width / float(dpi), height / float(dpi)
+ LabelSize, LegendFontsize = 16, 16
+
+ fig, axs = plt.subplots(1, 3, figsize=figsize)
+ datasets = ["cifar10", "cifar100", "ImageNet16-120"]
+
+ def sub_plot_fn(ax, dataset, indicator):
+ performances = []
+ # pickup top 10% architectures
+ for _index in range(len(api)):
+ performances.append((all_infos[_index][dataset][indicator], _index))
+ performances = sorted(performances, reverse=True)
+ performances = performances[: int(len(api) * topk * 0.01)]
+ selected_indexes = [x[1] for x in performances]
+ print(
+ "{:} plot {:10s} with {:}, {:} architectures".format(
+ time_string(), dataset, indicator, len(selected_indexes)
+ )
+ )
+ standard_scores = []
+ random_scores = []
+ for idx in selected_indexes:
+ standard_scores.append(
+ api.get_more_info(
+ idx,
+ dataset,
+ hp=api.full_train_epochs if indicator == "more" else "12",
+ is_random=False,
+ )["test-accuracy"]
+ )
+ random_scores.append(
+ api.get_more_info(
+ idx,
+ dataset,
+ hp=api.full_train_epochs if indicator == "more" else "12",
+ is_random=True,
+ )["test-accuracy"]
+ )
+ indexes = list(range(len(selected_indexes)))
+ standard_indexes = sorted(indexes, key=lambda i: standard_scores[i])
+ random_indexes = sorted(indexes, key=lambda i: random_scores[i])
+ random_labels = []
+ for idx in standard_indexes:
+ random_labels.append(random_indexes.index(idx))
+ for tick in ax.get_xticklabels():
+ tick.set_fontsize(LabelSize - 3)
+ for tick in ax.get_yticklabels():
+ tick.set_rotation(25)
+ tick.set_fontsize(LabelSize - 3)
+ ax.set_xlim(0, len(indexes))
+ ax.set_ylim(0, len(indexes))
+ ax.set_yticks(np.arange(min(indexes), max(indexes), max(indexes) // 3))
+ ax.set_xticks(np.arange(min(indexes), max(indexes), max(indexes) // 5))
+ ax.scatter(indexes, random_labels, marker="^", s=0.5, c="tab:green", alpha=0.8)
+ ax.scatter(indexes, indexes, marker="o", s=0.5, c="tab:blue", alpha=0.8)
+ ax.scatter(
+ [-1],
+ [-1],
+ marker="o",
+ s=100,
+ c="tab:blue",
+ label="Average Over Multi-Trials",
+ )
+ ax.scatter(
+ [-1],
+ [-1],
+ marker="^",
+ s=100,
+ c="tab:green",
+ label="Randomly Selected Trial",
+ )
+
+ coef, p = scipy.stats.kendalltau(standard_scores, random_scores)
+ ax.set_xlabel(
+ "architecture ranking in {:}".format(name2label[dataset]),
+ fontsize=LabelSize,
+ )
+ if dataset == "cifar10":
+ ax.set_ylabel("architecture ranking", fontsize=LabelSize)
+ ax.legend(loc=4, fontsize=LegendFontsize)
+ return coef
+
+ for dataset, ax in zip(datasets, axs):
+ rank_coef = sub_plot_fn(ax, dataset, indicator)
+ print(
+ "sub-plot {:} on {:} done, the ranking coefficient is {:.4f}.".format(
+ dataset, search_space, rank_coef
+ )
+ )
+
+ save_path = (
+ vis_save_dir / "{:}-rank-{:}-top{:}.pdf".format(search_space, indicator, topk)
+ ).resolve()
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="pdf")
+ save_path = (
+ vis_save_dir / "{:}-rank-{:}-top{:}.png".format(search_space, indicator, topk)
+ ).resolve()
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="png")
+ print("Save into {:}".format(save_path))
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(
+ description="NATS-Bench", formatter_class=argparse.ArgumentDefaultsHelpFormatter
+ )
+ parser.add_argument(
+ "--save_dir",
+ type=str,
+ default="output/vis-nas-bench/rank-stability",
+ help="Folder to save checkpoints and log.",
+ )
+ args = parser.parse_args()
+ to_save_dir = Path(args.save_dir)
+
+ for topk in [1, 5, 10, 20]:
+ visualize_relative_info(to_save_dir, "tss", "more", topk)
+ visualize_relative_info(to_save_dir, "sss", "less", topk)
+ print("{:} : complete running this file : {:}".format(time_string(), __file__))
diff --git a/AutoDL-Projects/exps/NATS-Bench/draw-table.py b/AutoDL-Projects/exps/NATS-Bench/draw-table.py
new file mode 100644
index 0000000..34c7467
--- /dev/null
+++ b/AutoDL-Projects/exps/NATS-Bench/draw-table.py
@@ -0,0 +1,191 @@
+###############################################################
+# NATS-Bench (arxiv.org/pdf/2009.00437.pdf), IEEE TPAMI 2021 #
+# The code to draw some results in Table 4 in our paper. #
+###############################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020.06 #
+###############################################################
+# Usage: python exps/NATS-Bench/draw-table.py #
+###############################################################
+import os, gc, sys, time, torch, argparse
+import numpy as np
+from typing import List, Text, Dict, Any
+from shutil import copyfile
+from collections import defaultdict, OrderedDict
+from copy import deepcopy
+from pathlib import Path
+import matplotlib
+import seaborn as sns
+
+matplotlib.use("agg")
+import matplotlib.pyplot as plt
+import matplotlib.ticker as ticker
+
+from xautodl.config_utils import dict2config, load_config
+from xautodl.log_utils import time_string
+from nats_bench import create
+
+
+def fetch_data(root_dir="./output/search", search_space="tss", dataset=None):
+ ss_dir = "{:}-{:}".format(root_dir, search_space)
+ alg2name, alg2path = OrderedDict(), OrderedDict()
+ alg2name["REA"] = "R-EA-SS3"
+ alg2name["REINFORCE"] = "REINFORCE-0.01"
+ alg2name["RANDOM"] = "RANDOM"
+ alg2name["BOHB"] = "BOHB"
+ for alg, name in alg2name.items():
+ alg2path[alg] = os.path.join(ss_dir, dataset, name, "results.pth")
+ assert os.path.isfile(alg2path[alg]), "invalid path : {:}".format(alg2path[alg])
+ alg2data = OrderedDict()
+ for alg, path in alg2path.items():
+ data = torch.load(path)
+ for index, info in data.items():
+ info["time_w_arch"] = [
+ (x, y) for x, y in zip(info["all_total_times"], info["all_archs"])
+ ]
+ for j, arch in enumerate(info["all_archs"]):
+ assert arch != -1, "invalid arch from {:} {:} {:} ({:}, {:})".format(
+ alg, search_space, dataset, index, j
+ )
+ alg2data[alg] = data
+ return alg2data
+
+
+def get_valid_test_acc(api, arch, dataset):
+ is_size_space = api.search_space_name == "size"
+ if dataset == "cifar10":
+ xinfo = api.get_more_info(
+ arch, dataset=dataset, hp=90 if is_size_space else 200, is_random=False
+ )
+ test_acc = xinfo["test-accuracy"]
+ xinfo = api.get_more_info(
+ arch,
+ dataset="cifar10-valid",
+ hp=90 if is_size_space else 200,
+ is_random=False,
+ )
+ valid_acc = xinfo["valid-accuracy"]
+ else:
+ xinfo = api.get_more_info(
+ arch, dataset=dataset, hp=90 if is_size_space else 200, is_random=False
+ )
+ valid_acc = xinfo["valid-accuracy"]
+ test_acc = xinfo["test-accuracy"]
+ return (
+ valid_acc,
+ test_acc,
+ "validation = {:.2f}, test = {:.2f}\n".format(valid_acc, test_acc),
+ )
+
+
+def show_valid_test(api, arch):
+ is_size_space = api.search_space_name == "size"
+ final_str = ""
+ for dataset in ["cifar10", "cifar100", "ImageNet16-120"]:
+ valid_acc, test_acc, perf_str = get_valid_test_acc(api, arch, dataset)
+ final_str += "{:} : {:}\n".format(dataset, perf_str)
+ return final_str
+
+
+def find_best_valid(api, dataset):
+ all_valid_accs, all_test_accs = [], []
+ for index, arch in enumerate(api):
+ valid_acc, test_acc, perf_str = get_valid_test_acc(api, index, dataset)
+ all_valid_accs.append((index, valid_acc))
+ all_test_accs.append((index, test_acc))
+ best_valid_index = sorted(all_valid_accs, key=lambda x: -x[1])[0][0]
+ best_test_index = sorted(all_test_accs, key=lambda x: -x[1])[0][0]
+
+ print("-" * 50 + "{:10s}".format(dataset) + "-" * 50)
+ print(
+ "Best ({:}) architecture on validation: {:}".format(
+ best_valid_index, api[best_valid_index]
+ )
+ )
+ print(
+ "Best ({:}) architecture on test: {:}".format(
+ best_test_index, api[best_test_index]
+ )
+ )
+ _, _, perf_str = get_valid_test_acc(api, best_valid_index, dataset)
+ print("using validation ::: {:}".format(perf_str))
+ _, _, perf_str = get_valid_test_acc(api, best_test_index, dataset)
+ print("using test ::: {:}".format(perf_str))
+
+
+def interplate_fn(xpair1, xpair2, x):
+ (x1, y1) = xpair1
+ (x2, y2) = xpair2
+ return (x2 - x) / (x2 - x1) * y1 + (x - x1) / (x2 - x1) * y2
+
+
+def query_performance(api, info, dataset, ticket):
+ info = deepcopy(info)
+ results, is_size_space = [], api.search_space_name == "size"
+ time_w_arch = sorted(info["time_w_arch"], key=lambda x: abs(x[0] - ticket))
+ time_a, arch_a = time_w_arch[0]
+ time_b, arch_b = time_w_arch[1]
+
+ v_acc_a, t_acc_a, _ = get_valid_test_acc(api, arch_a, dataset)
+ v_acc_b, t_acc_b, _ = get_valid_test_acc(api, arch_b, dataset)
+ v_acc = interplate_fn((time_a, v_acc_a), (time_b, v_acc_b), ticket)
+ t_acc = interplate_fn((time_a, t_acc_a), (time_b, t_acc_b), ticket)
+ # if True:
+ # interplate = (time_b-ticket) / (time_b-time_a) * accuracy_a + (ticket-time_a) / (time_b-time_a) * accuracy_b
+ # results.append(interplate)
+ # return sum(results) / len(results)
+ return v_acc, t_acc
+
+
+def show_multi_trial(search_space):
+ api = create(None, search_space, fast_mode=True, verbose=False)
+
+ def show(dataset):
+ print("show {:} on {:} done.".format(dataset, search_space))
+ xdataset, max_time = dataset.split("-T")
+ alg2data = fetch_data(search_space=search_space, dataset=dataset)
+ for idx, (alg, data) in enumerate(alg2data.items()):
+
+ valid_accs, test_accs = [], []
+ for _, x in data.items():
+ v_acc, t_acc = query_performance(api, x, xdataset, float(max_time))
+ valid_accs.append(v_acc)
+ test_accs.append(t_acc)
+ valid_str = "{:.2f}$\pm${:.2f}".format(
+ np.mean(valid_accs), np.std(valid_accs)
+ )
+ test_str = "{:.2f}$\pm${:.2f}".format(np.mean(test_accs), np.std(test_accs))
+ print(
+ "{:} plot alg : {:10s} | validation = {:} | test = {:}".format(
+ time_string(), alg, valid_str, test_str
+ )
+ )
+
+ if search_space == "tss":
+ datasets = ["cifar10-T20000", "cifar100-T40000", "ImageNet16-120-T120000"]
+ elif search_space == "sss":
+ datasets = ["cifar10-T20000", "cifar100-T40000", "ImageNet16-120-T60000"]
+ else:
+ raise ValueError("Unknown search space: {:}".format(search_space))
+ for dataset in datasets:
+ show(dataset)
+ print("{:} complete show multi-trial results.\n".format(time_string()))
+
+
+if __name__ == "__main__":
+
+ show_multi_trial("tss")
+ show_multi_trial("sss")
+
+ api_tss = create(None, "tss", fast_mode=False, verbose=False)
+ resnet = "|nor_conv_3x3~0|+|none~0|nor_conv_3x3~1|+|skip_connect~0|none~1|skip_connect~2|"
+ resnet_index = api_tss.query_index_by_arch(resnet)
+ print(show_valid_test(api_tss, resnet_index))
+
+ for dataset in ["cifar10", "cifar100", "ImageNet16-120"]:
+ find_best_valid(api_tss, dataset)
+
+ largest = "64:64:64:64:64"
+ largest_index = api_sss.query_index_by_arch(largest)
+ print(show_valid_test(api_sss, largest_index))
+ for dataset in ["cifar10", "cifar100", "ImageNet16-120"]:
+ find_best_valid(api_sss, dataset)
diff --git a/AutoDL-Projects/exps/NATS-Bench/main-sss.py b/AutoDL-Projects/exps/NATS-Bench/main-sss.py
new file mode 100644
index 0000000..aac422f
--- /dev/null
+++ b/AutoDL-Projects/exps/NATS-Bench/main-sss.py
@@ -0,0 +1,486 @@
+##############################################################################
+# NATS-Bench: Benchmarking NAS Algorithms for Architecture Topology and Size #
+##############################################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020.07 #
+##############################################################################
+# This file is used to train (all) architecture candidate in the size search #
+# space in NATS-Bench (sss) with different hyper-parameters. #
+# When use mode=new, it will automatically detect whether the checkpoint of #
+# a trial exists, if so, it will skip this trial. When use mode=cover, it #
+# will ignore the (possible) existing checkpoint, run each trial, and save. #
+# (NOTE): the topology for all candidates in sss is fixed as: ######################
+# |nor_conv_3x3~0|+|nor_conv_3x3~0|nor_conv_3x3~1|+|skip_connect~0|nor_conv_3x3~1|nor_conv_3x3~2| #
+###################################################################################################
+# Please use the script of scripts/NATS-Bench/train-shapes.sh to run. #
+##############################################################################
+import os, sys, time, torch, argparse
+from typing import List, Text, Dict, Any
+from PIL import ImageFile
+
+ImageFile.LOAD_TRUNCATED_IMAGES = True
+from copy import deepcopy
+from pathlib import Path
+
+from xautodl.config_utils import dict2config, load_config
+from xautodl.procedures import bench_evaluate_for_seed
+from xautodl.procedures import get_machine_info
+from xautodl.datasets import get_datasets
+from xautodl.log_utils import Logger, AverageMeter, time_string, convert_secs2time
+from xautodl.utils import split_str2indexes
+
+
+def evaluate_all_datasets(
+ channels: Text,
+ datasets: List[Text],
+ xpaths: List[Text],
+ splits: List[Text],
+ config_path: Text,
+ seed: int,
+ workers: int,
+ logger,
+):
+ machine_info = get_machine_info()
+ all_infos = {"info": machine_info}
+ all_dataset_keys = []
+ # look all the dataset
+ for dataset, xpath, split in zip(datasets, xpaths, splits):
+ # the train and valid data
+ train_data, valid_data, xshape, class_num = get_datasets(dataset, xpath, -1)
+ # load the configuration
+ if dataset == "cifar10" or dataset == "cifar100":
+ split_info = load_config(
+ "configs/nas-benchmark/cifar-split.txt", None, None
+ )
+ elif dataset.startswith("ImageNet16"):
+ split_info = load_config(
+ "configs/nas-benchmark/{:}-split.txt".format(dataset), None, None
+ )
+ else:
+ raise ValueError("invalid dataset : {:}".format(dataset))
+ config = load_config(
+ config_path, dict(class_num=class_num, xshape=xshape), logger
+ )
+ # check whether use the splitted validation set
+ if bool(split):
+ assert dataset == "cifar10"
+ ValLoaders = {
+ "ori-test": torch.utils.data.DataLoader(
+ valid_data,
+ batch_size=config.batch_size,
+ shuffle=False,
+ num_workers=workers,
+ pin_memory=True,
+ )
+ }
+ assert len(train_data) == len(split_info.train) + len(
+ split_info.valid
+ ), "invalid length : {:} vs {:} + {:}".format(
+ len(train_data), len(split_info.train), len(split_info.valid)
+ )
+ train_data_v2 = deepcopy(train_data)
+ train_data_v2.transform = valid_data.transform
+ valid_data = train_data_v2
+ # data loader
+ train_loader = torch.utils.data.DataLoader(
+ train_data,
+ batch_size=config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(split_info.train),
+ num_workers=workers,
+ pin_memory=True,
+ )
+ valid_loader = torch.utils.data.DataLoader(
+ valid_data,
+ batch_size=config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(split_info.valid),
+ num_workers=workers,
+ pin_memory=True,
+ )
+ ValLoaders["x-valid"] = valid_loader
+ else:
+ # data loader
+ train_loader = torch.utils.data.DataLoader(
+ train_data,
+ batch_size=config.batch_size,
+ shuffle=True,
+ num_workers=workers,
+ pin_memory=True,
+ )
+ valid_loader = torch.utils.data.DataLoader(
+ valid_data,
+ batch_size=config.batch_size,
+ shuffle=False,
+ num_workers=workers,
+ pin_memory=True,
+ )
+ if dataset == "cifar10":
+ ValLoaders = {"ori-test": valid_loader}
+ elif dataset == "cifar100":
+ cifar100_splits = load_config(
+ "configs/nas-benchmark/cifar100-test-split.txt", None, None
+ )
+ ValLoaders = {
+ "ori-test": valid_loader,
+ "x-valid": torch.utils.data.DataLoader(
+ valid_data,
+ batch_size=config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(
+ cifar100_splits.xvalid
+ ),
+ num_workers=workers,
+ pin_memory=True,
+ ),
+ "x-test": torch.utils.data.DataLoader(
+ valid_data,
+ batch_size=config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(
+ cifar100_splits.xtest
+ ),
+ num_workers=workers,
+ pin_memory=True,
+ ),
+ }
+ elif dataset == "ImageNet16-120":
+ imagenet16_splits = load_config(
+ "configs/nas-benchmark/imagenet-16-120-test-split.txt", None, None
+ )
+ ValLoaders = {
+ "ori-test": valid_loader,
+ "x-valid": torch.utils.data.DataLoader(
+ valid_data,
+ batch_size=config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(
+ imagenet16_splits.xvalid
+ ),
+ num_workers=workers,
+ pin_memory=True,
+ ),
+ "x-test": torch.utils.data.DataLoader(
+ valid_data,
+ batch_size=config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(
+ imagenet16_splits.xtest
+ ),
+ num_workers=workers,
+ pin_memory=True,
+ ),
+ }
+ else:
+ raise ValueError("invalid dataset : {:}".format(dataset))
+
+ dataset_key = "{:}".format(dataset)
+ if bool(split):
+ dataset_key = dataset_key + "-valid"
+ logger.log(
+ "Evaluate ||||||| {:10s} ||||||| Train-Num={:}, Valid-Num={:}, Train-Loader-Num={:}, Valid-Loader-Num={:}, batch size={:}".format(
+ dataset_key,
+ len(train_data),
+ len(valid_data),
+ len(train_loader),
+ len(valid_loader),
+ config.batch_size,
+ )
+ )
+ logger.log(
+ "Evaluate ||||||| {:10s} ||||||| Config={:}".format(dataset_key, config)
+ )
+ for key, value in ValLoaders.items():
+ logger.log(
+ "Evaluate ---->>>> {:10s} with {:} batchs".format(key, len(value))
+ )
+ # arch-index= 9930, arch=|nor_conv_3x3~0|+|nor_conv_3x3~0|nor_conv_3x3~1|+|skip_connect~0|nor_conv_3x3~1|nor_conv_3x3~2|
+ # this genotype is the architecture with the highest accuracy on CIFAR-100 validation set
+ genotype = "|nor_conv_3x3~0|+|nor_conv_3x3~0|nor_conv_3x3~1|+|skip_connect~0|nor_conv_3x3~1|nor_conv_3x3~2|"
+ arch_config = dict2config(
+ dict(
+ name="infer.shape.tiny",
+ channels=channels,
+ genotype=genotype,
+ num_classes=class_num,
+ ),
+ None,
+ )
+ results = bench_evaluate_for_seed(
+ arch_config, config, train_loader, ValLoaders, seed, logger
+ )
+ all_infos[dataset_key] = results
+ all_dataset_keys.append(dataset_key)
+ all_infos["all_dataset_keys"] = all_dataset_keys
+ return all_infos
+
+
+def main(
+ save_dir: Path,
+ workers: int,
+ datasets: List[Text],
+ xpaths: List[Text],
+ splits: List[int],
+ seeds: List[int],
+ nets: List[str],
+ opt_config: Dict[Text, Any],
+ to_evaluate_indexes: tuple,
+ cover_mode: bool,
+):
+
+ log_dir = save_dir / "logs"
+ log_dir.mkdir(parents=True, exist_ok=True)
+ logger = Logger(str(log_dir), os.getpid(), False)
+
+ logger.log("xargs : seeds = {:}".format(seeds))
+ logger.log("xargs : cover_mode = {:}".format(cover_mode))
+ logger.log("-" * 100)
+ logger.log(
+ "Start evaluating range =: {:06d} - {:06d}".format(
+ min(to_evaluate_indexes), max(to_evaluate_indexes)
+ )
+ + "({:} in total) / {:06d} with cover-mode={:}".format(
+ len(to_evaluate_indexes), len(nets), cover_mode
+ )
+ )
+ for i, (dataset, xpath, split) in enumerate(zip(datasets, xpaths, splits)):
+ logger.log(
+ "--->>> Evaluate {:}/{:} : dataset={:9s}, path={:}, split={:}".format(
+ i, len(datasets), dataset, xpath, split
+ )
+ )
+ logger.log("--->>> optimization config : {:}".format(opt_config))
+
+ start_time, epoch_time = time.time(), AverageMeter()
+ for i, index in enumerate(to_evaluate_indexes):
+ channelstr = nets[index]
+ logger.log(
+ "\n{:} evaluate {:06d}/{:06d} ({:06d}/{:06d})-th arch [seeds={:}] {:}".format(
+ time_string(),
+ i,
+ len(to_evaluate_indexes),
+ index,
+ len(nets),
+ seeds,
+ "-" * 15,
+ )
+ )
+ logger.log("{:} {:} {:}".format("-" * 15, channelstr, "-" * 15))
+
+ # test this arch on different datasets with different seeds
+ has_continue = False
+ for seed in seeds:
+ to_save_name = save_dir / "arch-{:06d}-seed-{:04d}.pth".format(index, seed)
+ if to_save_name.exists():
+ if cover_mode:
+ logger.log(
+ "Find existing file : {:}, remove it before evaluation".format(
+ to_save_name
+ )
+ )
+ os.remove(str(to_save_name))
+ else:
+ logger.log(
+ "Find existing file : {:}, skip this evaluation".format(
+ to_save_name
+ )
+ )
+ has_continue = True
+ continue
+ results = evaluate_all_datasets(
+ channelstr, datasets, xpaths, splits, opt_config, seed, workers, logger
+ )
+ torch.save(results, to_save_name)
+ logger.log(
+ "\n{:} evaluate {:06d}/{:06d} ({:06d}/{:06d})-th arch [seeds={:}] ===>>> {:}".format(
+ time_string(),
+ i,
+ len(to_evaluate_indexes),
+ index,
+ len(nets),
+ seeds,
+ to_save_name,
+ )
+ )
+ # measure elapsed time
+ if not has_continue:
+ epoch_time.update(time.time() - start_time)
+ start_time = time.time()
+ need_time = "Time Left: {:}".format(
+ convert_secs2time(epoch_time.avg * (len(to_evaluate_indexes) - i - 1), True)
+ )
+ logger.log(
+ "This arch costs : {:}".format(convert_secs2time(epoch_time.val, True))
+ )
+ logger.log("{:}".format("*" * 100))
+ logger.log(
+ "{:} {:74s} {:}".format(
+ "*" * 10,
+ "{:06d}/{:06d} ({:06d}/{:06d})-th done, left {:}".format(
+ i, len(to_evaluate_indexes), index, len(nets), need_time
+ ),
+ "*" * 10,
+ )
+ )
+ logger.log("{:}".format("*" * 100))
+
+ logger.close()
+
+
+def traverse_net(candidates: List[int], N: int):
+ nets = [""]
+ for i in range(N):
+ new_nets = []
+ for net in nets:
+ for C in candidates:
+ new_nets.append(str(C) if net == "" else "{:}:{:}".format(net, C))
+ nets = new_nets
+ return nets
+
+
+def filter_indexes(xlist, mode, save_dir, seeds):
+ all_indexes = []
+ for index in xlist:
+ if mode == "cover":
+ all_indexes.append(index)
+ else:
+ for seed in seeds:
+ temp_path = save_dir / "arch-{:06d}-seed-{:04d}.pth".format(index, seed)
+ if not temp_path.exists():
+ all_indexes.append(index)
+ break
+ print(
+ "{:} [FILTER-INDEXES] : there are {:}/{:} architectures in total".format(
+ time_string(), len(all_indexes), len(xlist)
+ )
+ )
+
+ SLURM_PROCID, SLURM_NTASKS = "SLURM_PROCID", "SLURM_NTASKS"
+ if SLURM_PROCID in os.environ and SLURM_NTASKS in os.environ: # run on the slurm
+ proc_id, ntasks = int(os.environ[SLURM_PROCID]), int(os.environ[SLURM_NTASKS])
+ assert 0 <= proc_id < ntasks, "invalid proc_id {:} vs ntasks {:}".format(
+ proc_id, ntasks
+ )
+ scales = [int(float(i) / ntasks * len(all_indexes)) for i in range(ntasks)] + [
+ len(all_indexes)
+ ]
+ per_job = []
+ for i in range(ntasks):
+ xs, xe = min(max(scales[i], 0), len(all_indexes) - 1), min(
+ max(scales[i + 1] - 1, 0), len(all_indexes) - 1
+ )
+ per_job.append((xs, xe))
+ for i, srange in enumerate(per_job):
+ print(" -->> {:2d}/{:02d} : {:}".format(i, ntasks, srange))
+ current_range = per_job[proc_id]
+ all_indexes = [
+ all_indexes[i] for i in range(current_range[0], current_range[1] + 1)
+ ]
+ # set the device id
+ device = proc_id % torch.cuda.device_count()
+ torch.cuda.set_device(device)
+ print(" set the device id = {:}".format(device))
+ print(
+ "{:} [FILTER-INDEXES] : after filtering there are {:} architectures in total".format(
+ time_string(), len(all_indexes)
+ )
+ )
+ return all_indexes
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(
+ description="NATS-Bench (size search space)",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ )
+ parser.add_argument(
+ "--mode",
+ type=str,
+ required=True,
+ choices=["new", "cover"],
+ help="The script mode.",
+ )
+ parser.add_argument(
+ "--save_dir",
+ type=str,
+ default="output/NATS-Bench-size",
+ help="Folder to save checkpoints and log.",
+ )
+ parser.add_argument(
+ "--candidateC",
+ type=int,
+ nargs="+",
+ default=[8, 16, 24, 32, 40, 48, 56, 64],
+ help=".",
+ )
+ parser.add_argument(
+ "--num_layers", type=int, default=5, help="The number of layers in a network."
+ )
+ parser.add_argument("--check_N", type=int, default=32768, help="For safety.")
+ # use for train the model
+ parser.add_argument(
+ "--workers",
+ type=int,
+ default=8,
+ help="The number of data loading workers (default: 2)",
+ )
+ parser.add_argument(
+ "--srange", type=str, required=True, help="The range of models to be evaluated"
+ )
+ parser.add_argument("--datasets", type=str, nargs="+", help="The applied datasets.")
+ parser.add_argument(
+ "--xpaths", type=str, nargs="+", help="The root path for this dataset."
+ )
+ parser.add_argument(
+ "--splits", type=int, nargs="+", help="The root path for this dataset."
+ )
+ parser.add_argument(
+ "--hyper",
+ type=str,
+ default="12",
+ choices=["01", "12", "90"],
+ help="The tag for hyper-parameters.",
+ )
+ parser.add_argument(
+ "--seeds", type=int, nargs="+", help="The range of models to be evaluated"
+ )
+ args = parser.parse_args()
+
+ nets = traverse_net(args.candidateC, args.num_layers)
+ if len(nets) != args.check_N:
+ raise ValueError(
+ "Pre-num-check failed : {:} vs {:}".format(len(nets), args.check_N)
+ )
+
+ opt_config = "./configs/nas-benchmark/hyper-opts/{:}E.config".format(args.hyper)
+ if not os.path.isfile(opt_config):
+ raise ValueError("{:} is not a file.".format(opt_config))
+ save_dir = Path(args.save_dir) / "raw-data-{:}".format(args.hyper)
+ save_dir.mkdir(parents=True, exist_ok=True)
+ to_evaluate_indexes = split_str2indexes(args.srange, args.check_N, 5)
+
+ if not len(args.seeds):
+ raise ValueError("invalid length of seeds args: {:}".format(args.seeds))
+ if not (len(args.datasets) == len(args.xpaths) == len(args.splits)):
+ raise ValueError(
+ "invalid infos : {:} vs {:} vs {:}".format(
+ len(args.datasets), len(args.xpaths), len(args.splits)
+ )
+ )
+ if args.workers <= 0:
+ raise ValueError("invalid number of workers : {:}".format(args.workers))
+
+ target_indexes = filter_indexes(
+ to_evaluate_indexes, args.mode, save_dir, args.seeds
+ )
+
+ assert torch.cuda.is_available(), "CUDA is not available."
+ torch.backends.cudnn.enabled = True
+ torch.backends.cudnn.deterministic = True
+ # torch.set_num_threads(args.workers)
+
+ main(
+ save_dir,
+ args.workers,
+ args.datasets,
+ args.xpaths,
+ args.splits,
+ tuple(args.seeds),
+ nets,
+ opt_config,
+ target_indexes,
+ args.mode == "cover",
+ )
diff --git a/AutoDL-Projects/exps/NATS-Bench/main-tss.py b/AutoDL-Projects/exps/NATS-Bench/main-tss.py
new file mode 100644
index 0000000..205be39
--- /dev/null
+++ b/AutoDL-Projects/exps/NATS-Bench/main-tss.py
@@ -0,0 +1,696 @@
+##############################################################################
+# NATS-Bench: Benchmarking NAS Algorithms for Architecture Topology and Size #
+##############################################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020.07 #
+##############################################################################
+# This file is used to train (all) architecture candidate in the topology #
+# search space in NATS-Bench (tss) with different hyper-parameters. #
+# When use mode=new, it will automatically detect whether the checkpoint of #
+# a trial exists, if so, it will skip this trial. When use mode=cover, it #
+# will ignore the (possible) existing checkpoint, run each trial, and save. #
+##############################################################################
+# Please use the script of scripts/NATS-Bench/train-topology.sh to run. #
+# bash scripts/NATS-Bench/train-topology.sh 00000-15624 12 777 #
+# bash scripts/NATS-Bench/train-topology.sh 00000-15624 200 '777 888 999' #
+# #
+################ #
+# [Deprecated Function: Generate the meta information] #
+# python ./exps/NATS-Bench/main-tss.py --mode meta #
+##############################################################################
+import os, sys, time, torch, random, argparse
+from typing import List, Text, Dict, Any
+from PIL import ImageFile
+
+ImageFile.LOAD_TRUNCATED_IMAGES = True
+from copy import deepcopy
+from pathlib import Path
+
+from xautodl.config_utils import dict2config, load_config
+from xautodl.procedures import bench_evaluate_for_seed
+from xautodl.procedures import get_machine_info
+from xautodl.datasets import get_datasets
+from xautodl.log_utils import Logger, AverageMeter, time_string, convert_secs2time
+from xautodl.models import CellStructure, CellArchitectures, get_search_spaces
+from xautodl.utils import split_str2indexes
+
+
+def evaluate_all_datasets(
+ arch: Text,
+ datasets: List[Text],
+ xpaths: List[Text],
+ splits: List[Text],
+ config_path: Text,
+ seed: int,
+ raw_arch_config,
+ workers,
+ logger,
+):
+ machine_info, raw_arch_config = get_machine_info(), deepcopy(raw_arch_config)
+ all_infos = {"info": machine_info}
+ all_dataset_keys = []
+ # look all the datasets
+ for dataset, xpath, split in zip(datasets, xpaths, splits):
+ # train valid data
+ train_data, valid_data, xshape, class_num = get_datasets(dataset, xpath, -1)
+ # load the configuration
+ if dataset == "cifar10" or dataset == "cifar100":
+ split_info = load_config(
+ "configs/nas-benchmark/cifar-split.txt", None, None
+ )
+ elif dataset.startswith("ImageNet16"):
+ split_info = load_config(
+ "configs/nas-benchmark/{:}-split.txt".format(dataset), None, None
+ )
+ else:
+ raise ValueError("invalid dataset : {:}".format(dataset))
+ config = load_config(
+ config_path, dict(class_num=class_num, xshape=xshape), logger
+ )
+ # check whether use splited validation set
+ if bool(split):
+ assert dataset == "cifar10"
+ ValLoaders = {
+ "ori-test": torch.utils.data.DataLoader(
+ valid_data,
+ batch_size=config.batch_size,
+ shuffle=False,
+ num_workers=workers,
+ pin_memory=True,
+ )
+ }
+ assert len(train_data) == len(split_info.train) + len(
+ split_info.valid
+ ), "invalid length : {:} vs {:} + {:}".format(
+ len(train_data), len(split_info.train), len(split_info.valid)
+ )
+ train_data_v2 = deepcopy(train_data)
+ train_data_v2.transform = valid_data.transform
+ valid_data = train_data_v2
+ # data loader
+ train_loader = torch.utils.data.DataLoader(
+ train_data,
+ batch_size=config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(split_info.train),
+ num_workers=workers,
+ pin_memory=True,
+ )
+ valid_loader = torch.utils.data.DataLoader(
+ valid_data,
+ batch_size=config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(split_info.valid),
+ num_workers=workers,
+ pin_memory=True,
+ )
+ ValLoaders["x-valid"] = valid_loader
+ else:
+ # data loader
+ train_loader = torch.utils.data.DataLoader(
+ train_data,
+ batch_size=config.batch_size,
+ shuffle=True,
+ num_workers=workers,
+ pin_memory=True,
+ )
+ valid_loader = torch.utils.data.DataLoader(
+ valid_data,
+ batch_size=config.batch_size,
+ shuffle=False,
+ num_workers=workers,
+ pin_memory=True,
+ )
+ if dataset == "cifar10":
+ ValLoaders = {"ori-test": valid_loader}
+ elif dataset == "cifar100":
+ cifar100_splits = load_config(
+ "configs/nas-benchmark/cifar100-test-split.txt", None, None
+ )
+ ValLoaders = {
+ "ori-test": valid_loader,
+ "x-valid": torch.utils.data.DataLoader(
+ valid_data,
+ batch_size=config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(
+ cifar100_splits.xvalid
+ ),
+ num_workers=workers,
+ pin_memory=True,
+ ),
+ "x-test": torch.utils.data.DataLoader(
+ valid_data,
+ batch_size=config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(
+ cifar100_splits.xtest
+ ),
+ num_workers=workers,
+ pin_memory=True,
+ ),
+ }
+ elif dataset == "ImageNet16-120":
+ imagenet16_splits = load_config(
+ "configs/nas-benchmark/imagenet-16-120-test-split.txt", None, None
+ )
+ ValLoaders = {
+ "ori-test": valid_loader,
+ "x-valid": torch.utils.data.DataLoader(
+ valid_data,
+ batch_size=config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(
+ imagenet16_splits.xvalid
+ ),
+ num_workers=workers,
+ pin_memory=True,
+ ),
+ "x-test": torch.utils.data.DataLoader(
+ valid_data,
+ batch_size=config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(
+ imagenet16_splits.xtest
+ ),
+ num_workers=workers,
+ pin_memory=True,
+ ),
+ }
+ else:
+ raise ValueError("invalid dataset : {:}".format(dataset))
+
+ dataset_key = "{:}".format(dataset)
+ if bool(split):
+ dataset_key = dataset_key + "-valid"
+ logger.log(
+ "Evaluate ||||||| {:10s} ||||||| Train-Num={:}, Valid-Num={:}, Train-Loader-Num={:}, Valid-Loader-Num={:}, batch size={:}".format(
+ dataset_key,
+ len(train_data),
+ len(valid_data),
+ len(train_loader),
+ len(valid_loader),
+ config.batch_size,
+ )
+ )
+ logger.log(
+ "Evaluate ||||||| {:10s} ||||||| Config={:}".format(dataset_key, config)
+ )
+ for key, value in ValLoaders.items():
+ logger.log(
+ "Evaluate ---->>>> {:10s} with {:} batchs".format(key, len(value))
+ )
+ arch_config = dict2config(
+ dict(
+ name="infer.tiny",
+ C=raw_arch_config["channel"],
+ N=raw_arch_config["num_cells"],
+ genotype=arch,
+ num_classes=config.class_num,
+ ),
+ None,
+ )
+ results = bench_evaluate_for_seed(
+ arch_config, config, train_loader, ValLoaders, seed, logger
+ )
+ all_infos[dataset_key] = results
+ all_dataset_keys.append(dataset_key)
+ all_infos["all_dataset_keys"] = all_dataset_keys
+ return all_infos
+
+
+def main(
+ save_dir: Path,
+ workers: int,
+ datasets: List[Text],
+ xpaths: List[Text],
+ splits: List[int],
+ seeds: List[int],
+ nets: List[str],
+ opt_config: Dict[Text, Any],
+ to_evaluate_indexes: tuple,
+ cover_mode: bool,
+ arch_config: Dict[Text, Any],
+):
+
+ log_dir = save_dir / "logs"
+ log_dir.mkdir(parents=True, exist_ok=True)
+ logger = Logger(str(log_dir), os.getpid(), False)
+
+ logger.log("xargs : seeds = {:}".format(seeds))
+ logger.log("xargs : cover_mode = {:}".format(cover_mode))
+ logger.log("-" * 100)
+ logger.log(
+ "Start evaluating range =: {:06d} - {:06d}".format(
+ min(to_evaluate_indexes), max(to_evaluate_indexes)
+ )
+ + "({:} in total) / {:06d} with cover-mode={:}".format(
+ len(to_evaluate_indexes), len(nets), cover_mode
+ )
+ )
+ for i, (dataset, xpath, split) in enumerate(zip(datasets, xpaths, splits)):
+ logger.log(
+ "--->>> Evaluate {:}/{:} : dataset={:9s}, path={:}, split={:}".format(
+ i, len(datasets), dataset, xpath, split
+ )
+ )
+ logger.log("--->>> optimization config : {:}".format(opt_config))
+
+ start_time, epoch_time = time.time(), AverageMeter()
+ for i, index in enumerate(to_evaluate_indexes):
+ arch = nets[index]
+ logger.log(
+ "\n{:} evaluate {:06d}/{:06d} ({:06d}/{:06d})-th arch [seeds={:}] {:}".format(
+ time_string(),
+ i,
+ len(to_evaluate_indexes),
+ index,
+ len(nets),
+ seeds,
+ "-" * 15,
+ )
+ )
+ logger.log("{:} {:} {:}".format("-" * 15, arch, "-" * 15))
+
+ # test this arch on different datasets with different seeds
+ has_continue = False
+ for seed in seeds:
+ to_save_name = save_dir / "arch-{:06d}-seed-{:04d}.pth".format(index, seed)
+ if to_save_name.exists():
+ if cover_mode:
+ logger.log(
+ "Find existing file : {:}, remove it before evaluation".format(
+ to_save_name
+ )
+ )
+ os.remove(str(to_save_name))
+ else:
+ logger.log(
+ "Find existing file : {:}, skip this evaluation".format(
+ to_save_name
+ )
+ )
+ has_continue = True
+ continue
+ results = evaluate_all_datasets(
+ CellStructure.str2structure(arch),
+ datasets,
+ xpaths,
+ splits,
+ opt_config,
+ seed,
+ arch_config,
+ workers,
+ logger,
+ )
+ torch.save(results, to_save_name)
+ logger.log(
+ "\n{:} evaluate {:06d}/{:06d} ({:06d}/{:06d})-th arch [seeds={:}] ===>>> {:}".format(
+ time_string(),
+ i,
+ len(to_evaluate_indexes),
+ index,
+ len(nets),
+ seeds,
+ to_save_name,
+ )
+ )
+ # measure elapsed time
+ if not has_continue:
+ epoch_time.update(time.time() - start_time)
+ start_time = time.time()
+ need_time = "Time Left: {:}".format(
+ convert_secs2time(epoch_time.avg * (len(to_evaluate_indexes) - i - 1), True)
+ )
+ logger.log(
+ "This arch costs : {:}".format(convert_secs2time(epoch_time.val, True))
+ )
+ logger.log("{:}".format("*" * 100))
+ logger.log(
+ "{:} {:74s} {:}".format(
+ "*" * 10,
+ "{:06d}/{:06d} ({:06d}/{:06d})-th done, left {:}".format(
+ i, len(to_evaluate_indexes), index, len(nets), need_time
+ ),
+ "*" * 10,
+ )
+ )
+ logger.log("{:}".format("*" * 100))
+
+ logger.close()
+
+
+def train_single_model(
+ save_dir, workers, datasets, xpaths, splits, use_less, seeds, model_str, arch_config
+):
+ assert torch.cuda.is_available(), "CUDA is not available."
+ torch.backends.cudnn.enabled = True
+ torch.backends.cudnn.deterministic = True
+ # torch.backends.cudnn.benchmark = True
+ # torch.set_num_threads(workers)
+
+ save_dir = (
+ Path(save_dir)
+ / "specifics"
+ / "{:}-{:}-{:}-{:}".format(
+ "LESS" if use_less else "FULL",
+ model_str,
+ arch_config["channel"],
+ arch_config["num_cells"],
+ )
+ )
+ logger = Logger(str(save_dir), 0, False)
+ if model_str in CellArchitectures:
+ arch = CellArchitectures[model_str]
+ logger.log(
+ "The model string is found in pre-defined architecture dict : {:}".format(
+ model_str
+ )
+ )
+ else:
+ try:
+ arch = CellStructure.str2structure(model_str)
+ except:
+ raise ValueError(
+ "Invalid model string : {:}. It can not be found or parsed.".format(
+ model_str
+ )
+ )
+ assert arch.check_valid_op(
+ get_search_spaces("cell", "full")
+ ), "{:} has the invalid op.".format(arch)
+ logger.log("Start train-evaluate {:}".format(arch.tostr()))
+ logger.log("arch_config : {:}".format(arch_config))
+
+ start_time, seed_time = time.time(), AverageMeter()
+ for _is, seed in enumerate(seeds):
+ logger.log(
+ "\nThe {:02d}/{:02d}-th seed is {:} ----------------------<.>----------------------".format(
+ _is, len(seeds), seed
+ )
+ )
+ to_save_name = save_dir / "seed-{:04d}.pth".format(seed)
+ if to_save_name.exists():
+ logger.log(
+ "Find the existing file {:}, directly load!".format(to_save_name)
+ )
+ checkpoint = torch.load(to_save_name)
+ else:
+ logger.log(
+ "Does not find the existing file {:}, train and evaluate!".format(
+ to_save_name
+ )
+ )
+ checkpoint = evaluate_all_datasets(
+ arch,
+ datasets,
+ xpaths,
+ splits,
+ use_less,
+ seed,
+ arch_config,
+ workers,
+ logger,
+ )
+ torch.save(checkpoint, to_save_name)
+ # log information
+ logger.log("{:}".format(checkpoint["info"]))
+ all_dataset_keys = checkpoint["all_dataset_keys"]
+ for dataset_key in all_dataset_keys:
+ logger.log(
+ "\n{:} dataset : {:} {:}".format("-" * 15, dataset_key, "-" * 15)
+ )
+ dataset_info = checkpoint[dataset_key]
+ # logger.log('Network ==>\n{:}'.format( dataset_info['net_string'] ))
+ logger.log(
+ "Flops = {:} MB, Params = {:} MB".format(
+ dataset_info["flop"], dataset_info["param"]
+ )
+ )
+ logger.log("config : {:}".format(dataset_info["config"]))
+ logger.log(
+ "Training State (finish) = {:}".format(dataset_info["finish-train"])
+ )
+ last_epoch = dataset_info["total_epoch"] - 1
+ train_acc1es, train_acc5es = (
+ dataset_info["train_acc1es"],
+ dataset_info["train_acc5es"],
+ )
+ valid_acc1es, valid_acc5es = (
+ dataset_info["valid_acc1es"],
+ dataset_info["valid_acc5es"],
+ )
+ logger.log(
+ "Last Info : Train = Acc@1 {:.2f}% Acc@5 {:.2f}% Error@1 {:.2f}%, Test = Acc@1 {:.2f}% Acc@5 {:.2f}% Error@1 {:.2f}%".format(
+ train_acc1es[last_epoch],
+ train_acc5es[last_epoch],
+ 100 - train_acc1es[last_epoch],
+ valid_acc1es[last_epoch],
+ valid_acc5es[last_epoch],
+ 100 - valid_acc1es[last_epoch],
+ )
+ )
+ # measure elapsed time
+ seed_time.update(time.time() - start_time)
+ start_time = time.time()
+ need_time = "Time Left: {:}".format(
+ convert_secs2time(seed_time.avg * (len(seeds) - _is - 1), True)
+ )
+ logger.log(
+ "\n<<<***>>> The {:02d}/{:02d}-th seed is {:} other procedures need {:}".format(
+ _is, len(seeds), seed, need_time
+ )
+ )
+ logger.close()
+
+
+def generate_meta_info(save_dir, max_node, divide=40):
+ aa_nas_bench_ss = get_search_spaces("cell", "nas-bench-201")
+ archs = CellStructure.gen_all(aa_nas_bench_ss, max_node, False)
+ print(
+ "There are {:} archs vs {:}.".format(
+ len(archs), len(aa_nas_bench_ss) ** ((max_node - 1) * max_node / 2)
+ )
+ )
+
+ random.seed(88) # please do not change this line for reproducibility
+ random.shuffle(archs)
+ # to test fixed-random shuffle
+ # print ('arch [0] : {:}\n---->>>> {:}'.format( archs[0], archs[0].tostr() ))
+ # print ('arch [9] : {:}\n---->>>> {:}'.format( archs[9], archs[9].tostr() ))
+ assert (
+ archs[0].tostr()
+ == "|avg_pool_3x3~0|+|nor_conv_1x1~0|skip_connect~1|+|nor_conv_1x1~0|skip_connect~1|skip_connect~2|"
+ ), "please check the 0-th architecture : {:}".format(archs[0])
+ assert (
+ archs[9].tostr()
+ == "|avg_pool_3x3~0|+|none~0|none~1|+|skip_connect~0|none~1|nor_conv_3x3~2|"
+ ), "please check the 9-th architecture : {:}".format(archs[9])
+ assert (
+ archs[123].tostr()
+ == "|avg_pool_3x3~0|+|avg_pool_3x3~0|nor_conv_1x1~1|+|none~0|avg_pool_3x3~1|nor_conv_3x3~2|"
+ ), "please check the 123-th architecture : {:}".format(archs[123])
+ total_arch = len(archs)
+
+ num = 50000
+ indexes_5W = list(range(num))
+ random.seed(1021)
+ random.shuffle(indexes_5W)
+ train_split = sorted(list(set(indexes_5W[: num // 2])))
+ valid_split = sorted(list(set(indexes_5W[num // 2 :])))
+ assert len(train_split) + len(valid_split) == num
+ assert (
+ train_split[0] == 0
+ and train_split[10] == 26
+ and train_split[111] == 203
+ and valid_split[0] == 1
+ and valid_split[10] == 18
+ and valid_split[111] == 242
+ ), "{:} {:} {:} - {:} {:} {:}".format(
+ train_split[0],
+ train_split[10],
+ train_split[111],
+ valid_split[0],
+ valid_split[10],
+ valid_split[111],
+ )
+ splits = {num: {"train": train_split, "valid": valid_split}}
+
+ info = {
+ "archs": [x.tostr() for x in archs],
+ "total": total_arch,
+ "max_node": max_node,
+ "splits": splits,
+ }
+
+ save_dir = Path(save_dir)
+ save_dir.mkdir(parents=True, exist_ok=True)
+ save_name = save_dir / "meta-node-{:}.pth".format(max_node)
+ assert not save_name.exists(), "{:} already exist".format(save_name)
+ torch.save(info, save_name)
+ print("save the meta file into {:}".format(save_name))
+
+
+def traverse_net(max_node):
+ aa_nas_bench_ss = get_search_spaces("cell", "nats-bench")
+ archs = CellStructure.gen_all(aa_nas_bench_ss, max_node, False)
+ print(
+ "There are {:} archs vs {:}.".format(
+ len(archs), len(aa_nas_bench_ss) ** ((max_node - 1) * max_node / 2)
+ )
+ )
+
+ random.seed(88) # please do not change this line for reproducibility
+ random.shuffle(archs)
+ assert (
+ archs[0].tostr()
+ == "|avg_pool_3x3~0|+|nor_conv_1x1~0|skip_connect~1|+|nor_conv_1x1~0|skip_connect~1|skip_connect~2|"
+ ), "please check the 0-th architecture : {:}".format(archs[0])
+ assert (
+ archs[9].tostr()
+ == "|avg_pool_3x3~0|+|none~0|none~1|+|skip_connect~0|none~1|nor_conv_3x3~2|"
+ ), "please check the 9-th architecture : {:}".format(archs[9])
+ assert (
+ archs[123].tostr()
+ == "|avg_pool_3x3~0|+|avg_pool_3x3~0|nor_conv_1x1~1|+|none~0|avg_pool_3x3~1|nor_conv_3x3~2|"
+ ), "please check the 123-th architecture : {:}".format(archs[123])
+ return [x.tostr() for x in archs]
+
+
+def filter_indexes(xlist, mode, save_dir, seeds):
+ all_indexes = []
+ for index in xlist:
+ if mode == "cover":
+ all_indexes.append(index)
+ else:
+ for seed in seeds:
+ temp_path = save_dir / "arch-{:06d}-seed-{:04d}.pth".format(index, seed)
+ if not temp_path.exists():
+ all_indexes.append(index)
+ break
+ print(
+ "{:} [FILTER-INDEXES] : there are {:}/{:} architectures in total".format(
+ time_string(), len(all_indexes), len(xlist)
+ )
+ )
+ return all_indexes
+
+
+if __name__ == "__main__":
+ # mode_choices = ['meta', 'new', 'cover'] + ['specific-{:}'.format(_) for _ in CellArchitectures.keys()]
+ parser = argparse.ArgumentParser(
+ description="NATS-Bench (topology search space)",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ )
+ parser.add_argument("--mode", type=str, required=True, help="The script mode.")
+ parser.add_argument(
+ "--save_dir",
+ type=str,
+ default="output/NATS-Bench-topology",
+ help="Folder to save checkpoints and log.",
+ )
+ parser.add_argument(
+ "--max_node",
+ type=int,
+ default=4,
+ help="The maximum node in a cell (please do not change it).",
+ )
+ # use for train the model
+ parser.add_argument(
+ "--workers",
+ type=int,
+ default=8,
+ help="number of data loading workers (default: 2)",
+ )
+ parser.add_argument(
+ "--srange", type=str, required=True, help="The range of models to be evaluated"
+ )
+ parser.add_argument("--datasets", type=str, nargs="+", help="The applied datasets.")
+ parser.add_argument(
+ "--xpaths", type=str, nargs="+", help="The root path for this dataset."
+ )
+ parser.add_argument(
+ "--splits", type=int, nargs="+", help="The root path for this dataset."
+ )
+ parser.add_argument(
+ "--hyper",
+ type=str,
+ default="12",
+ choices=["01", "12", "200"],
+ help="The tag for hyper-parameters.",
+ )
+
+ parser.add_argument(
+ "--seeds", type=int, nargs="+", help="The range of models to be evaluated"
+ )
+ parser.add_argument(
+ "--channel", type=int, default=16, help="The number of channels."
+ )
+ parser.add_argument(
+ "--num_cells", type=int, default=5, help="The number of cells in one stage."
+ )
+ parser.add_argument("--check_N", type=int, default=15625, help="For safety.")
+ args = parser.parse_args()
+
+ assert args.mode in ["meta", "new", "cover"] or args.mode.startswith(
+ "specific-"
+ ), "invalid mode : {:}".format(args.mode)
+
+ if args.mode == "meta":
+ generate_meta_info(args.save_dir, args.max_node)
+ elif args.mode.startswith("specific"):
+ assert len(args.mode.split("-")) == 2, "invalid mode : {:}".format(args.mode)
+ model_str = args.mode.split("-")[1]
+ train_single_model(
+ args.save_dir,
+ args.workers,
+ args.datasets,
+ args.xpaths,
+ args.splits,
+ args.use_less > 0,
+ tuple(args.seeds),
+ model_str,
+ {"channel": args.channel, "num_cells": args.num_cells},
+ )
+ else:
+ nets = traverse_net(args.max_node)
+ if len(nets) != args.check_N:
+ raise ValueError(
+ "Pre-num-check failed : {:} vs {:}".format(len(nets), args.check_N)
+ )
+ opt_config = "./configs/nas-benchmark/hyper-opts/{:}E.config".format(args.hyper)
+ if not os.path.isfile(opt_config):
+ raise ValueError("{:} is not a file.".format(opt_config))
+ save_dir = Path(args.save_dir) / "raw-data-{:}".format(args.hyper)
+ save_dir.mkdir(parents=True, exist_ok=True)
+ to_evaluate_indexes = split_str2indexes(args.srange, args.check_N, 5)
+ if not len(args.seeds):
+ raise ValueError("invalid length of seeds args: {:}".format(args.seeds))
+ if not (len(args.datasets) == len(args.xpaths) == len(args.splits)):
+ raise ValueError(
+ "invalid infos : {:} vs {:} vs {:}".format(
+ len(args.datasets), len(args.xpaths), len(args.splits)
+ )
+ )
+ if args.workers < 0:
+ raise ValueError("invalid number of workers : {:}".format(args.workers))
+
+ target_indexes = filter_indexes(
+ to_evaluate_indexes, args.mode, save_dir, args.seeds
+ )
+
+ assert torch.cuda.is_available(), "CUDA is not available."
+ torch.backends.cudnn.enabled = True
+ torch.backends.cudnn.deterministic = True
+ # torch.set_num_threads(args.workers if args.workers > 0 else 1)
+
+ main(
+ save_dir,
+ args.workers,
+ args.datasets,
+ args.xpaths,
+ args.splits,
+ tuple(args.seeds),
+ nets,
+ opt_config,
+ target_indexes,
+ args.mode == "cover",
+ {
+ "name": "infer.tiny",
+ "channel": args.channel,
+ "num_cells": args.num_cells,
+ },
+ )
diff --git a/AutoDL-Projects/exps/NATS-Bench/show-dataset.py b/AutoDL-Projects/exps/NATS-Bench/show-dataset.py
new file mode 100644
index 0000000..0c66ae5
--- /dev/null
+++ b/AutoDL-Projects/exps/NATS-Bench/show-dataset.py
@@ -0,0 +1,59 @@
+##############################################################################
+# NATS-Bench: Benchmarking NAS algorithms for Architecture Topology and Size #
+##############################################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020.07 #
+##############################################################################
+# python ./exps/NATS-Bench/show-dataset.py #
+##############################################################################
+import os, sys, time, torch, random, argparse
+from typing import List, Text, Dict, Any
+from PIL import ImageFile
+
+ImageFile.LOAD_TRUNCATED_IMAGES = True
+from copy import deepcopy
+
+from xautodl.config_utils import dict2config, load_config
+from xautodl.datasets import get_datasets
+from nats_bench import create
+
+
+def show_imagenet_16_120(dataset_dir=None):
+ if dataset_dir is None:
+ torch_home_dir = (
+ os.environ["TORCH_HOME"]
+ if "TORCH_HOME" in os.environ
+ else os.path.join(os.environ["HOME"], ".torch")
+ )
+ dataset_dir = os.path.join(torch_home_dir, "cifar.python", "ImageNet16")
+ train_data, valid_data, xshape, class_num = get_datasets(
+ "ImageNet16-120", dataset_dir, -1
+ )
+ split_info = load_config(
+ "configs/nas-benchmark/ImageNet16-120-split.txt", None, None
+ )
+ print("=" * 10 + " ImageNet-16-120 " + "=" * 10)
+ print("Training Data: {:}".format(train_data))
+ print("Evaluation Data: {:}".format(valid_data))
+ print("Hold-out training: {:} images.".format(len(split_info.train)))
+ print("Hold-out valid : {:} images.".format(len(split_info.valid)))
+
+
+if __name__ == "__main__":
+ # show_imagenet_16_120()
+ api_nats_tss = create(None, "tss", fast_mode=True, verbose=True)
+
+ valid_acc_12e = []
+ test_acc_12e = []
+ test_acc_200e = []
+ for index in range(10000):
+ info = api_nats_tss.get_more_info(index, "ImageNet16-120", hp="12")
+ valid_acc_12e.append(
+ info["valid-accuracy"]
+ ) # the validation accuracy after training the model by 12 epochs
+ test_acc_12e.append(
+ info["test-accuracy"]
+ ) # the test accuracy after training the model by 12 epochs
+ info = api_nats_tss.get_more_info(index, "ImageNet16-120", hp="200")
+ test_acc_200e.append(
+ info["test-accuracy"]
+ ) # the test accuracy after training the model by 200 epochs (which I reported in the paper)
diff --git a/AutoDL-Projects/exps/NATS-Bench/sss-collect.py b/AutoDL-Projects/exps/NATS-Bench/sss-collect.py
new file mode 100644
index 0000000..be1805b
--- /dev/null
+++ b/AutoDL-Projects/exps/NATS-Bench/sss-collect.py
@@ -0,0 +1,389 @@
+##############################################################################
+# NATS-Bench: Benchmarking NAS Algorithms for Architecture Topology and Size #
+##############################################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020.08 #
+##############################################################################
+# This file is used to re-orangize all checkpoints (created by main-sss.py) #
+# into a single benchmark file. Besides, for each trial, we will merge the #
+# information of all its trials into a single file. #
+# #
+# Usage: #
+# python exps/NATS-Bench/sss-collect.py #
+##############################################################################
+import os, re, sys, time, shutil, argparse, collections
+import torch
+from tqdm import tqdm
+from pathlib import Path
+from collections import defaultdict, OrderedDict
+from typing import Dict, Any, Text, List
+
+from xautodl.log_utils import AverageMeter, time_string, convert_secs2time
+from xautodl.config_utils import dict2config
+from xautodl.models import CellStructure, get_cell_based_tiny_net
+from xautodl.procedures import (
+ bench_pure_evaluate as pure_evaluate,
+ get_nas_bench_loaders,
+)
+from xautodl.utils import get_md5_file
+
+from nats_bench import pickle_save, pickle_load, ArchResults, ResultsCount
+
+
+NATS_SSS_BASE_NAME = "NATS-sss-v1_0" # 2020.08.28
+
+
+def account_one_arch(
+ arch_index: int, arch_str: Text, checkpoints: List[Text], datasets: List[Text]
+) -> ArchResults:
+ information = ArchResults(arch_index, arch_str)
+
+ for checkpoint_path in checkpoints:
+ try:
+ checkpoint = torch.load(checkpoint_path, map_location="cpu")
+ except:
+ raise ValueError(
+ "This checkpoint failed to be loaded : {:}".format(checkpoint_path)
+ )
+ used_seed = checkpoint_path.name.split("-")[-1].split(".")[0]
+ ok_dataset = 0
+ for dataset in datasets:
+ if dataset not in checkpoint:
+ print(
+ "Can not find {:} in arch-{:} from {:}".format(
+ dataset, arch_index, checkpoint_path
+ )
+ )
+ continue
+ else:
+ ok_dataset += 1
+ results = checkpoint[dataset]
+ assert results[
+ "finish-train"
+ ], "This {:} arch seed={:} does not finish train on {:} ::: {:}".format(
+ arch_index, used_seed, dataset, checkpoint_path
+ )
+ arch_config = {
+ "name": "infer.shape.tiny",
+ "channels": arch_str,
+ "arch_str": arch_str,
+ "genotype": results["arch_config"]["genotype"],
+ "class_num": results["arch_config"]["num_classes"],
+ }
+ xresult = ResultsCount(
+ dataset,
+ results["net_state_dict"],
+ results["train_acc1es"],
+ results["train_losses"],
+ results["param"],
+ results["flop"],
+ arch_config,
+ used_seed,
+ results["total_epoch"],
+ None,
+ )
+ xresult.update_train_info(
+ results["train_acc1es"],
+ results["train_acc5es"],
+ results["train_losses"],
+ results["train_times"],
+ )
+ xresult.update_eval(
+ results["valid_acc1es"], results["valid_losses"], results["valid_times"]
+ )
+ information.update(dataset, int(used_seed), xresult)
+ if ok_dataset < len(datasets):
+ raise ValueError(
+ "{:} does find enought data : {:} vs {:}".format(
+ checkpoint_path, ok_dataset, len(datasets)
+ )
+ )
+ return information
+
+
+def correct_time_related_info(hp2info: Dict[Text, ArchResults]):
+ # calibrate the latency based on the number of epochs = 01, since they are trained on the same machine.
+ x1 = hp2info["01"].get_metrics("cifar10-valid", "x-valid")["all_time"] / 98
+ x2 = hp2info["01"].get_metrics("cifar10-valid", "ori-test")["all_time"] / 40
+ cifar010_latency = (x1 + x2) / 2
+ for hp, arch_info in hp2info.items():
+ arch_info.reset_latency("cifar10-valid", None, cifar010_latency)
+ arch_info.reset_latency("cifar10", None, cifar010_latency)
+ # hp2info['01'].get_latency('cifar10')
+
+ x1 = hp2info["01"].get_metrics("cifar100", "ori-test")["all_time"] / 40
+ x2 = hp2info["01"].get_metrics("cifar100", "x-test")["all_time"] / 20
+ x3 = hp2info["01"].get_metrics("cifar100", "x-valid")["all_time"] / 20
+ cifar100_latency = (x1 + x2 + x3) / 3
+ for hp, arch_info in hp2info.items():
+ arch_info.reset_latency("cifar100", None, cifar100_latency)
+
+ x1 = hp2info["01"].get_metrics("ImageNet16-120", "ori-test")["all_time"] / 24
+ x2 = hp2info["01"].get_metrics("ImageNet16-120", "x-test")["all_time"] / 12
+ x3 = hp2info["01"].get_metrics("ImageNet16-120", "x-valid")["all_time"] / 12
+ image_latency = (x1 + x2 + x3) / 3
+ for hp, arch_info in hp2info.items():
+ arch_info.reset_latency("ImageNet16-120", None, image_latency)
+
+ # CIFAR10 VALID
+ train_per_epoch_time = list(
+ hp2info["01"].query("cifar10-valid", 777).train_times.values()
+ )
+ train_per_epoch_time = sum(train_per_epoch_time) / len(train_per_epoch_time)
+ eval_ori_test_time, eval_x_valid_time = [], []
+ for key, value in hp2info["01"].query("cifar10-valid", 777).eval_times.items():
+ if key.startswith("ori-test@"):
+ eval_ori_test_time.append(value)
+ elif key.startswith("x-valid@"):
+ eval_x_valid_time.append(value)
+ else:
+ raise ValueError("-- {:} --".format(key))
+ eval_ori_test_time = sum(eval_ori_test_time) / len(eval_ori_test_time)
+ eval_x_valid_time = sum(eval_x_valid_time) / len(eval_x_valid_time)
+ for hp, arch_info in hp2info.items():
+ arch_info.reset_pseudo_train_times("cifar10-valid", None, train_per_epoch_time)
+ arch_info.reset_pseudo_eval_times(
+ "cifar10-valid", None, "x-valid", eval_x_valid_time
+ )
+ arch_info.reset_pseudo_eval_times(
+ "cifar10-valid", None, "ori-test", eval_ori_test_time
+ )
+
+ # CIFAR10
+ train_per_epoch_time = list(
+ hp2info["01"].query("cifar10", 777).train_times.values()
+ )
+ train_per_epoch_time = sum(train_per_epoch_time) / len(train_per_epoch_time)
+ eval_ori_test_time = []
+ for key, value in hp2info["01"].query("cifar10", 777).eval_times.items():
+ if key.startswith("ori-test@"):
+ eval_ori_test_time.append(value)
+ else:
+ raise ValueError("-- {:} --".format(key))
+ eval_ori_test_time = sum(eval_ori_test_time) / len(eval_ori_test_time)
+ for hp, arch_info in hp2info.items():
+ arch_info.reset_pseudo_train_times("cifar10", None, train_per_epoch_time)
+ arch_info.reset_pseudo_eval_times(
+ "cifar10", None, "ori-test", eval_ori_test_time
+ )
+
+ # CIFAR100
+ train_per_epoch_time = list(
+ hp2info["01"].query("cifar100", 777).train_times.values()
+ )
+ train_per_epoch_time = sum(train_per_epoch_time) / len(train_per_epoch_time)
+ eval_ori_test_time, eval_x_valid_time, eval_x_test_time = [], [], []
+ for key, value in hp2info["01"].query("cifar100", 777).eval_times.items():
+ if key.startswith("ori-test@"):
+ eval_ori_test_time.append(value)
+ elif key.startswith("x-valid@"):
+ eval_x_valid_time.append(value)
+ elif key.startswith("x-test@"):
+ eval_x_test_time.append(value)
+ else:
+ raise ValueError("-- {:} --".format(key))
+ eval_ori_test_time = sum(eval_ori_test_time) / len(eval_ori_test_time)
+ eval_x_valid_time = sum(eval_x_valid_time) / len(eval_x_valid_time)
+ eval_x_test_time = sum(eval_x_test_time) / len(eval_x_test_time)
+ for hp, arch_info in hp2info.items():
+ arch_info.reset_pseudo_train_times("cifar100", None, train_per_epoch_time)
+ arch_info.reset_pseudo_eval_times(
+ "cifar100", None, "x-valid", eval_x_valid_time
+ )
+ arch_info.reset_pseudo_eval_times("cifar100", None, "x-test", eval_x_test_time)
+ arch_info.reset_pseudo_eval_times(
+ "cifar100", None, "ori-test", eval_ori_test_time
+ )
+
+ # ImageNet16-120
+ train_per_epoch_time = list(
+ hp2info["01"].query("ImageNet16-120", 777).train_times.values()
+ )
+ train_per_epoch_time = sum(train_per_epoch_time) / len(train_per_epoch_time)
+ eval_ori_test_time, eval_x_valid_time, eval_x_test_time = [], [], []
+ for key, value in hp2info["01"].query("ImageNet16-120", 777).eval_times.items():
+ if key.startswith("ori-test@"):
+ eval_ori_test_time.append(value)
+ elif key.startswith("x-valid@"):
+ eval_x_valid_time.append(value)
+ elif key.startswith("x-test@"):
+ eval_x_test_time.append(value)
+ else:
+ raise ValueError("-- {:} --".format(key))
+ eval_ori_test_time = sum(eval_ori_test_time) / len(eval_ori_test_time)
+ eval_x_valid_time = sum(eval_x_valid_time) / len(eval_x_valid_time)
+ eval_x_test_time = sum(eval_x_test_time) / len(eval_x_test_time)
+ for hp, arch_info in hp2info.items():
+ arch_info.reset_pseudo_train_times("ImageNet16-120", None, train_per_epoch_time)
+ arch_info.reset_pseudo_eval_times(
+ "ImageNet16-120", None, "x-valid", eval_x_valid_time
+ )
+ arch_info.reset_pseudo_eval_times(
+ "ImageNet16-120", None, "x-test", eval_x_test_time
+ )
+ arch_info.reset_pseudo_eval_times(
+ "ImageNet16-120", None, "ori-test", eval_ori_test_time
+ )
+ return hp2info
+
+
+def simplify(save_dir, save_name, nets, total):
+
+ hps, seeds = ["01", "12", "90"], set()
+ for hp in hps:
+ sub_save_dir = save_dir / "raw-data-{:}".format(hp)
+ ckps = sorted(list(sub_save_dir.glob("arch-*-seed-*.pth")))
+ seed2names = defaultdict(list)
+ for ckp in ckps:
+ parts = re.split("-|\.", ckp.name)
+ seed2names[parts[3]].append(ckp.name)
+ print("DIR : {:}".format(sub_save_dir))
+ nums = []
+ for seed, xlist in seed2names.items():
+ seeds.add(seed)
+ nums.append(len(xlist))
+ print(" [seed={:}] there are {:} checkpoints.".format(seed, len(xlist)))
+ assert (
+ len(nets) == total == max(nums)
+ ), "there are some missed files : {:} vs {:}".format(max(nums), total)
+ print("{:} start simplify the checkpoint.".format(time_string()))
+
+ datasets = ("cifar10-valid", "cifar10", "cifar100", "ImageNet16-120")
+
+ # Create the directory to save the processed data
+ # full_save_dir contains all benchmark files with trained weights.
+ # simplify_save_dir contains all benchmark files without trained weights.
+ full_save_dir = save_dir / (save_name + "-FULL")
+ simple_save_dir = save_dir / (save_name + "-SIMPLIFY")
+ full_save_dir.mkdir(parents=True, exist_ok=True)
+ simple_save_dir.mkdir(parents=True, exist_ok=True)
+ # all data in memory
+ arch2infos, evaluated_indexes = dict(), set()
+ end_time, arch_time = time.time(), AverageMeter()
+
+ for index in tqdm(range(total)):
+ arch_str = nets[index]
+ hp2info = OrderedDict()
+
+ full_save_path = full_save_dir / "{:06d}.pickle".format(index)
+ simple_save_path = simple_save_dir / "{:06d}.pickle".format(index)
+
+ for hp in hps:
+ sub_save_dir = save_dir / "raw-data-{:}".format(hp)
+ ckps = [
+ sub_save_dir / "arch-{:06d}-seed-{:}.pth".format(index, seed)
+ for seed in seeds
+ ]
+ ckps = [x for x in ckps if x.exists()]
+ if len(ckps) == 0:
+ raise ValueError("Invalid data : index={:}, hp={:}".format(index, hp))
+
+ arch_info = account_one_arch(index, arch_str, ckps, datasets)
+ hp2info[hp] = arch_info
+
+ hp2info = correct_time_related_info(hp2info)
+ evaluated_indexes.add(index)
+
+ hp2info["01"].clear_params() # to save some spaces...
+ to_save_data = OrderedDict(
+ {
+ "01": hp2info["01"].state_dict(),
+ "12": hp2info["12"].state_dict(),
+ "90": hp2info["90"].state_dict(),
+ }
+ )
+ pickle_save(to_save_data, str(full_save_path))
+
+ for hp in hps:
+ hp2info[hp].clear_params()
+ to_save_data = OrderedDict(
+ {
+ "01": hp2info["01"].state_dict(),
+ "12": hp2info["12"].state_dict(),
+ "90": hp2info["90"].state_dict(),
+ }
+ )
+ pickle_save(to_save_data, str(simple_save_path))
+ arch2infos[index] = to_save_data
+ # measure elapsed time
+ arch_time.update(time.time() - end_time)
+ end_time = time.time()
+ need_time = "{:}".format(
+ convert_secs2time(arch_time.avg * (total - index - 1), True)
+ )
+ # print('{:} {:06d}/{:06d} : still need {:}'.format(time_string(), index, total, need_time))
+ print("{:} {:} done.".format(time_string(), save_name))
+ final_infos = {
+ "meta_archs": nets,
+ "total_archs": total,
+ "arch2infos": arch2infos,
+ "evaluated_indexes": evaluated_indexes,
+ }
+ save_file_name = save_dir / "{:}.pickle".format(save_name)
+ pickle_save(final_infos, str(save_file_name))
+ # move the benchmark file to a new path
+ hd5sum = get_md5_file(str(save_file_name) + ".pbz2")
+ hd5_file_name = save_dir / "{:}-{:}.pickle.pbz2".format(NATS_SSS_BASE_NAME, hd5sum)
+ shutil.move(str(save_file_name) + ".pbz2", hd5_file_name)
+ print(
+ "Save {:} / {:} architecture results into {:} -> {:}.".format(
+ len(evaluated_indexes), total, save_file_name, hd5_file_name
+ )
+ )
+ # move the directory to a new path
+ hd5_full_save_dir = save_dir / "{:}-{:}-full".format(NATS_SSS_BASE_NAME, hd5sum)
+ hd5_simple_save_dir = save_dir / "{:}-{:}-simple".format(NATS_SSS_BASE_NAME, hd5sum)
+ shutil.move(full_save_dir, hd5_full_save_dir)
+ shutil.move(simple_save_dir, hd5_simple_save_dir)
+ # save the meta information for simple and full
+ final_infos["arch2infos"] = None
+ final_infos["evaluated_indexes"] = set()
+ pickle_save(final_infos, str(hd5_full_save_dir / "meta.pickle"))
+ pickle_save(final_infos, str(hd5_simple_save_dir / "meta.pickle"))
+
+
+def traverse_net(candidates: List[int], N: int):
+ nets = [""]
+ for i in range(N):
+ new_nets = []
+ for net in nets:
+ for C in candidates:
+ new_nets.append(str(C) if net == "" else "{:}:{:}".format(net, C))
+ nets = new_nets
+ return nets
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(
+ description="NATS-Bench (size search space)",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ )
+ parser.add_argument(
+ "--base_save_dir",
+ type=str,
+ default="./output/NATS-Bench-size",
+ help="The base-name of folder to save checkpoints and log.",
+ )
+ parser.add_argument(
+ "--candidateC",
+ type=int,
+ nargs="+",
+ default=[8, 16, 24, 32, 40, 48, 56, 64],
+ help=".",
+ )
+ parser.add_argument(
+ "--num_layers", type=int, default=5, help="The number of layers in a network."
+ )
+ parser.add_argument("--check_N", type=int, default=32768, help="For safety.")
+ parser.add_argument(
+ "--save_name", type=str, default="process", help="The save directory."
+ )
+ args = parser.parse_args()
+
+ nets = traverse_net(args.candidateC, args.num_layers)
+ if len(nets) != args.check_N:
+ raise ValueError(
+ "Pre-num-check failed : {:} vs {:}".format(len(nets), args.check_N)
+ )
+
+ save_dir = Path(args.base_save_dir)
+ simplify(save_dir, args.save_name, nets, args.check_N)
diff --git a/AutoDL-Projects/exps/NATS-Bench/sss-file-manager.py b/AutoDL-Projects/exps/NATS-Bench/sss-file-manager.py
new file mode 100644
index 0000000..3e600a9
--- /dev/null
+++ b/AutoDL-Projects/exps/NATS-Bench/sss-file-manager.py
@@ -0,0 +1,103 @@
+##############################################################################
+# NATS-Bench: Benchmarking NAS Algorithms for Architecture Topology and Size #
+##############################################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020.08 #
+##############################################################################
+# Usage: python exps/NATS-Bench/sss-file-manager.py --mode check #
+##############################################################################
+import os, sys, time, torch, argparse
+from typing import List, Text, Dict, Any
+from shutil import copyfile
+from collections import defaultdict
+from copy import deepcopy
+from pathlib import Path
+
+from xautodl.config_utils import dict2config, load_config
+from xautodl.procedures import bench_evaluate_for_seed
+from xautodl.procedures import get_machine_info
+from xautodl.datasets import get_datasets
+from xautodl.log_utils import Logger, AverageMeter, time_string, convert_secs2time
+
+
+def obtain_valid_ckp(save_dir: Text, total: int):
+ possible_seeds = [777, 888, 999]
+ seed2ckps = defaultdict(list)
+ miss2ckps = defaultdict(list)
+ for i in range(total):
+ for seed in possible_seeds:
+ path = os.path.join(save_dir, "arch-{:06d}-seed-{:04d}.pth".format(i, seed))
+ if os.path.exists(path):
+ seed2ckps[seed].append(i)
+ else:
+ miss2ckps[seed].append(i)
+ for seed, xlist in seed2ckps.items():
+ print(
+ "[{:}] [seed={:}] has {:5d}/{:5d} | miss {:5d}/{:5d}".format(
+ save_dir, seed, len(xlist), total, total - len(xlist), total
+ )
+ )
+ return dict(seed2ckps), dict(miss2ckps)
+
+
+def copy_data(source_dir, target_dir, meta_path):
+ target_dir = Path(target_dir)
+ target_dir.mkdir(parents=True, exist_ok=True)
+ miss2ckps = torch.load(meta_path)["miss2ckps"]
+ s2t = {}
+ for seed, xlist in miss2ckps.items():
+ for i in xlist:
+ file_name = "arch-{:06d}-seed-{:04d}.pth".format(i, seed)
+ source_path = os.path.join(source_dir, file_name)
+ target_path = os.path.join(target_dir, file_name)
+ if os.path.exists(source_path):
+ s2t[source_path] = target_path
+ print(
+ "Map from {:} to {:}, find {:} missed ckps.".format(
+ source_dir, target_dir, len(s2t)
+ )
+ )
+ for s, t in s2t.items():
+ copyfile(s, t)
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(
+ description="NATS-Bench (size search space) file manager.",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ )
+ parser.add_argument(
+ "--mode",
+ type=str,
+ required=True,
+ choices=["check", "copy"],
+ help="The script mode.",
+ )
+ parser.add_argument(
+ "--save_dir",
+ type=str,
+ default="output/NATS-Bench-size",
+ help="Folder to save checkpoints and log.",
+ )
+ parser.add_argument("--check_N", type=int, default=32768, help="For safety.")
+ # use for train the model
+ args = parser.parse_args()
+ possible_configs = ["01", "12", "90"]
+ if args.mode == "check":
+ for config in possible_configs:
+ cur_save_dir = "{:}/raw-data-{:}".format(args.save_dir, config)
+ seed2ckps, miss2ckps = obtain_valid_ckp(cur_save_dir, args.check_N)
+ torch.save(
+ dict(seed2ckps=seed2ckps, miss2ckps=miss2ckps),
+ "{:}/meta-{:}.pth".format(args.save_dir, config),
+ )
+ elif args.mode == "copy":
+ for config in possible_configs:
+ cur_save_dir = "{:}/raw-data-{:}".format(args.save_dir, config)
+ cur_copy_dir = "{:}/copy-{:}".format(args.save_dir, config)
+ cur_meta_path = "{:}/meta-{:}.pth".format(args.save_dir, config)
+ if os.path.exists(cur_meta_path):
+ copy_data(cur_save_dir, cur_copy_dir, cur_meta_path)
+ else:
+ print("Do not find : {:}".format(cur_meta_path))
+ else:
+ raise ValueError("invalid mode : {:}".format(args.mode))
diff --git a/AutoDL-Projects/exps/NATS-Bench/test-nats-api.py b/AutoDL-Projects/exps/NATS-Bench/test-nats-api.py
new file mode 100644
index 0000000..dae4597
--- /dev/null
+++ b/AutoDL-Projects/exps/NATS-Bench/test-nats-api.py
@@ -0,0 +1,111 @@
+##############################################################################
+# NATS-Bench: Benchmarking NAS Algorithms for Architecture Topology and Size #
+##############################################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020.08 #
+##############################################################################
+# Usage: python exps/NATS-Bench/test-nats-api.py #
+##############################################################################
+import os, gc, sys, time, torch, argparse
+import numpy as np
+from typing import List, Text, Dict, Any
+from shutil import copyfile
+from collections import defaultdict
+from copy import deepcopy
+from pathlib import Path
+import matplotlib
+import seaborn as sns
+
+matplotlib.use("agg")
+import matplotlib.pyplot as plt
+import matplotlib.ticker as ticker
+
+from xautodl.config_utils import dict2config, load_config
+from xautodl.log_utils import time_string
+from xautodl.models import get_cell_based_tiny_net, CellStructure
+from nats_bench import create
+
+
+def test_api(api, sss_or_tss=True):
+ print("{:} start testing the api : {:}".format(time_string(), api))
+ api.clear_params(12)
+ api.reload(index=12)
+
+ # Query the informations of 1113-th architecture
+ info_strs = api.query_info_str_by_arch(1113)
+ print(info_strs)
+ info = api.query_by_index(113)
+ print("{:}\n".format(info))
+ info = api.query_by_index(113, "cifar100")
+ print("{:}\n".format(info))
+
+ info = api.query_meta_info_by_index(115, "90" if sss_or_tss else "200")
+ print("{:}\n".format(info))
+
+ for dataset in ["cifar10", "cifar100", "ImageNet16-120"]:
+ for xset in ["train", "test", "valid"]:
+ best_index, highest_accuracy = api.find_best(dataset, xset)
+ print("")
+ params = api.get_net_param(12, "cifar10", None)
+
+ # Obtain the config and create the network
+ config = api.get_net_config(12, "cifar10")
+ print("{:}\n".format(config))
+ network = get_cell_based_tiny_net(config)
+ network.load_state_dict(next(iter(params.values())))
+
+ # Obtain the cost information
+ info = api.get_cost_info(12, "cifar10")
+ print("{:}\n".format(info))
+ info = api.get_latency(12, "cifar10")
+ print("{:}\n".format(info))
+ for index in [13, 15, 19, 200]:
+ info = api.get_latency(index, "cifar10")
+
+ # Count the number of architectures
+ info = api.statistics("cifar100", "12")
+ print("{:} statistics results : {:}\n".format(time_string(), info))
+
+ # Show the information of the 123-th architecture
+ api.show(123)
+
+ # Obtain both cost and performance information
+ info = api.get_more_info(1234, "cifar10")
+ print("{:}\n".format(info))
+ print("{:} finish testing the api : {:}".format(time_string(), api))
+
+ if not sss_or_tss:
+ arch_str = "|nor_conv_3x3~0|+|nor_conv_3x3~0|avg_pool_3x3~1|+|skip_connect~0|nor_conv_3x3~1|skip_connect~2|"
+ matrix = api.str2matrix(arch_str)
+ print("Compute the adjacency matrix of {:}".format(arch_str))
+ print(matrix)
+ info = api.simulate_train_eval(123, "cifar10")
+ print("simulate_train_eval : {:}\n\n".format(info))
+
+
+if __name__ == "__main__":
+
+ # api201 = create('./output/NATS-Bench-topology/process-FULL', 'topology', fast_mode=True, verbose=True)
+ for fast_mode in [True, False]:
+ for verbose in [True, False]:
+ api_nats_tss = create(None, "tss", fast_mode=fast_mode, verbose=True)
+ print(
+ "{:} create with fast_mode={:} and verbose={:}".format(
+ time_string(), fast_mode, verbose
+ )
+ )
+ test_api(api_nats_tss, False)
+ del api_nats_tss
+ gc.collect()
+
+ for fast_mode in [True, False]:
+ for verbose in [True, False]:
+ print(
+ "{:} create with fast_mode={:} and verbose={:}".format(
+ time_string(), fast_mode, verbose
+ )
+ )
+ api_nats_sss = create(None, "size", fast_mode=fast_mode, verbose=True)
+ print("{:} --->>> {:}".format(time_string(), api_nats_sss))
+ test_api(api_nats_sss, True)
+ del api_nats_sss
+ gc.collect()
diff --git a/AutoDL-Projects/exps/NATS-Bench/tss-collect-patcher.py b/AutoDL-Projects/exps/NATS-Bench/tss-collect-patcher.py
new file mode 100644
index 0000000..5d493df
--- /dev/null
+++ b/AutoDL-Projects/exps/NATS-Bench/tss-collect-patcher.py
@@ -0,0 +1,179 @@
+##############################################################################
+# NATS-Bench: Benchmarking NAS Algorithms for Architecture Topology and Size #
+##############################################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020.08 #
+##############################################################################
+# This file is used to re-orangize all checkpoints (created by main-tss.py) #
+# into a single benchmark file. Besides, for each trial, we will merge the #
+# information of all its trials into a single file. #
+# #
+# Usage: #
+# python exps/NATS-Bench/tss-collect-patcher.py #
+##############################################################################
+import os, re, sys, time, shutil, random, argparse, collections
+import numpy as np
+from copy import deepcopy
+import torch
+from tqdm import tqdm
+from pathlib import Path
+from collections import defaultdict, OrderedDict
+from typing import Dict, Any, Text, List
+
+from xautodl.log_utils import AverageMeter, time_string, convert_secs2time
+from xautodl.config_utils import load_config, dict2config
+from xautodl.datasets import get_datasets
+from xautodl.models import CellStructure, get_cell_based_tiny_net, get_search_spaces
+from xautodl.procedures import (
+ bench_pure_evaluate as pure_evaluate,
+ get_nas_bench_loaders,
+)
+from xautodl.utils import get_md5_file
+
+from nats_bench import pickle_save, pickle_load, ArchResults, ResultsCount
+from nas_201_api import NASBench201API
+
+
+NATS_TSS_BASE_NAME = "NATS-tss-v1_0" # 2020.08.28
+
+
+def simplify(save_dir, save_name, nets, total, sup_config):
+ hps, seeds = ["12", "200"], set()
+ for hp in hps:
+ sub_save_dir = save_dir / "raw-data-{:}".format(hp)
+ ckps = sorted(list(sub_save_dir.glob("arch-*-seed-*.pth")))
+ seed2names = defaultdict(list)
+ for ckp in ckps:
+ parts = re.split("-|\.", ckp.name)
+ seed2names[parts[3]].append(ckp.name)
+ print("DIR : {:}".format(sub_save_dir))
+ nums = []
+ for seed, xlist in seed2names.items():
+ seeds.add(seed)
+ nums.append(len(xlist))
+ print(" [seed={:}] there are {:} checkpoints.".format(seed, len(xlist)))
+ assert (
+ len(nets) == total == max(nums)
+ ), "there are some missed files : {:} vs {:}".format(max(nums), total)
+ print("{:} start simplify the checkpoint.".format(time_string()))
+
+ datasets = ("cifar10-valid", "cifar10", "cifar100", "ImageNet16-120")
+
+ # Create the directory to save the processed data
+ # full_save_dir contains all benchmark files with trained weights.
+ # simplify_save_dir contains all benchmark files without trained weights.
+ full_save_dir = save_dir / (save_name + "-FULL")
+ simple_save_dir = save_dir / (save_name + "-SIMPLIFY")
+ full_save_dir.mkdir(parents=True, exist_ok=True)
+ simple_save_dir.mkdir(parents=True, exist_ok=True)
+ # all data in memory
+ arch2infos, evaluated_indexes = dict(), set()
+ end_time, arch_time = time.time(), AverageMeter()
+ # save the meta information
+ for index in tqdm(range(total)):
+ arch_str = nets[index]
+ hp2info = OrderedDict()
+
+ simple_save_path = simple_save_dir / "{:06d}.pickle".format(index)
+
+ arch2infos[index] = pickle_load(simple_save_path)
+ evaluated_indexes.add(index)
+
+ # measure elapsed time
+ arch_time.update(time.time() - end_time)
+ end_time = time.time()
+ need_time = "{:}".format(
+ convert_secs2time(arch_time.avg * (total - index - 1), True)
+ )
+ # print('{:} {:06d}/{:06d} : still need {:}'.format(time_string(), index, total, need_time))
+ print("{:} {:} done.".format(time_string(), save_name))
+ final_infos = {
+ "meta_archs": nets,
+ "total_archs": total,
+ "arch2infos": arch2infos,
+ "evaluated_indexes": evaluated_indexes,
+ }
+ save_file_name = save_dir / "{:}.pickle".format(save_name)
+ pickle_save(final_infos, str(save_file_name))
+ # move the benchmark file to a new path
+ hd5sum = get_md5_file(str(save_file_name) + ".pbz2")
+ hd5_file_name = save_dir / "{:}-{:}.pickle.pbz2".format(NATS_TSS_BASE_NAME, hd5sum)
+ shutil.move(str(save_file_name) + ".pbz2", hd5_file_name)
+ print(
+ "Save {:} / {:} architecture results into {:} -> {:}.".format(
+ len(evaluated_indexes), total, save_file_name, hd5_file_name
+ )
+ )
+ # move the directory to a new path
+ hd5_full_save_dir = save_dir / "{:}-{:}-full".format(NATS_TSS_BASE_NAME, hd5sum)
+ hd5_simple_save_dir = save_dir / "{:}-{:}-simple".format(NATS_TSS_BASE_NAME, hd5sum)
+ shutil.move(full_save_dir, hd5_full_save_dir)
+ shutil.move(simple_save_dir, hd5_simple_save_dir)
+
+
+def traverse_net(max_node):
+ aa_nas_bench_ss = get_search_spaces("cell", "nats-bench")
+ archs = CellStructure.gen_all(aa_nas_bench_ss, max_node, False)
+ print(
+ "There are {:} archs vs {:}.".format(
+ len(archs), len(aa_nas_bench_ss) ** ((max_node - 1) * max_node / 2)
+ )
+ )
+
+ random.seed(88) # please do not change this line for reproducibility
+ random.shuffle(archs)
+ assert (
+ archs[0].tostr()
+ == "|avg_pool_3x3~0|+|nor_conv_1x1~0|skip_connect~1|+|nor_conv_1x1~0|skip_connect~1|skip_connect~2|"
+ ), "please check the 0-th architecture : {:}".format(archs[0])
+ assert (
+ archs[9].tostr()
+ == "|avg_pool_3x3~0|+|none~0|none~1|+|skip_connect~0|none~1|nor_conv_3x3~2|"
+ ), "please check the 9-th architecture : {:}".format(archs[9])
+ assert (
+ archs[123].tostr()
+ == "|avg_pool_3x3~0|+|avg_pool_3x3~0|nor_conv_1x1~1|+|none~0|avg_pool_3x3~1|nor_conv_3x3~2|"
+ ), "please check the 123-th architecture : {:}".format(archs[123])
+ return [x.tostr() for x in archs]
+
+
+if __name__ == "__main__":
+
+ parser = argparse.ArgumentParser(
+ description="NATS-Bench (topology search space)",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ )
+ parser.add_argument(
+ "--base_save_dir",
+ type=str,
+ default="./output/NATS-Bench-topology",
+ help="The base-name of folder to save checkpoints and log.",
+ )
+ parser.add_argument(
+ "--max_node", type=int, default=4, help="The maximum node in a cell."
+ )
+ parser.add_argument(
+ "--channel", type=int, default=16, help="The number of channels."
+ )
+ parser.add_argument(
+ "--num_cells", type=int, default=5, help="The number of cells in one stage."
+ )
+ parser.add_argument("--check_N", type=int, default=15625, help="For safety.")
+ parser.add_argument(
+ "--save_name", type=str, default="process", help="The save directory."
+ )
+ args = parser.parse_args()
+
+ nets = traverse_net(args.max_node)
+ if len(nets) != args.check_N:
+ raise ValueError(
+ "Pre-num-check failed : {:} vs {:}".format(len(nets), args.check_N)
+ )
+
+ save_dir = Path(args.base_save_dir)
+ simplify(
+ save_dir,
+ args.save_name,
+ nets,
+ args.check_N,
+ {"name": "infer.tiny", "channel": args.channel, "num_cells": args.num_cells},
+ )
diff --git a/AutoDL-Projects/exps/NATS-Bench/tss-collect.py b/AutoDL-Projects/exps/NATS-Bench/tss-collect.py
new file mode 100644
index 0000000..af06d43
--- /dev/null
+++ b/AutoDL-Projects/exps/NATS-Bench/tss-collect.py
@@ -0,0 +1,461 @@
+##############################################################################
+# NATS-Bench: Benchmarking NAS Algorithms for Architecture Topology and Size #
+##############################################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020.08 #
+##############################################################################
+# This file is used to re-orangize all checkpoints (created by main-tss.py) #
+# into a single benchmark file. Besides, for each trial, we will merge the #
+# information of all its trials into a single file. #
+# #
+# Usage: #
+# python exps/NATS-Bench/tss-collect.py #
+##############################################################################
+import os, re, sys, time, shutil, random, argparse, collections
+import numpy as np
+from copy import deepcopy
+import torch
+from tqdm import tqdm
+from pathlib import Path
+from collections import defaultdict, OrderedDict
+from typing import Dict, Any, Text, List
+
+from xautodl.log_utils import AverageMeter, time_string, convert_secs2time
+from xautodl.config_utils import load_config, dict2config
+from xautodl.datasets import get_datasets
+from xautodl.models import CellStructure, get_cell_based_tiny_net, get_search_spaces
+from xautodl.procedures import (
+ bench_pure_evaluate as pure_evaluate,
+ get_nas_bench_loaders,
+)
+from xautodl.utils import get_md5_file
+from nats_bench import pickle_save, pickle_load, ArchResults, ResultsCount
+from nas_201_api import NASBench201API
+
+
+api = NASBench201API(
+ "{:}/.torch/NAS-Bench-201-v1_0-e61699.pth".format(os.environ["HOME"])
+)
+
+NATS_TSS_BASE_NAME = "NATS-tss-v1_0" # 2020.08.28
+
+
+def create_result_count(
+ used_seed: int,
+ dataset: Text,
+ arch_config: Dict[Text, Any],
+ results: Dict[Text, Any],
+ dataloader_dict: Dict[Text, Any],
+) -> ResultsCount:
+ xresult = ResultsCount(
+ dataset,
+ results["net_state_dict"],
+ results["train_acc1es"],
+ results["train_losses"],
+ results["param"],
+ results["flop"],
+ arch_config,
+ used_seed,
+ results["total_epoch"],
+ None,
+ )
+ net_config = dict2config(
+ {
+ "name": "infer.tiny",
+ "C": arch_config["channel"],
+ "N": arch_config["num_cells"],
+ "genotype": CellStructure.str2structure(arch_config["arch_str"]),
+ "num_classes": arch_config["class_num"],
+ },
+ None,
+ )
+ if "train_times" in results: # new version
+ xresult.update_train_info(
+ results["train_acc1es"],
+ results["train_acc5es"],
+ results["train_losses"],
+ results["train_times"],
+ )
+ xresult.update_eval(
+ results["valid_acc1es"], results["valid_losses"], results["valid_times"]
+ )
+ else:
+ network = get_cell_based_tiny_net(net_config)
+ network.load_state_dict(xresult.get_net_param())
+ if dataset == "cifar10-valid":
+ xresult.update_OLD_eval(
+ "x-valid", results["valid_acc1es"], results["valid_losses"]
+ )
+ loss, top1, top5, latencies = pure_evaluate(
+ dataloader_dict["{:}@{:}".format("cifar10", "test")], network.cuda()
+ )
+ xresult.update_OLD_eval(
+ "ori-test",
+ {results["total_epoch"] - 1: top1},
+ {results["total_epoch"] - 1: loss},
+ )
+ xresult.update_latency(latencies)
+ elif dataset == "cifar10":
+ xresult.update_OLD_eval(
+ "ori-test", results["valid_acc1es"], results["valid_losses"]
+ )
+ loss, top1, top5, latencies = pure_evaluate(
+ dataloader_dict["{:}@{:}".format(dataset, "test")], network.cuda()
+ )
+ xresult.update_latency(latencies)
+ elif dataset == "cifar100" or dataset == "ImageNet16-120":
+ xresult.update_OLD_eval(
+ "ori-test", results["valid_acc1es"], results["valid_losses"]
+ )
+ loss, top1, top5, latencies = pure_evaluate(
+ dataloader_dict["{:}@{:}".format(dataset, "valid")], network.cuda()
+ )
+ xresult.update_OLD_eval(
+ "x-valid",
+ {results["total_epoch"] - 1: top1},
+ {results["total_epoch"] - 1: loss},
+ )
+ loss, top1, top5, latencies = pure_evaluate(
+ dataloader_dict["{:}@{:}".format(dataset, "test")], network.cuda()
+ )
+ xresult.update_OLD_eval(
+ "x-test",
+ {results["total_epoch"] - 1: top1},
+ {results["total_epoch"] - 1: loss},
+ )
+ xresult.update_latency(latencies)
+ else:
+ raise ValueError("invalid dataset name : {:}".format(dataset))
+ return xresult
+
+
+def account_one_arch(arch_index, arch_str, checkpoints, datasets, dataloader_dict):
+ information = ArchResults(arch_index, arch_str)
+
+ for checkpoint_path in checkpoints:
+ checkpoint = torch.load(checkpoint_path, map_location="cpu")
+ used_seed = checkpoint_path.name.split("-")[-1].split(".")[0]
+ ok_dataset = 0
+ for dataset in datasets:
+ if dataset not in checkpoint:
+ print(
+ "Can not find {:} in arch-{:} from {:}".format(
+ dataset, arch_index, checkpoint_path
+ )
+ )
+ continue
+ else:
+ ok_dataset += 1
+ results = checkpoint[dataset]
+ assert results[
+ "finish-train"
+ ], "This {:} arch seed={:} does not finish train on {:} ::: {:}".format(
+ arch_index, used_seed, dataset, checkpoint_path
+ )
+ arch_config = {
+ "channel": results["channel"],
+ "num_cells": results["num_cells"],
+ "arch_str": arch_str,
+ "class_num": results["config"]["class_num"],
+ }
+
+ xresult = create_result_count(
+ used_seed, dataset, arch_config, results, dataloader_dict
+ )
+ information.update(dataset, int(used_seed), xresult)
+ if ok_dataset == 0:
+ raise ValueError("{:} does not find any data".format(checkpoint_path))
+ return information
+
+
+def correct_time_related_info(arch_index: int, arch_infos: Dict[Text, ArchResults]):
+ # calibrate the latency based on NAS-Bench-201-v1_0-e61699.pth
+ cifar010_latency = (
+ api.get_latency(arch_index, "cifar10-valid", hp="200")
+ + api.get_latency(arch_index, "cifar10", hp="200")
+ ) / 2
+ cifar100_latency = api.get_latency(arch_index, "cifar100", hp="200")
+ image_latency = api.get_latency(arch_index, "ImageNet16-120", hp="200")
+ for hp, arch_info in arch_infos.items():
+ arch_info.reset_latency("cifar10-valid", None, cifar010_latency)
+ arch_info.reset_latency("cifar10", None, cifar010_latency)
+ arch_info.reset_latency("cifar100", None, cifar100_latency)
+ arch_info.reset_latency("ImageNet16-120", None, image_latency)
+
+ train_per_epoch_time = list(
+ arch_infos["12"].query("cifar10-valid", 777).train_times.values()
+ )
+ train_per_epoch_time = sum(train_per_epoch_time) / len(train_per_epoch_time)
+ eval_ori_test_time, eval_x_valid_time = [], []
+ for key, value in arch_infos["12"].query("cifar10-valid", 777).eval_times.items():
+ if key.startswith("ori-test@"):
+ eval_ori_test_time.append(value)
+ elif key.startswith("x-valid@"):
+ eval_x_valid_time.append(value)
+ else:
+ raise ValueError("-- {:} --".format(key))
+ eval_ori_test_time, eval_x_valid_time = float(np.mean(eval_ori_test_time)), float(
+ np.mean(eval_x_valid_time)
+ )
+ nums = {
+ "ImageNet16-120-train": 151700,
+ "ImageNet16-120-valid": 3000,
+ "ImageNet16-120-test": 6000,
+ "cifar10-valid-train": 25000,
+ "cifar10-valid-valid": 25000,
+ "cifar10-train": 50000,
+ "cifar10-test": 10000,
+ "cifar100-train": 50000,
+ "cifar100-test": 10000,
+ "cifar100-valid": 5000,
+ }
+ eval_per_sample = (eval_ori_test_time + eval_x_valid_time) / (
+ nums["cifar10-valid-valid"] + nums["cifar10-test"]
+ )
+ for hp, arch_info in arch_infos.items():
+ arch_info.reset_pseudo_train_times(
+ "cifar10-valid",
+ None,
+ train_per_epoch_time
+ / nums["cifar10-valid-train"]
+ * nums["cifar10-valid-train"],
+ )
+ arch_info.reset_pseudo_train_times(
+ "cifar10",
+ None,
+ train_per_epoch_time / nums["cifar10-valid-train"] * nums["cifar10-train"],
+ )
+ arch_info.reset_pseudo_train_times(
+ "cifar100",
+ None,
+ train_per_epoch_time / nums["cifar10-valid-train"] * nums["cifar100-train"],
+ )
+ arch_info.reset_pseudo_train_times(
+ "ImageNet16-120",
+ None,
+ train_per_epoch_time
+ / nums["cifar10-valid-train"]
+ * nums["ImageNet16-120-train"],
+ )
+ arch_info.reset_pseudo_eval_times(
+ "cifar10-valid",
+ None,
+ "x-valid",
+ eval_per_sample * nums["cifar10-valid-valid"],
+ )
+ arch_info.reset_pseudo_eval_times(
+ "cifar10-valid", None, "ori-test", eval_per_sample * nums["cifar10-test"]
+ )
+ arch_info.reset_pseudo_eval_times(
+ "cifar10", None, "ori-test", eval_per_sample * nums["cifar10-test"]
+ )
+ arch_info.reset_pseudo_eval_times(
+ "cifar100", None, "x-valid", eval_per_sample * nums["cifar100-valid"]
+ )
+ arch_info.reset_pseudo_eval_times(
+ "cifar100", None, "x-test", eval_per_sample * nums["cifar100-valid"]
+ )
+ arch_info.reset_pseudo_eval_times(
+ "cifar100", None, "ori-test", eval_per_sample * nums["cifar100-test"]
+ )
+ arch_info.reset_pseudo_eval_times(
+ "ImageNet16-120",
+ None,
+ "x-valid",
+ eval_per_sample * nums["ImageNet16-120-valid"],
+ )
+ arch_info.reset_pseudo_eval_times(
+ "ImageNet16-120",
+ None,
+ "x-test",
+ eval_per_sample * nums["ImageNet16-120-valid"],
+ )
+ arch_info.reset_pseudo_eval_times(
+ "ImageNet16-120",
+ None,
+ "ori-test",
+ eval_per_sample * nums["ImageNet16-120-test"],
+ )
+ return arch_infos
+
+
+def simplify(save_dir, save_name, nets, total, sup_config):
+ dataloader_dict = get_nas_bench_loaders(6)
+ hps, seeds = ["12", "200"], set()
+ for hp in hps:
+ sub_save_dir = save_dir / "raw-data-{:}".format(hp)
+ ckps = sorted(list(sub_save_dir.glob("arch-*-seed-*.pth")))
+ seed2names = defaultdict(list)
+ for ckp in ckps:
+ parts = re.split("-|\.", ckp.name)
+ seed2names[parts[3]].append(ckp.name)
+ print("DIR : {:}".format(sub_save_dir))
+ nums = []
+ for seed, xlist in seed2names.items():
+ seeds.add(seed)
+ nums.append(len(xlist))
+ print(" [seed={:}] there are {:} checkpoints.".format(seed, len(xlist)))
+ assert (
+ len(nets) == total == max(nums)
+ ), "there are some missed files : {:} vs {:}".format(max(nums), total)
+ print("{:} start simplify the checkpoint.".format(time_string()))
+
+ datasets = ("cifar10-valid", "cifar10", "cifar100", "ImageNet16-120")
+
+ # Create the directory to save the processed data
+ # full_save_dir contains all benchmark files with trained weights.
+ # simplify_save_dir contains all benchmark files without trained weights.
+ full_save_dir = save_dir / (save_name + "-FULL")
+ simple_save_dir = save_dir / (save_name + "-SIMPLIFY")
+ full_save_dir.mkdir(parents=True, exist_ok=True)
+ simple_save_dir.mkdir(parents=True, exist_ok=True)
+ # all data in memory
+ arch2infos, evaluated_indexes = dict(), set()
+ end_time, arch_time = time.time(), AverageMeter()
+ # save the meta information
+ temp_final_infos = {
+ "meta_archs": nets,
+ "total_archs": total,
+ "arch2infos": None,
+ "evaluated_indexes": set(),
+ }
+ pickle_save(temp_final_infos, str(full_save_dir / "meta.pickle"))
+ pickle_save(temp_final_infos, str(simple_save_dir / "meta.pickle"))
+
+ for index in tqdm(range(total)):
+ arch_str = nets[index]
+ hp2info = OrderedDict()
+
+ full_save_path = full_save_dir / "{:06d}.pickle".format(index)
+ simple_save_path = simple_save_dir / "{:06d}.pickle".format(index)
+ for hp in hps:
+ sub_save_dir = save_dir / "raw-data-{:}".format(hp)
+ ckps = [
+ sub_save_dir / "arch-{:06d}-seed-{:}.pth".format(index, seed)
+ for seed in seeds
+ ]
+ ckps = [x for x in ckps if x.exists()]
+ if len(ckps) == 0:
+ raise ValueError("Invalid data : index={:}, hp={:}".format(index, hp))
+
+ arch_info = account_one_arch(
+ index, arch_str, ckps, datasets, dataloader_dict
+ )
+ hp2info[hp] = arch_info
+
+ hp2info = correct_time_related_info(index, hp2info)
+ evaluated_indexes.add(index)
+
+ to_save_data = OrderedDict(
+ {"12": hp2info["12"].state_dict(), "200": hp2info["200"].state_dict()}
+ )
+ pickle_save(to_save_data, str(full_save_path))
+
+ for hp in hps:
+ hp2info[hp].clear_params()
+ to_save_data = OrderedDict(
+ {"12": hp2info["12"].state_dict(), "200": hp2info["200"].state_dict()}
+ )
+ pickle_save(to_save_data, str(simple_save_path))
+ arch2infos[index] = to_save_data
+ # measure elapsed time
+ arch_time.update(time.time() - end_time)
+ end_time = time.time()
+ need_time = "{:}".format(
+ convert_secs2time(arch_time.avg * (total - index - 1), True)
+ )
+ # print('{:} {:06d}/{:06d} : still need {:}'.format(time_string(), index, total, need_time))
+ print("{:} {:} done.".format(time_string(), save_name))
+ final_infos = {
+ "meta_archs": nets,
+ "total_archs": total,
+ "arch2infos": arch2infos,
+ "evaluated_indexes": evaluated_indexes,
+ }
+ save_file_name = save_dir / "{:}.pickle".format(save_name)
+ pickle_save(final_infos, str(save_file_name))
+ # move the benchmark file to a new path
+ hd5sum = get_md5_file(str(save_file_name) + ".pbz2")
+ hd5_file_name = save_dir / "{:}-{:}.pickle.pbz2".format(NATS_TSS_BASE_NAME, hd5sum)
+ shutil.move(str(save_file_name) + ".pbz2", hd5_file_name)
+ print(
+ "Save {:} / {:} architecture results into {:} -> {:}.".format(
+ len(evaluated_indexes), total, save_file_name, hd5_file_name
+ )
+ )
+ # move the directory to a new path
+ hd5_full_save_dir = save_dir / "{:}-{:}-full".format(NATS_TSS_BASE_NAME, hd5sum)
+ hd5_simple_save_dir = save_dir / "{:}-{:}-simple".format(NATS_TSS_BASE_NAME, hd5sum)
+ shutil.move(full_save_dir, hd5_full_save_dir)
+ shutil.move(simple_save_dir, hd5_simple_save_dir)
+ # save the meta information for simple and full
+ # final_infos['arch2infos'] = None
+ # final_infos['evaluated_indexes'] = set()
+
+
+def traverse_net(max_node):
+ aa_nas_bench_ss = get_search_spaces("cell", "nats-bench")
+ archs = CellStructure.gen_all(aa_nas_bench_ss, max_node, False)
+ print(
+ "There are {:} archs vs {:}.".format(
+ len(archs), len(aa_nas_bench_ss) ** ((max_node - 1) * max_node / 2)
+ )
+ )
+
+ random.seed(88) # please do not change this line for reproducibility
+ random.shuffle(archs)
+ assert (
+ archs[0].tostr()
+ == "|avg_pool_3x3~0|+|nor_conv_1x1~0|skip_connect~1|+|nor_conv_1x1~0|skip_connect~1|skip_connect~2|"
+ ), "please check the 0-th architecture : {:}".format(archs[0])
+ assert (
+ archs[9].tostr()
+ == "|avg_pool_3x3~0|+|none~0|none~1|+|skip_connect~0|none~1|nor_conv_3x3~2|"
+ ), "please check the 9-th architecture : {:}".format(archs[9])
+ assert (
+ archs[123].tostr()
+ == "|avg_pool_3x3~0|+|avg_pool_3x3~0|nor_conv_1x1~1|+|none~0|avg_pool_3x3~1|nor_conv_3x3~2|"
+ ), "please check the 123-th architecture : {:}".format(archs[123])
+ return [x.tostr() for x in archs]
+
+
+if __name__ == "__main__":
+
+ parser = argparse.ArgumentParser(
+ description="NATS-Bench (topology search space)",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ )
+ parser.add_argument(
+ "--base_save_dir",
+ type=str,
+ default="./output/NATS-Bench-topology",
+ help="The base-name of folder to save checkpoints and log.",
+ )
+ parser.add_argument(
+ "--max_node", type=int, default=4, help="The maximum node in a cell."
+ )
+ parser.add_argument(
+ "--channel", type=int, default=16, help="The number of channels."
+ )
+ parser.add_argument(
+ "--num_cells", type=int, default=5, help="The number of cells in one stage."
+ )
+ parser.add_argument("--check_N", type=int, default=15625, help="For safety.")
+ parser.add_argument(
+ "--save_name", type=str, default="process", help="The save directory."
+ )
+ args = parser.parse_args()
+
+ nets = traverse_net(args.max_node)
+ if len(nets) != args.check_N:
+ raise ValueError(
+ "Pre-num-check failed : {:} vs {:}".format(len(nets), args.check_N)
+ )
+
+ save_dir = Path(args.base_save_dir)
+ simplify(
+ save_dir,
+ args.save_name,
+ nets,
+ args.check_N,
+ {"name": "infer.tiny", "channel": args.channel, "num_cells": args.num_cells},
+ )
diff --git a/AutoDL-Projects/exps/NATS-Bench/tss-file-manager.py b/AutoDL-Projects/exps/NATS-Bench/tss-file-manager.py
new file mode 100644
index 0000000..5ac6f92
--- /dev/null
+++ b/AutoDL-Projects/exps/NATS-Bench/tss-file-manager.py
@@ -0,0 +1,105 @@
+##############################################################################
+# NATS-Bench: Benchmarking NAS Algorithms for Architecture Topology and Size #
+##############################################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020.08 #
+##############################################################################
+# Usage: python exps/NATS-Bench/tss-file-manager.py --mode check #
+##############################################################################
+import os, sys, time, torch, argparse
+from typing import List, Text, Dict, Any
+from shutil import copyfile
+from collections import defaultdict
+from copy import deepcopy
+from pathlib import Path
+
+from xautodl.config_utils import dict2config, load_config
+from xautodl.procedures import bench_evaluate_for_seed
+from xautodl.procedures import get_machine_info
+from xautodl.datasets import get_datasets
+from xautodl.log_utils import Logger, AverageMeter, time_string, convert_secs2time
+
+
+def obtain_valid_ckp(save_dir: Text, total: int, possible_seeds: List[int]):
+ seed2ckps = defaultdict(list)
+ miss2ckps = defaultdict(list)
+ for i in range(total):
+ for seed in possible_seeds:
+ path = os.path.join(save_dir, "arch-{:06d}-seed-{:04d}.pth".format(i, seed))
+ if os.path.exists(path):
+ seed2ckps[seed].append(i)
+ else:
+ miss2ckps[seed].append(i)
+ for seed, xlist in seed2ckps.items():
+ print(
+ "[{:}] [seed={:}] has {:5d}/{:5d} | miss {:5d}/{:5d}".format(
+ save_dir, seed, len(xlist), total, total - len(xlist), total
+ )
+ )
+ return dict(seed2ckps), dict(miss2ckps)
+
+
+def copy_data(source_dir, target_dir, meta_path):
+ target_dir = Path(target_dir)
+ target_dir.mkdir(parents=True, exist_ok=True)
+ miss2ckps = torch.load(meta_path)["miss2ckps"]
+ s2t = {}
+ for seed, xlist in miss2ckps.items():
+ for i in xlist:
+ file_name = "arch-{:06d}-seed-{:04d}.pth".format(i, seed)
+ source_path = os.path.join(source_dir, file_name)
+ target_path = os.path.join(target_dir, file_name)
+ if os.path.exists(source_path):
+ s2t[source_path] = target_path
+ print(
+ "Map from {:} to {:}, find {:} missed ckps.".format(
+ source_dir, target_dir, len(s2t)
+ )
+ )
+ for s, t in s2t.items():
+ copyfile(s, t)
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(
+ description="NATS-Bench (topology search space) file manager.",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ )
+ parser.add_argument(
+ "--mode",
+ type=str,
+ required=True,
+ choices=["check", "copy"],
+ help="The script mode.",
+ )
+ parser.add_argument(
+ "--save_dir",
+ type=str,
+ default="output/NATS-Bench-topology",
+ help="Folder to save checkpoints and log.",
+ )
+ parser.add_argument("--check_N", type=int, default=15625, help="For safety.")
+ # use for train the model
+ args = parser.parse_args()
+ possible_configs = ["12", "200"]
+ possible_seedss = [[111, 777], [777, 888, 999]]
+ if args.mode == "check":
+ for config, possible_seeds in zip(possible_configs, possible_seedss):
+ cur_save_dir = "{:}/raw-data-{:}".format(args.save_dir, config)
+ seed2ckps, miss2ckps = obtain_valid_ckp(
+ cur_save_dir, args.check_N, possible_seeds
+ )
+ torch.save(
+ dict(seed2ckps=seed2ckps, miss2ckps=miss2ckps),
+ "{:}/meta-{:}.pth".format(args.save_dir, config),
+ )
+ elif args.mode == "copy":
+ for config in possible_configs:
+ cur_save_dir = "{:}/raw-data-{:}".format(args.save_dir, config)
+ cur_copy_dir = "{:}/copy-{:}".format(args.save_dir, config)
+ cur_meta_path = "{:}/meta-{:}.pth".format(args.save_dir, config)
+ if os.path.exists(cur_meta_path):
+ copy_data(cur_save_dir, cur_copy_dir, cur_meta_path)
+ else:
+ print("Do not find : {:}".format(cur_meta_path))
+ else:
+ raise ValueError("invalid mode : {:}".format(args.mode))
diff --git a/AutoDL-Projects/exps/NATS-algos/README.md b/AutoDL-Projects/exps/NATS-algos/README.md
new file mode 100644
index 0000000..b4b2e39
--- /dev/null
+++ b/AutoDL-Projects/exps/NATS-algos/README.md
@@ -0,0 +1,29 @@
+# NAS Algorithms evaluated in [NATS-Bench](https://arxiv.org/abs/2009.00437)
+
+The Python files in this folder are used to re-produce the results in ``NATS-Bench: Benchmarking NAS Algorithms for Architecture Topology and Size''.
+
+- [`search-size.py`](https://github.com/D-X-Y/AutoDL-Projects/blob/main/exps/NATS-algos/search-size.py) contains codes for weight-sharing-based search on the size search space.
+- [`search-cell.py`](https://github.com/D-X-Y/AutoDL-Projects/blob/main/exps/NATS-algos/search-cell.py) contains codes for weight-sharing-based search on the topology search space.
+- [`bohb.py`](https://github.com/D-X-Y/AutoDL-Projects/blob/main/exps/NATS-algos/bohb.py) contains the BOHB algorithm for both size and topology search spaces.
+- [`random_wo_share.py`](https://github.com/D-X-Y/AutoDL-Projects/blob/main/exps/NATS-algos/random_wo_share.py) contains the random search algorithm for both search spaces.
+- [`regularized_ea.py`](https://github.com/D-X-Y/AutoDL-Projects/blob/main/exps/NATS-algos/regularized_ea.py) contains the REA algorithm for both search spaces.
+- [`reinforce.py`](https://github.com/D-X-Y/AutoDL-Projects/blob/main/exps/NATS-algos/reinforce.py) contains the REINFORCE algorithm for both search spaces.
+
+## Requirements
+
+- `nats_bench`>=v1.2 : you can use `pip install nats_bench` to install or from [sources](https://github.com/D-X-Y/NATS-Bench)
+- `hpbandster` : if you want to run BOHB
+
+## Citation
+
+If you find that this project helps your research, please consider citing the related paper:
+```
+@article{dong2021nats,
+ title = {{NATS-Bench}: Benchmarking NAS Algorithms for Architecture Topology and Size},
+ author = {Dong, Xuanyi and Liu, Lu and Musial, Katarzyna and Gabrys, Bogdan},
+ doi = {10.1109/TPAMI.2021.3054824},
+ journal = {IEEE Transactions on Pattern Analysis and Machine Intelligence (TPAMI)},
+ year = {2021},
+ note = {\mbox{doi}:\url{10.1109/TPAMI.2021.3054824}}
+}
+```
diff --git a/AutoDL-Projects/exps/NATS-algos/bohb.py b/AutoDL-Projects/exps/NATS-algos/bohb.py
new file mode 100644
index 0000000..23dd3ee
--- /dev/null
+++ b/AutoDL-Projects/exps/NATS-algos/bohb.py
@@ -0,0 +1,276 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020 #
+###################################################################
+# BOHB: Robust and Efficient Hyperparameter Optimization at Scale #
+# required to install hpbandster ##################################
+# pip install hpbandster ##################################
+###################################################################
+# OMP_NUM_THREADS=4 python exps/NATS-algos/bohb.py --search_space tss --dataset cifar10 --num_samples 4 --random_fraction 0.0 --bandwidth_factor 3 --rand_seed 1
+# OMP_NUM_THREADS=4 python exps/NATS-algos/bohb.py --search_space sss --dataset cifar10 --num_samples 4 --random_fraction 0.0 --bandwidth_factor 3 --rand_seed 1
+###################################################################
+import os, sys, time, random, argparse, collections
+from copy import deepcopy
+import torch
+
+from xautodl.config_utils import load_config
+from xautodl.datasets import get_datasets, SearchDataset
+from xautodl.procedures import prepare_seed, prepare_logger
+from xautodl.log_utils import AverageMeter, time_string, convert_secs2time
+from xautodl.models import CellStructure, get_search_spaces
+from nats_bench import create
+
+# BOHB: Robust and Efficient Hyperparameter Optimization at Scale, ICML 2018
+import ConfigSpace
+from hpbandster.optimizers.bohb import BOHB
+import hpbandster.core.nameserver as hpns
+from hpbandster.core.worker import Worker
+
+
+def get_topology_config_space(search_space, max_nodes=4):
+ cs = ConfigSpace.ConfigurationSpace()
+ # edge2index = {}
+ for i in range(1, max_nodes):
+ for j in range(i):
+ node_str = "{:}<-{:}".format(i, j)
+ cs.add_hyperparameter(
+ ConfigSpace.CategoricalHyperparameter(node_str, search_space)
+ )
+ return cs
+
+
+def get_size_config_space(search_space):
+ cs = ConfigSpace.ConfigurationSpace()
+ for ilayer in range(search_space["numbers"]):
+ node_str = "layer-{:}".format(ilayer)
+ cs.add_hyperparameter(
+ ConfigSpace.CategoricalHyperparameter(node_str, search_space["candidates"])
+ )
+ return cs
+
+
+def config2topology_func(max_nodes=4):
+ def config2structure(config):
+ genotypes = []
+ for i in range(1, max_nodes):
+ xlist = []
+ for j in range(i):
+ node_str = "{:}<-{:}".format(i, j)
+ op_name = config[node_str]
+ xlist.append((op_name, j))
+ genotypes.append(tuple(xlist))
+ return CellStructure(genotypes)
+
+ return config2structure
+
+
+def config2size_func(search_space):
+ def config2structure(config):
+ channels = []
+ for ilayer in range(search_space["numbers"]):
+ node_str = "layer-{:}".format(ilayer)
+ channels.append(str(config[node_str]))
+ return ":".join(channels)
+
+ return config2structure
+
+
+class MyWorker(Worker):
+ def __init__(self, *args, convert_func=None, dataset=None, api=None, **kwargs):
+ super().__init__(*args, **kwargs)
+ self.convert_func = convert_func
+ self._dataset = dataset
+ self._api = api
+ self.total_times = []
+ self.trajectory = []
+
+ def compute(self, config, budget, **kwargs):
+ arch = self.convert_func(config)
+ accuracy, latency, time_cost, total_time = self._api.simulate_train_eval(
+ arch, self._dataset, iepoch=int(budget) - 1, hp="12"
+ )
+ self.trajectory.append((accuracy, arch))
+ self.total_times.append(total_time)
+ return {"loss": 100 - accuracy, "info": self._api.query_index_by_arch(arch)}
+
+
+def main(xargs, api):
+ torch.set_num_threads(4)
+ prepare_seed(xargs.rand_seed)
+ logger = prepare_logger(args)
+
+ logger.log("{:} use api : {:}".format(time_string(), api))
+ api.reset_time()
+ search_space = get_search_spaces(xargs.search_space, "nats-bench")
+ if xargs.search_space == "tss":
+ cs = get_topology_config_space(search_space)
+ config2structure = config2topology_func()
+ else:
+ cs = get_size_config_space(search_space)
+ config2structure = config2size_func(search_space)
+
+ hb_run_id = "0"
+
+ NS = hpns.NameServer(run_id=hb_run_id, host="localhost", port=0)
+ ns_host, ns_port = NS.start()
+ num_workers = 1
+
+ workers = []
+ for i in range(num_workers):
+ w = MyWorker(
+ nameserver=ns_host,
+ nameserver_port=ns_port,
+ convert_func=config2structure,
+ dataset=xargs.dataset,
+ api=api,
+ run_id=hb_run_id,
+ id=i,
+ )
+ w.run(background=True)
+ workers.append(w)
+
+ start_time = time.time()
+ bohb = BOHB(
+ configspace=cs,
+ run_id=hb_run_id,
+ eta=3,
+ min_budget=1,
+ max_budget=12,
+ nameserver=ns_host,
+ nameserver_port=ns_port,
+ num_samples=xargs.num_samples,
+ random_fraction=xargs.random_fraction,
+ bandwidth_factor=xargs.bandwidth_factor,
+ ping_interval=10,
+ min_bandwidth=xargs.min_bandwidth,
+ )
+
+ results = bohb.run(xargs.n_iters, min_n_workers=num_workers)
+
+ bohb.shutdown(shutdown_workers=True)
+ NS.shutdown()
+
+ # print('There are {:} runs.'.format(len(results.get_all_runs())))
+ # workers[0].total_times
+ # workers[0].trajectory
+ current_best_index = []
+ for idx in range(len(workers[0].trajectory)):
+ trajectory = workers[0].trajectory[: idx + 1]
+ arch = max(trajectory, key=lambda x: x[0])[1]
+ current_best_index.append(api.query_index_by_arch(arch))
+
+ best_arch = max(workers[0].trajectory, key=lambda x: x[0])[1]
+ logger.log(
+ "Best found configuration: {:} within {:.3f} s".format(
+ best_arch, workers[0].total_times[-1]
+ )
+ )
+ info = api.query_info_str_by_arch(
+ best_arch, "200" if xargs.search_space == "tss" else "90"
+ )
+ logger.log("{:}".format(info))
+ logger.log("-" * 100)
+ logger.close()
+
+ return logger.log_dir, current_best_index, workers[0].total_times
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(
+ "BOHB: Robust and Efficient Hyperparameter Optimization at Scale"
+ )
+ parser.add_argument(
+ "--dataset",
+ type=str,
+ choices=["cifar10", "cifar100", "ImageNet16-120"],
+ help="Choose between Cifar10/100 and ImageNet-16.",
+ )
+ # general arg
+ parser.add_argument(
+ "--search_space",
+ type=str,
+ choices=["tss", "sss"],
+ help="Choose the search space.",
+ )
+ parser.add_argument(
+ "--time_budget",
+ type=int,
+ default=20000,
+ help="The total time cost budge for searching (in seconds).",
+ )
+ parser.add_argument(
+ "--loops_if_rand", type=int, default=500, help="The total runs for evaluation."
+ )
+ # BOHB
+ parser.add_argument(
+ "--strategy",
+ default="sampling",
+ type=str,
+ nargs="?",
+ help="optimization strategy for the acquisition function",
+ )
+ parser.add_argument(
+ "--min_bandwidth",
+ default=0.3,
+ type=float,
+ nargs="?",
+ help="minimum bandwidth for KDE",
+ )
+ parser.add_argument(
+ "--num_samples",
+ default=64,
+ type=int,
+ nargs="?",
+ help="number of samples for the acquisition function",
+ )
+ parser.add_argument(
+ "--random_fraction",
+ default=0.33,
+ type=float,
+ nargs="?",
+ help="fraction of random configurations",
+ )
+ parser.add_argument(
+ "--bandwidth_factor",
+ default=3,
+ type=int,
+ nargs="?",
+ help="factor multiplied to the bandwidth",
+ )
+ parser.add_argument(
+ "--n_iters",
+ default=300,
+ type=int,
+ nargs="?",
+ help="number of iterations for optimization method",
+ )
+ # log
+ parser.add_argument(
+ "--save_dir",
+ type=str,
+ default="./output/search",
+ help="Folder to save checkpoints and log.",
+ )
+ parser.add_argument("--rand_seed", type=int, default=-1, help="manual seed")
+ args = parser.parse_args()
+
+ api = create(None, args.search_space, fast_mode=False, verbose=False)
+
+ args.save_dir = os.path.join(
+ "{:}-{:}".format(args.save_dir, args.search_space),
+ "{:}-T{:}".format(args.dataset, args.time_budget),
+ "BOHB",
+ )
+ print("save-dir : {:}".format(args.save_dir))
+
+ if args.rand_seed < 0:
+ save_dir, all_info = None, collections.OrderedDict()
+ for i in range(args.loops_if_rand):
+ print("{:} : {:03d}/{:03d}".format(time_string(), i, args.loops_if_rand))
+ args.rand_seed = random.randint(1, 100000)
+ save_dir, all_archs, all_total_times = main(args, api)
+ all_info[i] = {"all_archs": all_archs, "all_total_times": all_total_times}
+ save_path = save_dir / "results.pth"
+ print("save into {:}".format(save_path))
+ torch.save(all_info, save_path)
+ else:
+ main(args, api)
diff --git a/AutoDL-Projects/exps/NATS-algos/random_wo_share.py b/AutoDL-Projects/exps/NATS-algos/random_wo_share.py
new file mode 100644
index 0000000..ac43059
--- /dev/null
+++ b/AutoDL-Projects/exps/NATS-algos/random_wo_share.py
@@ -0,0 +1,156 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020 #
+##############################################################################
+# Random Search for Hyper-Parameter Optimization, JMLR 2012 ##################
+##############################################################################
+# python ./exps/NATS-algos/random_wo_share.py --dataset cifar10 --search_space tss
+# python ./exps/NATS-algos/random_wo_share.py --dataset cifar100 --search_space tss
+# python ./exps/NATS-algos/random_wo_share.py --dataset ImageNet16-120 --search_space tss
+##############################################################################
+import os, sys, time, glob, random, argparse
+import numpy as np, collections
+from copy import deepcopy
+import torch
+import torch.nn as nn
+
+from xautodl.config_utils import load_config, dict2config, configure2str
+from xautodl.datasets import get_datasets, SearchDataset
+from xautodl.procedures import (
+ prepare_seed,
+ prepare_logger,
+ save_checkpoint,
+ copy_checkpoint,
+ get_optim_scheduler,
+)
+from xautodl.utils import get_model_infos, obtain_accuracy
+from xautodl.log_utils import AverageMeter, time_string, convert_secs2time
+from xautodl.models import CellStructure, get_search_spaces
+from nats_bench import create
+
+
+def random_topology_func(op_names, max_nodes=4):
+ # Return a random architecture
+ def random_architecture():
+ genotypes = []
+ for i in range(1, max_nodes):
+ xlist = []
+ for j in range(i):
+ node_str = "{:}<-{:}".format(i, j)
+ op_name = random.choice(op_names)
+ xlist.append((op_name, j))
+ genotypes.append(tuple(xlist))
+ return CellStructure(genotypes)
+
+ return random_architecture
+
+
+def random_size_func(info):
+ # Return a random architecture
+ def random_architecture():
+ channels = []
+ for i in range(info["numbers"]):
+ channels.append(str(random.choice(info["candidates"])))
+ return ":".join(channels)
+
+ return random_architecture
+
+
+def main(xargs, api):
+ torch.set_num_threads(4)
+ prepare_seed(xargs.rand_seed)
+ logger = prepare_logger(args)
+
+ logger.log("{:} use api : {:}".format(time_string(), api))
+ api.reset_time()
+
+ search_space = get_search_spaces(xargs.search_space, "nats-bench")
+ if xargs.search_space == "tss":
+ random_arch = random_topology_func(search_space)
+ else:
+ random_arch = random_size_func(search_space)
+
+ best_arch, best_acc, total_time_cost, history = None, -1, [], []
+ current_best_index = []
+ while len(total_time_cost) == 0 or total_time_cost[-1] < xargs.time_budget:
+ arch = random_arch()
+ accuracy, _, _, total_cost = api.simulate_train_eval(
+ arch, xargs.dataset, hp="12"
+ )
+ total_time_cost.append(total_cost)
+ history.append(arch)
+ if best_arch is None or best_acc < accuracy:
+ best_acc, best_arch = accuracy, arch
+ logger.log(
+ "[{:03d}] : {:} : accuracy = {:.2f}%".format(len(history), arch, accuracy)
+ )
+ current_best_index.append(api.query_index_by_arch(best_arch))
+ logger.log(
+ "{:} best arch is {:}, accuracy = {:.2f}%, visit {:} archs with {:.1f} s.".format(
+ time_string(), best_arch, best_acc, len(history), total_time_cost[-1]
+ )
+ )
+
+ info = api.query_info_str_by_arch(
+ best_arch, "200" if xargs.search_space == "tss" else "90"
+ )
+ logger.log("{:}".format(info))
+ logger.log("-" * 100)
+ logger.close()
+ return logger.log_dir, current_best_index, total_time_cost
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser("Random NAS")
+ parser.add_argument(
+ "--dataset",
+ type=str,
+ choices=["cifar10", "cifar100", "ImageNet16-120"],
+ help="Choose between Cifar10/100 and ImageNet-16.",
+ )
+ parser.add_argument(
+ "--search_space",
+ type=str,
+ choices=["tss", "sss"],
+ help="Choose the search space.",
+ )
+
+ parser.add_argument(
+ "--time_budget",
+ type=int,
+ default=20000,
+ help="The total time cost budge for searching (in seconds).",
+ )
+ parser.add_argument(
+ "--loops_if_rand", type=int, default=500, help="The total runs for evaluation."
+ )
+ # log
+ parser.add_argument(
+ "--save_dir",
+ type=str,
+ default="./output/search",
+ help="Folder to save checkpoints and log.",
+ )
+ parser.add_argument("--rand_seed", type=int, default=-1, help="manual seed")
+ args = parser.parse_args()
+
+ api = create(None, args.search_space, fast_mode=True, verbose=False)
+
+ args.save_dir = os.path.join(
+ "{:}-{:}".format(args.save_dir, args.search_space),
+ "{:}-T{:}".format(args.dataset, args.time_budget),
+ "RANDOM",
+ )
+ print("save-dir : {:}".format(args.save_dir))
+
+ if args.rand_seed < 0:
+ save_dir, all_info = None, collections.OrderedDict()
+ for i in range(args.loops_if_rand):
+ print("{:} : {:03d}/{:03d}".format(time_string(), i, args.loops_if_rand))
+ args.rand_seed = random.randint(1, 100000)
+ save_dir, all_archs, all_total_times = main(args, api)
+ all_info[i] = {"all_archs": all_archs, "all_total_times": all_total_times}
+ save_path = save_dir / "results.pth"
+ print("save into {:}".format(save_path))
+ torch.save(all_info, save_path)
+ else:
+ main(args, api)
diff --git a/AutoDL-Projects/exps/NATS-algos/regularized_ea.py b/AutoDL-Projects/exps/NATS-algos/regularized_ea.py
new file mode 100644
index 0000000..f16dd5f
--- /dev/null
+++ b/AutoDL-Projects/exps/NATS-algos/regularized_ea.py
@@ -0,0 +1,302 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020 #
+##################################################################
+# Regularized Evolution for Image Classifier Architecture Search #
+##################################################################
+# python ./exps/NATS-algos/regularized_ea.py --dataset cifar10 --search_space tss --ea_cycles 200 --ea_population 10 --ea_sample_size 3 --rand_seed 1
+# python ./exps/NATS-algos/regularized_ea.py --dataset cifar100 --search_space tss --ea_cycles 200 --ea_population 10 --ea_sample_size 3 --rand_seed 1
+# python ./exps/NATS-algos/regularized_ea.py --dataset ImageNet16-120 --search_space tss --ea_cycles 200 --ea_population 10 --ea_sample_size 3 --rand_seed 1
+# python ./exps/NATS-algos/regularized_ea.py --dataset cifar10 --search_space sss --ea_cycles 200 --ea_population 10 --ea_sample_size 3 --rand_seed 1
+# python ./exps/NATS-algos/regularized_ea.py --dataset cifar100 --search_space sss --ea_cycles 200 --ea_population 10 --ea_sample_size 3 --rand_seed 1
+# python ./exps/NATS-algos/regularized_ea.py --dataset ImageNet16-120 --search_space sss --ea_cycles 200 --ea_population 10 --ea_sample_size 3 --rand_seed 1
+# python ./exps/NATS-algos/regularized_ea.py --dataset ${dataset} --search_space ${search_space} --time_budget ${time_budget} --ea_cycles 200 --ea_population 10 --ea_sample_size 3 --use_proxy 0
+##################################################################
+import os, sys, time, glob, random, argparse
+import numpy as np, collections
+from copy import deepcopy
+import torch
+import torch.nn as nn
+
+from xautodl.config_utils import load_config, dict2config, configure2str
+from xautodl.datasets import get_datasets, SearchDataset
+from xautodl.procedures import (
+ prepare_seed,
+ prepare_logger,
+ save_checkpoint,
+ copy_checkpoint,
+ get_optim_scheduler,
+)
+from xautodl.utils import get_model_infos, obtain_accuracy
+from xautodl.log_utils import AverageMeter, time_string, convert_secs2time
+from xautodl.models import CellStructure, get_search_spaces
+from nats_bench import create
+
+
+class Model(object):
+ def __init__(self):
+ self.arch = None
+ self.accuracy = None
+
+ def __str__(self):
+ """Prints a readable version of this bitstring."""
+ return "{:}".format(self.arch)
+
+
+def random_topology_func(op_names, max_nodes=4):
+ # Return a random architecture
+ def random_architecture():
+ genotypes = []
+ for i in range(1, max_nodes):
+ xlist = []
+ for j in range(i):
+ node_str = "{:}<-{:}".format(i, j)
+ op_name = random.choice(op_names)
+ xlist.append((op_name, j))
+ genotypes.append(tuple(xlist))
+ return CellStructure(genotypes)
+
+ return random_architecture
+
+
+def random_size_func(info):
+ # Return a random architecture
+ def random_architecture():
+ channels = []
+ for i in range(info["numbers"]):
+ channels.append(str(random.choice(info["candidates"])))
+ return ":".join(channels)
+
+ return random_architecture
+
+
+def mutate_topology_func(op_names):
+ """Computes the architecture for a child of the given parent architecture.
+ The parent architecture is cloned and mutated to produce the child architecture. The child architecture is mutated by randomly switch one operation to another.
+ """
+
+ def mutate_topology_func(parent_arch):
+ child_arch = deepcopy(parent_arch)
+ node_id = random.randint(0, len(child_arch.nodes) - 1)
+ node_info = list(child_arch.nodes[node_id])
+ snode_id = random.randint(0, len(node_info) - 1)
+ xop = random.choice(op_names)
+ while xop == node_info[snode_id][0]:
+ xop = random.choice(op_names)
+ node_info[snode_id] = (xop, node_info[snode_id][1])
+ child_arch.nodes[node_id] = tuple(node_info)
+ return child_arch
+
+ return mutate_topology_func
+
+
+def mutate_size_func(info):
+ """Computes the architecture for a child of the given parent architecture.
+ The parent architecture is cloned and mutated to produce the child architecture. The child architecture is mutated by randomly switch one operation to another.
+ """
+
+ def mutate_size_func(parent_arch):
+ child_arch = deepcopy(parent_arch)
+ child_arch = child_arch.split(":")
+ index = random.randint(0, len(child_arch) - 1)
+ child_arch[index] = str(random.choice(info["candidates"]))
+ return ":".join(child_arch)
+
+ return mutate_size_func
+
+
+def regularized_evolution(
+ cycles,
+ population_size,
+ sample_size,
+ time_budget,
+ random_arch,
+ mutate_arch,
+ api,
+ use_proxy,
+ dataset,
+):
+ """Algorithm for regularized evolution (i.e. aging evolution).
+
+ Follows "Algorithm 1" in Real et al. "Regularized Evolution for Image
+ Classifier Architecture Search".
+
+ Args:
+ cycles: the number of cycles the algorithm should run for.
+ population_size: the number of individuals to keep in the population.
+ sample_size: the number of individuals that should participate in each tournament.
+ time_budget: the upper bound of searching cost
+
+ Returns:
+ history: a list of `Model` instances, representing all the models computed
+ during the evolution experiment.
+ """
+ population = collections.deque()
+ api.reset_time()
+ history, total_time_cost = (
+ [],
+ [],
+ ) # Not used by the algorithm, only used to report results.
+ current_best_index = []
+ # Initialize the population with random models.
+ while len(population) < population_size:
+ model = Model()
+ model.arch = random_arch()
+ model.accuracy, _, _, total_cost = api.simulate_train_eval(
+ model.arch, dataset, hp="12" if use_proxy else api.full_train_epochs
+ )
+ # Append the info
+ population.append(model)
+ history.append((model.accuracy, model.arch))
+ total_time_cost.append(total_cost)
+ current_best_index.append(
+ api.query_index_by_arch(max(history, key=lambda x: x[0])[1])
+ )
+
+ # Carry out evolution in cycles. Each cycle produces a model and removes another.
+ while total_time_cost[-1] < time_budget:
+ # Sample randomly chosen models from the current population.
+ start_time, sample = time.time(), []
+ while len(sample) < sample_size:
+ # Inefficient, but written this way for clarity. In the case of neural
+ # nets, the efficiency of this line is irrelevant because training neural
+ # nets is the rate-determining step.
+ candidate = random.choice(list(population))
+ sample.append(candidate)
+
+ # The parent is the best model in the sample.
+ parent = max(sample, key=lambda i: i.accuracy)
+
+ # Create the child model and store it.
+ child = Model()
+ child.arch = mutate_arch(parent.arch)
+ child.accuracy, _, _, total_cost = api.simulate_train_eval(
+ child.arch, dataset, hp="12" if use_proxy else api.full_train_epochs
+ )
+ # Append the info
+ population.append(child)
+ history.append((child.accuracy, child.arch))
+ current_best_index.append(
+ api.query_index_by_arch(max(history, key=lambda x: x[0])[1])
+ )
+ total_time_cost.append(total_cost)
+
+ # Remove the oldest model.
+ population.popleft()
+ return history, current_best_index, total_time_cost
+
+
+def main(xargs, api):
+ torch.set_num_threads(4)
+ prepare_seed(xargs.rand_seed)
+ logger = prepare_logger(args)
+
+ search_space = get_search_spaces(xargs.search_space, "nats-bench")
+ if xargs.search_space == "tss":
+ random_arch = random_topology_func(search_space)
+ mutate_arch = mutate_topology_func(search_space)
+ else:
+ random_arch = random_size_func(search_space)
+ mutate_arch = mutate_size_func(search_space)
+
+ x_start_time = time.time()
+ logger.log("{:} use api : {:}".format(time_string(), api))
+ logger.log(
+ "-" * 30
+ + " start searching with the time budget of {:} s".format(xargs.time_budget)
+ )
+ history, current_best_index, total_times = regularized_evolution(
+ xargs.ea_cycles,
+ xargs.ea_population,
+ xargs.ea_sample_size,
+ xargs.time_budget,
+ random_arch,
+ mutate_arch,
+ api,
+ xargs.use_proxy > 0,
+ xargs.dataset,
+ )
+ logger.log(
+ "{:} regularized_evolution finish with history of {:} arch with {:.1f} s (real-cost={:.2f} s).".format(
+ time_string(), len(history), total_times[-1], time.time() - x_start_time
+ )
+ )
+ best_arch = max(history, key=lambda x: x[0])[1]
+ logger.log("{:} best arch is {:}".format(time_string(), best_arch))
+
+ info = api.query_info_str_by_arch(
+ best_arch, "200" if xargs.search_space == "tss" else "90"
+ )
+ logger.log("{:}".format(info))
+ logger.log("-" * 100)
+ logger.close()
+ return logger.log_dir, current_best_index, total_times
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser("Regularized Evolution Algorithm")
+ parser.add_argument(
+ "--dataset",
+ type=str,
+ choices=["cifar10", "cifar100", "ImageNet16-120"],
+ help="Choose between Cifar10/100 and ImageNet-16.",
+ )
+ parser.add_argument(
+ "--search_space",
+ type=str,
+ choices=["tss", "sss"],
+ help="Choose the search space.",
+ )
+ # hyperparameters for REA
+ parser.add_argument("--ea_cycles", type=int, help="The number of cycles in EA.")
+ parser.add_argument("--ea_population", type=int, help="The population size in EA.")
+ parser.add_argument("--ea_sample_size", type=int, help="The sample size in EA.")
+ parser.add_argument(
+ "--time_budget",
+ type=int,
+ default=20000,
+ help="The total time cost budge for searching (in seconds).",
+ )
+ parser.add_argument(
+ "--use_proxy",
+ type=int,
+ default=1,
+ help="Whether to use the proxy (H0) task or not.",
+ )
+ #
+ parser.add_argument(
+ "--loops_if_rand", type=int, default=500, help="The total runs for evaluation."
+ )
+ # log
+ parser.add_argument(
+ "--save_dir",
+ type=str,
+ default="./output/search",
+ help="Folder to save checkpoints and log.",
+ )
+ parser.add_argument("--rand_seed", type=int, default=-1, help="manual seed")
+ args = parser.parse_args()
+
+ api = create(None, args.search_space, fast_mode=True, verbose=False)
+
+ args.save_dir = os.path.join(
+ "{:}-{:}".format(args.save_dir, args.search_space),
+ "{:}-T{:}{:}".format(
+ args.dataset, args.time_budget, "" if args.use_proxy > 0 else "-FULL"
+ ),
+ "R-EA-SS{:}".format(args.ea_sample_size),
+ )
+ print("save-dir : {:}".format(args.save_dir))
+ print("xargs : {:}".format(args))
+
+ if args.rand_seed < 0:
+ save_dir, all_info = None, collections.OrderedDict()
+ for i in range(args.loops_if_rand):
+ print("{:} : {:03d}/{:03d}".format(time_string(), i, args.loops_if_rand))
+ args.rand_seed = random.randint(1, 100000)
+ save_dir, all_archs, all_total_times = main(args, api)
+ all_info[i] = {"all_archs": all_archs, "all_total_times": all_total_times}
+ save_path = save_dir / "results.pth"
+ print("save into {:}".format(save_path))
+ torch.save(all_info, save_path)
+ else:
+ main(args, api)
diff --git a/AutoDL-Projects/exps/NATS-algos/reinforce.py b/AutoDL-Projects/exps/NATS-algos/reinforce.py
new file mode 100644
index 0000000..38b94d3
--- /dev/null
+++ b/AutoDL-Projects/exps/NATS-algos/reinforce.py
@@ -0,0 +1,268 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020 #
+#####################################################################################################
+# modified from https://github.com/pytorch/examples/blob/master/reinforcement_learning/reinforce.py #
+#####################################################################################################
+# python ./exps/NATS-algos/reinforce.py --dataset cifar10 --search_space tss --learning_rate 0.01
+# python ./exps/NATS-algos/reinforce.py --dataset cifar100 --search_space tss --learning_rate 0.01
+# python ./exps/NATS-algos/reinforce.py --dataset ImageNet16-120 --search_space tss --learning_rate 0.01
+# python ./exps/NATS-algos/reinforce.py --dataset cifar10 --search_space sss --learning_rate 0.01
+# python ./exps/NATS-algos/reinforce.py --dataset cifar100 --search_space sss --learning_rate 0.01
+# python ./exps/NATS-algos/reinforce.py --dataset ImageNet16-120 --search_space sss --learning_rate 0.01
+#####################################################################################################
+import os, sys, time, glob, random, argparse
+import numpy as np, collections
+from copy import deepcopy
+import torch
+import torch.nn as nn
+from torch.distributions import Categorical
+
+from xautodl.config_utils import load_config, dict2config, configure2str
+from xautodl.datasets import get_datasets, SearchDataset
+from xautodl.procedures import (
+ prepare_seed,
+ prepare_logger,
+ save_checkpoint,
+ copy_checkpoint,
+ get_optim_scheduler,
+)
+from xautodl.utils import get_model_infos, obtain_accuracy
+from xautodl.log_utils import AverageMeter, time_string, convert_secs2time
+from xautodl.models import CellStructure, get_search_spaces
+from nats_bench import create
+
+
+class PolicyTopology(nn.Module):
+ def __init__(self, search_space, max_nodes=4):
+ super(PolicyTopology, self).__init__()
+ self.max_nodes = max_nodes
+ self.search_space = deepcopy(search_space)
+ self.edge2index = {}
+ for i in range(1, max_nodes):
+ for j in range(i):
+ node_str = "{:}<-{:}".format(i, j)
+ self.edge2index[node_str] = len(self.edge2index)
+ self.arch_parameters = nn.Parameter(
+ 1e-3 * torch.randn(len(self.edge2index), len(search_space))
+ )
+
+ def generate_arch(self, actions):
+ genotypes = []
+ for i in range(1, self.max_nodes):
+ xlist = []
+ for j in range(i):
+ node_str = "{:}<-{:}".format(i, j)
+ op_name = self.search_space[actions[self.edge2index[node_str]]]
+ xlist.append((op_name, j))
+ genotypes.append(tuple(xlist))
+ return CellStructure(genotypes)
+
+ def genotype(self):
+ genotypes = []
+ for i in range(1, self.max_nodes):
+ xlist = []
+ for j in range(i):
+ node_str = "{:}<-{:}".format(i, j)
+ with torch.no_grad():
+ weights = self.arch_parameters[self.edge2index[node_str]]
+ op_name = self.search_space[weights.argmax().item()]
+ xlist.append((op_name, j))
+ genotypes.append(tuple(xlist))
+ return CellStructure(genotypes)
+
+ def forward(self):
+ alphas = nn.functional.softmax(self.arch_parameters, dim=-1)
+ return alphas
+
+
+class PolicySize(nn.Module):
+ def __init__(self, search_space):
+ super(PolicySize, self).__init__()
+ self.candidates = search_space["candidates"]
+ self.numbers = search_space["numbers"]
+ self.arch_parameters = nn.Parameter(
+ 1e-3 * torch.randn(self.numbers, len(self.candidates))
+ )
+
+ def generate_arch(self, actions):
+ channels = [str(self.candidates[i]) for i in actions]
+ return ":".join(channels)
+
+ def genotype(self):
+ channels = []
+ for i in range(self.numbers):
+ index = self.arch_parameters[i].argmax().item()
+ channels.append(str(self.candidates[index]))
+ return ":".join(channels)
+
+ def forward(self):
+ alphas = nn.functional.softmax(self.arch_parameters, dim=-1)
+ return alphas
+
+
+class ExponentialMovingAverage(object):
+ """Class that maintains an exponential moving average."""
+
+ def __init__(self, momentum):
+ self._numerator = 0
+ self._denominator = 0
+ self._momentum = momentum
+
+ def update(self, value):
+ self._numerator = (
+ self._momentum * self._numerator + (1 - self._momentum) * value
+ )
+ self._denominator = self._momentum * self._denominator + (1 - self._momentum)
+
+ def value(self):
+ """Return the current value of the moving average"""
+ return self._numerator / self._denominator
+
+
+def select_action(policy):
+ probs = policy()
+ m = Categorical(probs)
+ action = m.sample()
+ # policy.saved_log_probs.append(m.log_prob(action))
+ return m.log_prob(action), action.cpu().tolist()
+
+
+def main(xargs, api):
+ # torch.set_num_threads(4)
+ prepare_seed(xargs.rand_seed)
+ logger = prepare_logger(args)
+
+ search_space = get_search_spaces(xargs.search_space, "nats-bench")
+ if xargs.search_space == "tss":
+ policy = PolicyTopology(search_space)
+ else:
+ policy = PolicySize(search_space)
+ optimizer = torch.optim.Adam(policy.parameters(), lr=xargs.learning_rate)
+ # optimizer = torch.optim.SGD(policy.parameters(), lr=xargs.learning_rate)
+ eps = np.finfo(np.float32).eps.item()
+ baseline = ExponentialMovingAverage(xargs.EMA_momentum)
+ logger.log("policy : {:}".format(policy))
+ logger.log("optimizer : {:}".format(optimizer))
+ logger.log("eps : {:}".format(eps))
+
+ # nas dataset load
+ logger.log("{:} use api : {:}".format(time_string(), api))
+ api.reset_time()
+
+ # REINFORCE
+ x_start_time = time.time()
+ logger.log(
+ "Will start searching with time budget of {:} s.".format(xargs.time_budget)
+ )
+ total_steps, total_costs, trace = 0, [], []
+ current_best_index = []
+ while len(total_costs) == 0 or total_costs[-1] < xargs.time_budget:
+ start_time = time.time()
+ log_prob, action = select_action(policy)
+ arch = policy.generate_arch(action)
+ reward, _, _, current_total_cost = api.simulate_train_eval(
+ arch, xargs.dataset, hp="12"
+ )
+ trace.append((reward, arch))
+ total_costs.append(current_total_cost)
+
+ baseline.update(reward)
+ # calculate loss
+ policy_loss = (-log_prob * (reward - baseline.value())).sum()
+ optimizer.zero_grad()
+ policy_loss.backward()
+ optimizer.step()
+ # accumulate time
+ total_steps += 1
+ logger.log(
+ "step [{:3d}] : average-reward={:.3f} : policy_loss={:.4f} : {:}".format(
+ total_steps, baseline.value(), policy_loss.item(), policy.genotype()
+ )
+ )
+ # to analyze
+ current_best_index.append(
+ api.query_index_by_arch(max(trace, key=lambda x: x[0])[1])
+ )
+ # best_arch = policy.genotype() # first version
+ best_arch = max(trace, key=lambda x: x[0])[1]
+ logger.log(
+ "REINFORCE finish with {:} steps and {:.1f} s (real cost={:.3f}).".format(
+ total_steps, total_costs[-1], time.time() - x_start_time
+ )
+ )
+ info = api.query_info_str_by_arch(
+ best_arch, "200" if xargs.search_space == "tss" else "90"
+ )
+ logger.log("{:}".format(info))
+ logger.log("-" * 100)
+ logger.close()
+
+ return logger.log_dir, current_best_index, total_costs
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser("The REINFORCE Algorithm")
+ parser.add_argument(
+ "--dataset",
+ type=str,
+ choices=["cifar10", "cifar100", "ImageNet16-120"],
+ help="Choose between Cifar10/100 and ImageNet-16.",
+ )
+ parser.add_argument(
+ "--search_space",
+ type=str,
+ choices=["tss", "sss"],
+ help="Choose the search space.",
+ )
+ parser.add_argument(
+ "--learning_rate", type=float, help="The learning rate for REINFORCE."
+ )
+ parser.add_argument(
+ "--EMA_momentum", type=float, default=0.9, help="The momentum value for EMA."
+ )
+ parser.add_argument(
+ "--time_budget",
+ type=int,
+ default=20000,
+ help="The total time cost budge for searching (in seconds).",
+ )
+ parser.add_argument(
+ "--loops_if_rand", type=int, default=500, help="The total runs for evaluation."
+ )
+ # log
+ parser.add_argument(
+ "--save_dir",
+ type=str,
+ default="./output/search",
+ help="Folder to save checkpoints and log.",
+ )
+ parser.add_argument(
+ "--arch_nas_dataset",
+ type=str,
+ help="The path to load the architecture dataset (tiny-nas-benchmark).",
+ )
+ parser.add_argument("--print_freq", type=int, help="print frequency (default: 200)")
+ parser.add_argument("--rand_seed", type=int, default=-1, help="manual seed")
+ args = parser.parse_args()
+
+ api = create(None, args.search_space, fast_mode=True, verbose=False)
+
+ args.save_dir = os.path.join(
+ "{:}-{:}".format(args.save_dir, args.search_space),
+ "{:}-T{:}".format(args.dataset, args.time_budget),
+ "REINFORCE-{:}".format(args.learning_rate),
+ )
+ print("save-dir : {:}".format(args.save_dir))
+
+ if args.rand_seed < 0:
+ save_dir, all_info = None, collections.OrderedDict()
+ for i in range(args.loops_if_rand):
+ print("{:} : {:03d}/{:03d}".format(time_string(), i, args.loops_if_rand))
+ args.rand_seed = random.randint(1, 100000)
+ save_dir, all_archs, all_total_times = main(args, api)
+ all_info[i] = {"all_archs": all_archs, "all_total_times": all_total_times}
+ save_path = save_dir / "results.pth"
+ print("save into {:}".format(save_path))
+ torch.save(all_info, save_path)
+ else:
+ main(args, api)
diff --git a/AutoDL-Projects/exps/NATS-algos/run-all.sh b/AutoDL-Projects/exps/NATS-algos/run-all.sh
new file mode 100644
index 0000000..d24f23f
--- /dev/null
+++ b/AutoDL-Projects/exps/NATS-algos/run-all.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+# bash ./exps/NATS-algos/run-all.sh mul
+# bash ./exps/NATS-algos/run-all.sh ws
+set -e
+echo script name: $0
+echo $# arguments
+if [ "$#" -ne 1 ] ;then
+ echo "Input illegal number of parameters " $#
+ echo "Need 1 parameters for type of algorithms."
+ exit 1
+fi
+
+alg_type=$1
+
+if [ "$alg_type" == "mul" ]; then
+ # datasets="cifar10 cifar100 ImageNet16-120"
+ run_four_algorithms(){
+ dataset=$1
+ search_space=$2
+ time_budget=$3
+ python ./exps/NATS-algos/reinforce.py --dataset ${dataset} --search_space ${search_space} --time_budget ${time_budget} --learning_rate 0.01
+ python ./exps/NATS-algos/regularized_ea.py --dataset ${dataset} --search_space ${search_space} --time_budget ${time_budget} --ea_cycles 200 --ea_population 10 --ea_sample_size 3
+ python ./exps/NATS-algos/random_wo_share.py --dataset ${dataset} --search_space ${search_space} --time_budget ${time_budget}
+ python ./exps/NATS-algos/bohb.py --dataset ${dataset} --search_space ${search_space} --time_budget ${time_budget} --num_samples 4 --random_fraction 0.0 --bandwidth_factor 3
+ }
+ # The topology search space
+ run_four_algorithms "cifar10" "tss" "20000"
+ run_four_algorithms "cifar100" "tss" "40000"
+ run_four_algorithms "ImageNet16-120" "tss" "120000"
+
+ # The size search space
+ run_four_algorithms "cifar10" "sss" "20000"
+ run_four_algorithms "cifar100" "sss" "40000"
+ run_four_algorithms "ImageNet16-120" "sss" "60000"
+ # python exps/experimental/vis-bench-algos.py --search_space tss
+ # python exps/experimental/vis-bench-algos.py --search_space sss
+else
+ seeds="777 888 999"
+ algos="darts-v1 darts-v2 gdas setn random enas"
+ epoch=200
+ for seed in ${seeds}
+ do
+ for alg in ${algos}
+ do
+ python ./exps/NATS-algos/search-cell.py --dataset cifar10 --data_path $TORCH_HOME/cifar.python --algo ${alg} --rand_seed ${seed} --overwite_epochs ${epoch}
+ python ./exps/NATS-algos/search-cell.py --dataset cifar100 --data_path $TORCH_HOME/cifar.python --algo ${alg} --rand_seed ${seed} --overwite_epochs ${epoch}
+ python ./exps/NATS-algos/search-cell.py --dataset ImageNet16-120 --data_path $TORCH_HOME/cifar.python/ImageNet16 --algo ${alg} --rand_seed ${seed} --overwite_epochs ${epoch}
+ done
+ done
+fi
+
diff --git a/AutoDL-Projects/exps/NATS-algos/search-cell.py b/AutoDL-Projects/exps/NATS-algos/search-cell.py
new file mode 100644
index 0000000..66842a8
--- /dev/null
+++ b/AutoDL-Projects/exps/NATS-algos/search-cell.py
@@ -0,0 +1,879 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020 #
+######################################################################################
+# python ./exps/NATS-algos/search-cell.py --dataset cifar10 --data_path $TORCH_HOME/cifar.python --algo darts-v1 --rand_seed 777
+# python ./exps/NATS-algos/search-cell.py --dataset cifar100 --data_path $TORCH_HOME/cifar.python --algo darts-v1 --drop_path_rate 0.3
+# python ./exps/NATS-algos/search-cell.py --dataset ImageNet16-120 --data_path $TORCH_HOME/cifar.python/ImageNet16 --algo darts-v1
+####
+# python ./exps/NATS-algos/search-cell.py --dataset cifar10 --data_path $TORCH_HOME/cifar.python --algo darts-v2 --rand_seed 777
+# python ./exps/NATS-algos/search-cell.py --dataset cifar100 --data_path $TORCH_HOME/cifar.python --algo darts-v2
+# python ./exps/NATS-algos/search-cell.py --dataset ImageNet16-120 --data_path $TORCH_HOME/cifar.python/ImageNet16 --algo darts-v2
+####
+# python ./exps/NATS-algos/search-cell.py --dataset cifar10 --data_path $TORCH_HOME/cifar.python --algo gdas --rand_seed 777
+# python ./exps/NATS-algos/search-cell.py --dataset cifar100 --data_path $TORCH_HOME/cifar.python --algo gdas
+# python ./exps/NATS-algos/search-cell.py --dataset ImageNet16-120 --data_path $TORCH_HOME/cifar.python/ImageNet16 --algo gdas
+####
+# python ./exps/NATS-algos/search-cell.py --dataset cifar10 --data_path $TORCH_HOME/cifar.python --algo setn --rand_seed 777
+# python ./exps/NATS-algos/search-cell.py --dataset cifar100 --data_path $TORCH_HOME/cifar.python --algo setn
+# python ./exps/NATS-algos/search-cell.py --dataset ImageNet16-120 --data_path $TORCH_HOME/cifar.python/ImageNet16 --algo setn
+####
+# python ./exps/NATS-algos/search-cell.py --dataset cifar10 --data_path $TORCH_HOME/cifar.python --algo random --rand_seed 777
+# python ./exps/NATS-algos/search-cell.py --dataset cifar100 --data_path $TORCH_HOME/cifar.python --algo random
+# python ./exps/NATS-algos/search-cell.py --dataset ImageNet16-120 --data_path $TORCH_HOME/cifar.python/ImageNet16 --algo random
+####
+# python ./exps/NATS-algos/search-cell.py --dataset cifar10 --data_path $TORCH_HOME/cifar.python --algo enas --arch_weight_decay 0 --arch_learning_rate 0.001 --arch_eps 0.001 --rand_seed 777
+# python ./exps/NATS-algos/search-cell.py --dataset cifar100 --data_path $TORCH_HOME/cifar.python --algo enas --arch_weight_decay 0 --arch_learning_rate 0.001 --arch_eps 0.001 --rand_seed 777
+# python ./exps/NATS-algos/search-cell.py --dataset ImageNet16-120 --data_path $TORCH_HOME/cifar.python/ImageNet16 --algo enas --arch_weight_decay 0 --arch_learning_rate 0.001 --arch_eps 0.001 --rand_seed 777
+####
+# The following scripts are added in 20 Mar 2022
+# python ./exps/NATS-algos/search-cell.py --dataset cifar10 --data_path $TORCH_HOME/cifar.python --algo gdas_v1 --rand_seed 777
+######################################################################################
+import os, sys, time, random, argparse
+import numpy as np
+from copy import deepcopy
+import torch
+import torch.nn as nn
+
+from xautodl.config_utils import load_config, dict2config, configure2str
+from xautodl.datasets import get_datasets, get_nas_search_loaders
+from xautodl.procedures import (
+ prepare_seed,
+ prepare_logger,
+ save_checkpoint,
+ copy_checkpoint,
+ get_optim_scheduler,
+)
+from xautodl.utils import count_parameters_in_MB, obtain_accuracy
+from xautodl.log_utils import AverageMeter, time_string, convert_secs2time
+from xautodl.models import get_cell_based_tiny_net, get_search_spaces
+from nats_bench import create
+
+
+# The following three functions are used for DARTS-V2
+def _concat(xs):
+ return torch.cat([x.view(-1) for x in xs])
+
+
+def _hessian_vector_product(
+ vector, network, criterion, base_inputs, base_targets, r=1e-2
+):
+ R = r / _concat(vector).norm()
+ for p, v in zip(network.weights, vector):
+ p.data.add_(R, v)
+ _, logits = network(base_inputs)
+ loss = criterion(logits, base_targets)
+ grads_p = torch.autograd.grad(loss, network.alphas)
+
+ for p, v in zip(network.weights, vector):
+ p.data.sub_(2 * R, v)
+ _, logits = network(base_inputs)
+ loss = criterion(logits, base_targets)
+ grads_n = torch.autograd.grad(loss, network.alphas)
+
+ for p, v in zip(network.weights, vector):
+ p.data.add_(R, v)
+ return [(x - y).div_(2 * R) for x, y in zip(grads_p, grads_n)]
+
+
+def backward_step_unrolled(
+ network,
+ criterion,
+ base_inputs,
+ base_targets,
+ w_optimizer,
+ arch_inputs,
+ arch_targets,
+):
+ # _compute_unrolled_model
+ _, logits = network(base_inputs)
+ loss = criterion(logits, base_targets)
+ LR, WD, momentum = (
+ w_optimizer.param_groups[0]["lr"],
+ w_optimizer.param_groups[0]["weight_decay"],
+ w_optimizer.param_groups[0]["momentum"],
+ )
+ with torch.no_grad():
+ theta = _concat(network.weights)
+ try:
+ moment = _concat(
+ w_optimizer.state[v]["momentum_buffer"] for v in network.weights
+ )
+ moment = moment.mul_(momentum)
+ except:
+ moment = torch.zeros_like(theta)
+ dtheta = _concat(torch.autograd.grad(loss, network.weights)) + WD * theta
+ params = theta.sub(LR, moment + dtheta)
+ unrolled_model = deepcopy(network)
+ model_dict = unrolled_model.state_dict()
+ new_params, offset = {}, 0
+ for k, v in network.named_parameters():
+ if "arch_parameters" in k:
+ continue
+ v_length = np.prod(v.size())
+ new_params[k] = params[offset : offset + v_length].view(v.size())
+ offset += v_length
+ model_dict.update(new_params)
+ unrolled_model.load_state_dict(model_dict)
+
+ unrolled_model.zero_grad()
+ _, unrolled_logits = unrolled_model(arch_inputs)
+ unrolled_loss = criterion(unrolled_logits, arch_targets)
+ unrolled_loss.backward()
+
+ dalpha = unrolled_model.arch_parameters.grad
+ vector = [v.grad.data for v in unrolled_model.weights]
+ [implicit_grads] = _hessian_vector_product(
+ vector, network, criterion, base_inputs, base_targets
+ )
+
+ dalpha.data.sub_(LR, implicit_grads.data)
+
+ if network.arch_parameters.grad is None:
+ network.arch_parameters.grad = deepcopy(dalpha)
+ else:
+ network.arch_parameters.grad.data.copy_(dalpha.data)
+ return unrolled_loss.detach(), unrolled_logits.detach()
+
+
+def search_func(
+ xloader,
+ network,
+ criterion,
+ scheduler,
+ w_optimizer,
+ a_optimizer,
+ epoch_str,
+ print_freq,
+ algo,
+ logger,
+):
+ data_time, batch_time = AverageMeter(), AverageMeter()
+ base_losses, base_top1, base_top5 = AverageMeter(), AverageMeter(), AverageMeter()
+ arch_losses, arch_top1, arch_top5 = AverageMeter(), AverageMeter(), AverageMeter()
+ end = time.time()
+ network.train()
+ for step, (base_inputs, base_targets, arch_inputs, arch_targets) in enumerate(
+ xloader
+ ):
+ scheduler.update(None, 1.0 * step / len(xloader))
+ base_inputs = base_inputs.cuda(non_blocking=True)
+ arch_inputs = arch_inputs.cuda(non_blocking=True)
+ base_targets = base_targets.cuda(non_blocking=True)
+ arch_targets = arch_targets.cuda(non_blocking=True)
+ # measure data loading time
+ data_time.update(time.time() - end)
+
+ # Update the weights
+ if algo == "setn":
+ sampled_arch = network.dync_genotype(True)
+ network.set_cal_mode("dynamic", sampled_arch)
+ elif algo == "gdas":
+ network.set_cal_mode("gdas", None)
+ elif algo == "gdas_v1":
+ network.set_cal_mode("gdas_v1", None)
+ elif algo.startswith("darts"):
+ network.set_cal_mode("joint", None)
+ elif algo == "random":
+ network.set_cal_mode("urs", None)
+ elif algo == "enas":
+ with torch.no_grad():
+ network.controller.eval()
+ _, _, sampled_arch = network.controller()
+ network.set_cal_mode("dynamic", sampled_arch)
+ else:
+ raise ValueError("Invalid algo name : {:}".format(algo))
+
+ network.zero_grad()
+ _, logits = network(base_inputs)
+ base_loss = criterion(logits, base_targets)
+ base_loss.backward()
+ w_optimizer.step()
+ # record
+ base_prec1, base_prec5 = obtain_accuracy(
+ logits.data, base_targets.data, topk=(1, 5)
+ )
+ base_losses.update(base_loss.item(), base_inputs.size(0))
+ base_top1.update(base_prec1.item(), base_inputs.size(0))
+ base_top5.update(base_prec5.item(), base_inputs.size(0))
+
+ # update the architecture-weight
+ if algo == "setn":
+ network.set_cal_mode("joint")
+ elif algo == "gdas":
+ network.set_cal_mode("gdas", None)
+ elif algo == "gdas_v1":
+ network.set_cal_mode("gdas_v1", None)
+ elif algo.startswith("darts"):
+ network.set_cal_mode("joint", None)
+ elif algo == "random":
+ network.set_cal_mode("urs", None)
+ elif algo != "enas":
+ raise ValueError("Invalid algo name : {:}".format(algo))
+ network.zero_grad()
+ if algo == "darts-v2":
+ arch_loss, logits = backward_step_unrolled(
+ network,
+ criterion,
+ base_inputs,
+ base_targets,
+ w_optimizer,
+ arch_inputs,
+ arch_targets,
+ )
+ a_optimizer.step()
+ elif algo == "random" or algo == "enas":
+ with torch.no_grad():
+ _, logits = network(arch_inputs)
+ arch_loss = criterion(logits, arch_targets)
+ else:
+ _, logits = network(arch_inputs)
+ arch_loss = criterion(logits, arch_targets)
+ arch_loss.backward()
+ a_optimizer.step()
+ # record
+ arch_prec1, arch_prec5 = obtain_accuracy(
+ logits.data, arch_targets.data, topk=(1, 5)
+ )
+ arch_losses.update(arch_loss.item(), arch_inputs.size(0))
+ arch_top1.update(arch_prec1.item(), arch_inputs.size(0))
+ arch_top5.update(arch_prec5.item(), arch_inputs.size(0))
+
+ # measure elapsed time
+ batch_time.update(time.time() - end)
+ end = time.time()
+
+ if step % print_freq == 0 or step + 1 == len(xloader):
+ Sstr = (
+ "*SEARCH* "
+ + time_string()
+ + " [{:}][{:03d}/{:03d}]".format(epoch_str, step, len(xloader))
+ )
+ Tstr = "Time {batch_time.val:.2f} ({batch_time.avg:.2f}) Data {data_time.val:.2f} ({data_time.avg:.2f})".format(
+ batch_time=batch_time, data_time=data_time
+ )
+ Wstr = "Base [Loss {loss.val:.3f} ({loss.avg:.3f}) Prec@1 {top1.val:.2f} ({top1.avg:.2f}) Prec@5 {top5.val:.2f} ({top5.avg:.2f})]".format(
+ loss=base_losses, top1=base_top1, top5=base_top5
+ )
+ Astr = "Arch [Loss {loss.val:.3f} ({loss.avg:.3f}) Prec@1 {top1.val:.2f} ({top1.avg:.2f}) Prec@5 {top5.val:.2f} ({top5.avg:.2f})]".format(
+ loss=arch_losses, top1=arch_top1, top5=arch_top5
+ )
+ logger.log(Sstr + " " + Tstr + " " + Wstr + " " + Astr)
+ return (
+ base_losses.avg,
+ base_top1.avg,
+ base_top5.avg,
+ arch_losses.avg,
+ arch_top1.avg,
+ arch_top5.avg,
+ )
+
+
+def train_controller(
+ xloader, network, criterion, optimizer, prev_baseline, epoch_str, print_freq, logger
+):
+ # config. (containing some necessary arg)
+ # baseline: The baseline score (i.e. average val_acc) from the previous epoch
+ data_time, batch_time = AverageMeter(), AverageMeter()
+ (
+ GradnormMeter,
+ LossMeter,
+ ValAccMeter,
+ EntropyMeter,
+ BaselineMeter,
+ RewardMeter,
+ xend,
+ ) = (
+ AverageMeter(),
+ AverageMeter(),
+ AverageMeter(),
+ AverageMeter(),
+ AverageMeter(),
+ AverageMeter(),
+ time.time(),
+ )
+
+ controller_num_aggregate = 20
+ controller_train_steps = 50
+ controller_bl_dec = 0.99
+ controller_entropy_weight = 0.0001
+
+ network.eval()
+ network.controller.train()
+ network.controller.zero_grad()
+ loader_iter = iter(xloader)
+ for step in range(controller_train_steps * controller_num_aggregate):
+ try:
+ inputs, targets = next(loader_iter)
+ except:
+ loader_iter = iter(xloader)
+ inputs, targets = next(loader_iter)
+ inputs = inputs.cuda(non_blocking=True)
+ targets = targets.cuda(non_blocking=True)
+ # measure data loading time
+ data_time.update(time.time() - xend)
+
+ log_prob, entropy, sampled_arch = network.controller()
+ with torch.no_grad():
+ network.set_cal_mode("dynamic", sampled_arch)
+ _, logits = network(inputs)
+ val_top1, val_top5 = obtain_accuracy(logits.data, targets.data, topk=(1, 5))
+ val_top1 = val_top1.view(-1) / 100
+ reward = val_top1 + controller_entropy_weight * entropy
+ if prev_baseline is None:
+ baseline = val_top1
+ else:
+ baseline = prev_baseline - (1 - controller_bl_dec) * (
+ prev_baseline - reward
+ )
+
+ loss = -1 * log_prob * (reward - baseline)
+
+ # account
+ RewardMeter.update(reward.item())
+ BaselineMeter.update(baseline.item())
+ ValAccMeter.update(val_top1.item() * 100)
+ LossMeter.update(loss.item())
+ EntropyMeter.update(entropy.item())
+
+ # Average gradient over controller_num_aggregate samples
+ loss = loss / controller_num_aggregate
+ loss.backward(retain_graph=True)
+
+ # measure elapsed time
+ batch_time.update(time.time() - xend)
+ xend = time.time()
+ if (step + 1) % controller_num_aggregate == 0:
+ grad_norm = torch.nn.utils.clip_grad_norm_(
+ network.controller.parameters(), 5.0
+ )
+ GradnormMeter.update(grad_norm)
+ optimizer.step()
+ network.controller.zero_grad()
+
+ if step % print_freq == 0:
+ Sstr = (
+ "*Train-Controller* "
+ + time_string()
+ + " [{:}][{:03d}/{:03d}]".format(
+ epoch_str, step, controller_train_steps * controller_num_aggregate
+ )
+ )
+ Tstr = "Time {batch_time.val:.2f} ({batch_time.avg:.2f}) Data {data_time.val:.2f} ({data_time.avg:.2f})".format(
+ batch_time=batch_time, data_time=data_time
+ )
+ Wstr = "[Loss {loss.val:.3f} ({loss.avg:.3f}) Prec@1 {top1.val:.2f} ({top1.avg:.2f}) Reward {reward.val:.2f} ({reward.avg:.2f})] Baseline {basel.val:.2f} ({basel.avg:.2f})".format(
+ loss=LossMeter,
+ top1=ValAccMeter,
+ reward=RewardMeter,
+ basel=BaselineMeter,
+ )
+ Estr = "Entropy={:.4f} ({:.4f})".format(EntropyMeter.val, EntropyMeter.avg)
+ logger.log(Sstr + " " + Tstr + " " + Wstr + " " + Estr)
+
+ return LossMeter.avg, ValAccMeter.avg, BaselineMeter.avg, RewardMeter.avg
+
+
+def get_best_arch(xloader, network, n_samples, algo):
+ with torch.no_grad():
+ network.eval()
+ if algo == "random":
+ archs, valid_accs = network.return_topK(n_samples, True), []
+ elif algo == "setn":
+ archs, valid_accs = network.return_topK(n_samples, False), []
+ elif algo.startswith("darts") or algo == "gdas" or algo == "gdas_v1":
+ arch = network.genotype
+ archs, valid_accs = [arch], []
+ elif algo == "enas":
+ archs, valid_accs = [], []
+ for _ in range(n_samples):
+ _, _, sampled_arch = network.controller()
+ archs.append(sampled_arch)
+ else:
+ raise ValueError("Invalid algorithm name : {:}".format(algo))
+ loader_iter = iter(xloader)
+ for i, sampled_arch in enumerate(archs):
+ network.set_cal_mode("dynamic", sampled_arch)
+ try:
+ inputs, targets = next(loader_iter)
+ except:
+ loader_iter = iter(xloader)
+ inputs, targets = next(loader_iter)
+ _, logits = network(inputs.cuda(non_blocking=True))
+ val_top1, val_top5 = obtain_accuracy(
+ logits.cpu().data, targets.data, topk=(1, 5)
+ )
+ valid_accs.append(val_top1.item())
+ best_idx = np.argmax(valid_accs)
+ best_arch, best_valid_acc = archs[best_idx], valid_accs[best_idx]
+ return best_arch, best_valid_acc
+
+
+def valid_func(xloader, network, criterion, algo, logger):
+ data_time, batch_time = AverageMeter(), AverageMeter()
+ arch_losses, arch_top1, arch_top5 = AverageMeter(), AverageMeter(), AverageMeter()
+ end = time.time()
+ with torch.no_grad():
+ network.eval()
+ for step, (arch_inputs, arch_targets) in enumerate(xloader):
+ arch_targets = arch_targets.cuda(non_blocking=True)
+ # measure data loading time
+ data_time.update(time.time() - end)
+ # prediction
+ _, logits = network(arch_inputs.cuda(non_blocking=True))
+ arch_loss = criterion(logits, arch_targets)
+ # record
+ arch_prec1, arch_prec5 = obtain_accuracy(
+ logits.data, arch_targets.data, topk=(1, 5)
+ )
+ arch_losses.update(arch_loss.item(), arch_inputs.size(0))
+ arch_top1.update(arch_prec1.item(), arch_inputs.size(0))
+ arch_top5.update(arch_prec5.item(), arch_inputs.size(0))
+ # measure elapsed time
+ batch_time.update(time.time() - end)
+ end = time.time()
+ return arch_losses.avg, arch_top1.avg, arch_top5.avg
+
+
+def main(xargs):
+ assert torch.cuda.is_available(), "CUDA is not available."
+ torch.backends.cudnn.enabled = True
+ torch.backends.cudnn.benchmark = False
+ torch.backends.cudnn.deterministic = True
+ torch.set_num_threads(xargs.workers)
+ prepare_seed(xargs.rand_seed)
+ logger = prepare_logger(args)
+
+ train_data, valid_data, xshape, class_num = get_datasets(
+ xargs.dataset, xargs.data_path, -1
+ )
+ if xargs.overwite_epochs is None:
+ extra_info = {"class_num": class_num, "xshape": xshape}
+ else:
+ extra_info = {
+ "class_num": class_num,
+ "xshape": xshape,
+ "epochs": xargs.overwite_epochs,
+ }
+ config = load_config(xargs.config_path, extra_info, logger)
+ search_loader, train_loader, valid_loader = get_nas_search_loaders(
+ train_data,
+ valid_data,
+ xargs.dataset,
+ "configs/nas-benchmark/",
+ (config.batch_size, config.test_batch_size),
+ xargs.workers,
+ )
+ logger.log(
+ "||||||| {:10s} ||||||| Search-Loader-Num={:}, Valid-Loader-Num={:}, batch size={:}".format(
+ xargs.dataset, len(search_loader), len(valid_loader), config.batch_size
+ )
+ )
+ logger.log("||||||| {:10s} ||||||| Config={:}".format(xargs.dataset, config))
+
+ search_space = get_search_spaces(xargs.search_space, "nats-bench")
+
+ model_config = dict2config(
+ dict(
+ name="generic",
+ C=xargs.channel,
+ N=xargs.num_cells,
+ max_nodes=xargs.max_nodes,
+ num_classes=class_num,
+ space=search_space,
+ affine=bool(xargs.affine),
+ track_running_stats=bool(xargs.track_running_stats),
+ ),
+ None,
+ )
+ logger.log("search space : {:}".format(search_space))
+ logger.log("model config : {:}".format(model_config))
+ search_model = get_cell_based_tiny_net(model_config)
+ search_model.set_algo(xargs.algo)
+ logger.log("{:}".format(search_model))
+
+ w_optimizer, w_scheduler, criterion = get_optim_scheduler(
+ search_model.weights, config
+ )
+ a_optimizer = torch.optim.Adam(
+ search_model.alphas,
+ lr=xargs.arch_learning_rate,
+ betas=(0.5, 0.999),
+ weight_decay=xargs.arch_weight_decay,
+ eps=xargs.arch_eps,
+ )
+ logger.log("w-optimizer : {:}".format(w_optimizer))
+ logger.log("a-optimizer : {:}".format(a_optimizer))
+ logger.log("w-scheduler : {:}".format(w_scheduler))
+ logger.log("criterion : {:}".format(criterion))
+ params = count_parameters_in_MB(search_model)
+ logger.log("The parameters of the search model = {:.2f} MB".format(params))
+ logger.log("search-space : {:}".format(search_space))
+ if bool(xargs.use_api):
+ api = create(None, "topology", fast_mode=True, verbose=False)
+ else:
+ api = None
+ logger.log("{:} create API = {:} done".format(time_string(), api))
+
+ last_info, model_base_path, model_best_path = (
+ logger.path("info"),
+ logger.path("model"),
+ logger.path("best"),
+ )
+ network, criterion = search_model.cuda(), criterion.cuda() # use a single GPU
+
+ last_info, model_base_path, model_best_path = (
+ logger.path("info"),
+ logger.path("model"),
+ logger.path("best"),
+ )
+
+ if last_info.exists(): # automatically resume from previous checkpoint
+ logger.log(
+ "=> loading checkpoint of the last-info '{:}' start".format(last_info)
+ )
+ last_info = torch.load(last_info)
+ start_epoch = last_info["epoch"]
+ checkpoint = torch.load(last_info["last_checkpoint"])
+ genotypes = checkpoint["genotypes"]
+ baseline = checkpoint["baseline"]
+ valid_accuracies = checkpoint["valid_accuracies"]
+ search_model.load_state_dict(checkpoint["search_model"])
+ w_scheduler.load_state_dict(checkpoint["w_scheduler"])
+ w_optimizer.load_state_dict(checkpoint["w_optimizer"])
+ a_optimizer.load_state_dict(checkpoint["a_optimizer"])
+ logger.log(
+ "=> loading checkpoint of the last-info '{:}' start with {:}-th epoch.".format(
+ last_info, start_epoch
+ )
+ )
+ else:
+ logger.log("=> do not find the last-info file : {:}".format(last_info))
+ start_epoch, valid_accuracies, genotypes = (
+ 0,
+ {"best": -1},
+ {-1: network.return_topK(1, True)[0]},
+ )
+ baseline = None
+
+ # start training
+ start_time, search_time, epoch_time, total_epoch = (
+ time.time(),
+ AverageMeter(),
+ AverageMeter(),
+ config.epochs + config.warmup,
+ )
+ for epoch in range(start_epoch, total_epoch):
+ w_scheduler.update(epoch, 0.0)
+ need_time = "Time Left: {:}".format(
+ convert_secs2time(epoch_time.val * (total_epoch - epoch), True)
+ )
+ epoch_str = "{:03d}-{:03d}".format(epoch, total_epoch)
+ logger.log(
+ "\n[Search the {:}-th epoch] {:}, LR={:}".format(
+ epoch_str, need_time, min(w_scheduler.get_lr())
+ )
+ )
+
+ network.set_drop_path(float(epoch + 1) / total_epoch, xargs.drop_path_rate)
+ if xargs.algo == "gdas" or xargs.algo == "gdas_v1":
+ network.set_tau(
+ xargs.tau_max
+ - (xargs.tau_max - xargs.tau_min) * epoch / (total_epoch - 1)
+ )
+ logger.log(
+ "[RESET tau as : {:} and drop_path as {:}]".format(
+ network.tau, network.drop_path
+ )
+ )
+ (
+ search_w_loss,
+ search_w_top1,
+ search_w_top5,
+ search_a_loss,
+ search_a_top1,
+ search_a_top5,
+ ) = search_func(
+ search_loader,
+ network,
+ criterion,
+ w_scheduler,
+ w_optimizer,
+ a_optimizer,
+ epoch_str,
+ xargs.print_freq,
+ xargs.algo,
+ logger,
+ )
+ search_time.update(time.time() - start_time)
+ logger.log(
+ "[{:}] search [base] : loss={:.2f}, accuracy@1={:.2f}%, accuracy@5={:.2f}%, time-cost={:.1f} s".format(
+ epoch_str, search_w_loss, search_w_top1, search_w_top5, search_time.sum
+ )
+ )
+ logger.log(
+ "[{:}] search [arch] : loss={:.2f}, accuracy@1={:.2f}%, accuracy@5={:.2f}%".format(
+ epoch_str, search_a_loss, search_a_top1, search_a_top5
+ )
+ )
+ if xargs.algo == "enas":
+ ctl_loss, ctl_acc, baseline, ctl_reward = train_controller(
+ valid_loader,
+ network,
+ criterion,
+ a_optimizer,
+ baseline,
+ epoch_str,
+ xargs.print_freq,
+ logger,
+ )
+ logger.log(
+ "[{:}] controller : loss={:}, acc={:}, baseline={:}, reward={:}".format(
+ epoch_str, ctl_loss, ctl_acc, baseline, ctl_reward
+ )
+ )
+
+ genotype, temp_accuracy = get_best_arch(
+ valid_loader, network, xargs.eval_candidate_num, xargs.algo
+ )
+ if xargs.algo == "setn" or xargs.algo == "enas":
+ network.set_cal_mode("dynamic", genotype)
+ elif xargs.algo == "gdas":
+ network.set_cal_mode("gdas", None)
+ elif xargs.algo == "gdas_v1":
+ network.set_cal_mode("gdas_v1", None)
+ elif xargs.algo.startswith("darts"):
+ network.set_cal_mode("joint", None)
+ elif xargs.algo == "random":
+ network.set_cal_mode("urs", None)
+ else:
+ raise ValueError("Invalid algorithm name : {:}".format(xargs.algo))
+ logger.log(
+ "[{:}] - [get_best_arch] : {:} -> {:}".format(
+ epoch_str, genotype, temp_accuracy
+ )
+ )
+ valid_a_loss, valid_a_top1, valid_a_top5 = valid_func(
+ valid_loader, network, criterion, xargs.algo, logger
+ )
+ logger.log(
+ "[{:}] evaluate : loss={:.2f}, accuracy@1={:.2f}%, accuracy@5={:.2f}% | {:}".format(
+ epoch_str, valid_a_loss, valid_a_top1, valid_a_top5, genotype
+ )
+ )
+ valid_accuracies[epoch] = valid_a_top1
+
+ genotypes[epoch] = genotype
+ logger.log(
+ "<<<--->>> The {:}-th epoch : {:}".format(epoch_str, genotypes[epoch])
+ )
+ # save checkpoint
+ save_path = save_checkpoint(
+ {
+ "epoch": epoch + 1,
+ "args": deepcopy(xargs),
+ "baseline": baseline,
+ "search_model": search_model.state_dict(),
+ "w_optimizer": w_optimizer.state_dict(),
+ "a_optimizer": a_optimizer.state_dict(),
+ "w_scheduler": w_scheduler.state_dict(),
+ "genotypes": genotypes,
+ "valid_accuracies": valid_accuracies,
+ },
+ model_base_path,
+ logger,
+ )
+ last_info = save_checkpoint(
+ {
+ "epoch": epoch + 1,
+ "args": deepcopy(args),
+ "last_checkpoint": save_path,
+ },
+ logger.path("info"),
+ logger,
+ )
+ with torch.no_grad():
+ logger.log("{:}".format(search_model.show_alphas()))
+ if api is not None:
+ logger.log("{:}".format(api.query_by_arch(genotypes[epoch], "200")))
+ # measure elapsed time
+ epoch_time.update(time.time() - start_time)
+ start_time = time.time()
+
+ # the final post procedure : count the time
+ start_time = time.time()
+ genotype, temp_accuracy = get_best_arch(
+ valid_loader, network, xargs.eval_candidate_num, xargs.algo
+ )
+ if xargs.algo == "setn" or xargs.algo == "enas":
+ network.set_cal_mode("dynamic", genotype)
+ elif xargs.algo == "gdas":
+ network.set_cal_mode("gdas", None)
+ elif xargs.algo == "gdas_v1":
+ network.set_cal_mode("gdas_v1", None)
+ elif xargs.algo.startswith("darts"):
+ network.set_cal_mode("joint", None)
+ elif xargs.algo == "random":
+ network.set_cal_mode("urs", None)
+ else:
+ raise ValueError("Invalid algorithm name : {:}".format(xargs.algo))
+ search_time.update(time.time() - start_time)
+
+ valid_a_loss, valid_a_top1, valid_a_top5 = valid_func(
+ valid_loader, network, criterion, xargs.algo, logger
+ )
+ logger.log(
+ "Last : the gentotype is : {:}, with the validation accuracy of {:.3f}%.".format(
+ genotype, valid_a_top1
+ )
+ )
+
+ logger.log("\n" + "-" * 100)
+ # check the performance from the architecture dataset
+ logger.log(
+ "[{:}] run {:} epochs, cost {:.1f} s, last-geno is {:}.".format(
+ xargs.algo, total_epoch, search_time.sum, genotype
+ )
+ )
+ if api is not None:
+ logger.log("{:}".format(api.query_by_arch(genotype, "200")))
+ logger.close()
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser("Weight sharing NAS methods to search for cells.")
+ parser.add_argument("--data_path", type=str, help="Path to dataset")
+ parser.add_argument(
+ "--dataset",
+ type=str,
+ choices=["cifar10", "cifar100", "ImageNet16-120"],
+ help="Choose between Cifar10/100 and ImageNet-16.",
+ )
+ parser.add_argument(
+ "--search_space",
+ type=str,
+ default="tss",
+ choices=["tss"],
+ help="The search space name.",
+ )
+ parser.add_argument(
+ "--algo",
+ type=str,
+ choices=["darts-v1", "darts-v2", "gdas", "gdas_v1", "setn", "random", "enas"],
+ help="The search space name.",
+ )
+ parser.add_argument(
+ "--use_api",
+ type=int,
+ default=1,
+ choices=[0, 1],
+ help="Whether use API or not (which will cost much memory).",
+ )
+ # FOR GDAS
+ parser.add_argument(
+ "--tau_min", type=float, default=0.1, help="The minimum tau for Gumbel Softmax."
+ )
+ parser.add_argument(
+ "--tau_max", type=float, default=10, help="The maximum tau for Gumbel Softmax."
+ )
+ # channels and number-of-cells
+ parser.add_argument(
+ "--max_nodes", type=int, default=4, help="The maximum number of nodes."
+ )
+ parser.add_argument(
+ "--channel", type=int, default=16, help="The number of channels."
+ )
+ parser.add_argument(
+ "--num_cells", type=int, default=5, help="The number of cells in one stage."
+ )
+ #
+ parser.add_argument(
+ "--eval_candidate_num",
+ type=int,
+ default=100,
+ help="The number of selected architectures to evaluate.",
+ )
+ #
+ parser.add_argument(
+ "--track_running_stats",
+ type=int,
+ default=0,
+ choices=[0, 1],
+ help="Whether use track_running_stats or not in the BN layer.",
+ )
+ parser.add_argument(
+ "--affine",
+ type=int,
+ default=0,
+ choices=[0, 1],
+ help="Whether use affine=True or False in the BN layer.",
+ )
+ parser.add_argument(
+ "--config_path",
+ type=str,
+ default="./configs/nas-benchmark/algos/weight-sharing.config",
+ help="The path of configuration.",
+ )
+ parser.add_argument(
+ "--overwite_epochs",
+ type=int,
+ help="The number of epochs to overwrite that value in config files.",
+ )
+ # architecture leraning rate
+ parser.add_argument(
+ "--arch_learning_rate",
+ type=float,
+ default=3e-4,
+ help="learning rate for arch encoding",
+ )
+ parser.add_argument(
+ "--arch_weight_decay",
+ type=float,
+ default=1e-3,
+ help="weight decay for arch encoding",
+ )
+ parser.add_argument(
+ "--arch_eps", type=float, default=1e-8, help="weight decay for arch encoding"
+ )
+ parser.add_argument("--drop_path_rate", type=float, help="The drop path rate.")
+ # log
+ parser.add_argument(
+ "--workers",
+ type=int,
+ default=2,
+ help="number of data loading workers (default: 2)",
+ )
+ parser.add_argument(
+ "--save_dir",
+ type=str,
+ default="./output/search",
+ help="Folder to save checkpoints and log.",
+ )
+ parser.add_argument(
+ "--print_freq", type=int, default=200, help="print frequency (default: 200)"
+ )
+ parser.add_argument("--rand_seed", type=int, help="manual seed")
+ args = parser.parse_args()
+ if args.rand_seed is None or args.rand_seed < 0:
+ args.rand_seed = random.randint(1, 100000)
+ if args.overwite_epochs is None:
+ args.save_dir = os.path.join(
+ "{:}-{:}".format(args.save_dir, args.search_space),
+ args.dataset,
+ "{:}-affine{:}_BN{:}-{:}".format(
+ args.algo, args.affine, args.track_running_stats, args.drop_path_rate
+ ),
+ )
+ else:
+ args.save_dir = os.path.join(
+ "{:}-{:}".format(args.save_dir, args.search_space),
+ args.dataset,
+ "{:}-affine{:}_BN{:}-E{:}-{:}".format(
+ args.algo,
+ args.affine,
+ args.track_running_stats,
+ args.overwite_epochs,
+ args.drop_path_rate,
+ ),
+ )
+
+ main(args)
diff --git a/AutoDL-Projects/exps/NATS-algos/search-size.py b/AutoDL-Projects/exps/NATS-algos/search-size.py
new file mode 100644
index 0000000..c9c6a6d
--- /dev/null
+++ b/AutoDL-Projects/exps/NATS-algos/search-size.py
@@ -0,0 +1,582 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020 #
+###########################################################################################################################################
+#
+# In this file, we aims to evaluate three kinds of channel searching strategies:
+# - channel-wise interpolation from "Network Pruning via Transformable Architecture Search, NeurIPS 2019"
+# - masking + Gumbel-Softmax (mask_gumbel) from "FBNetV2: Differentiable Neural Architecture Search for Spatial and Channel Dimensions, CVPR 2020"
+# - masking + sampling (mask_rl) from "Can Weight Sharing Outperform Random Architecture Search? An Investigation With TuNAS, CVPR 2020"
+#
+# For simplicity, we use tas, mask_gumbel, and mask_rl to refer these three strategies. Their official implementations are at the following links:
+# - TAS: https://github.com/D-X-Y/AutoDL-Projects/blob/main/docs/NeurIPS-2019-TAS.md
+# - FBNetV2: https://github.com/facebookresearch/mobile-vision
+# - TuNAS: https://github.com/google-research/google-research/tree/master/tunas
+####
+# python ./exps/NATS-algos/search-size.py --dataset cifar10 --data_path $TORCH_HOME/cifar.python --algo mask_rl --arch_weight_decay 0 --warmup_ratio 0.25
+####
+# python ./exps/NATS-algos/search-size.py --dataset cifar10 --data_path $TORCH_HOME/cifar.python --algo tas --rand_seed 777
+# python ./exps/NATS-algos/search-size.py --dataset cifar100 --data_path $TORCH_HOME/cifar.python --algo tas --rand_seed 777
+# python ./exps/NATS-algos/search-size.py --dataset ImageNet16-120 --data_path $TORCH_HOME/cifar.python/ImageNet16 --algo tas --rand_seed 777
+####
+# python ./exps/NATS-algos/search-size.py --dataset cifar10 --data_path $TORCH_HOME/cifar.python --algo mask_gumbel --rand_seed 777
+# python ./exps/NATS-algos/search-size.py --dataset cifar100 --data_path $TORCH_HOME/cifar.python --algo mask_gumbel --rand_seed 777
+# python ./exps/NATS-algos/search-size.py --dataset ImageNet16-120 --data_path $TORCH_HOME/cifar.python/ImageNet16 --algo mask_gumbel --rand_seed 777
+####
+# python ./exps/NATS-algos/search-size.py --dataset cifar10 --data_path $TORCH_HOME/cifar.python --algo mask_rl --arch_weight_decay 0 --rand_seed 777 --use_api 0
+# python ./exps/NATS-algos/search-size.py --dataset cifar100 --data_path $TORCH_HOME/cifar.python --algo mask_rl --arch_weight_decay 0 --rand_seed 777
+# python ./exps/NATS-algos/search-size.py --dataset ImageNet16-120 --data_path $TORCH_HOME/cifar.python/ImageNet16 --algo mask_rl --arch_weight_decay 0 --rand_seed 777
+###########################################################################################################################################
+import os, sys, time, random, argparse
+import numpy as np
+from copy import deepcopy
+import torch
+import torch.nn as nn
+
+from xautodl.config_utils import load_config, dict2config, configure2str
+from xautodl.datasets import get_datasets, get_nas_search_loaders
+from xautodl.procedures import (
+ prepare_seed,
+ prepare_logger,
+ save_checkpoint,
+ copy_checkpoint,
+ get_optim_scheduler,
+)
+from xautodl.utils import count_parameters_in_MB, obtain_accuracy
+from xautodl.log_utils import AverageMeter, time_string, convert_secs2time
+from xautodl.models import get_cell_based_tiny_net, get_search_spaces
+from nats_bench import create
+
+
+# Ad-hoc for RL algorithms.
+class ExponentialMovingAverage(object):
+ """Class that maintains an exponential moving average."""
+
+ def __init__(self, momentum):
+ self._numerator = 0
+ self._denominator = 0
+ self._momentum = momentum
+
+ def update(self, value):
+ self._numerator = (
+ self._momentum * self._numerator + (1 - self._momentum) * value
+ )
+ self._denominator = self._momentum * self._denominator + (1 - self._momentum)
+
+ @property
+ def value(self):
+ """Return the current value of the moving average"""
+ return self._numerator / self._denominator
+
+
+RL_BASELINE_EMA = ExponentialMovingAverage(0.95)
+
+
+def search_func(
+ xloader,
+ network,
+ criterion,
+ scheduler,
+ w_optimizer,
+ a_optimizer,
+ enable_controller,
+ algo,
+ epoch_str,
+ print_freq,
+ logger,
+):
+ data_time, batch_time = AverageMeter(), AverageMeter()
+ base_losses, base_top1, base_top5 = AverageMeter(), AverageMeter(), AverageMeter()
+ arch_losses, arch_top1, arch_top5 = AverageMeter(), AverageMeter(), AverageMeter()
+ end = time.time()
+ network.train()
+ for step, (base_inputs, base_targets, arch_inputs, arch_targets) in enumerate(
+ xloader
+ ):
+ scheduler.update(None, 1.0 * step / len(xloader))
+ base_inputs = base_inputs.cuda(non_blocking=True)
+ arch_inputs = arch_inputs.cuda(non_blocking=True)
+ base_targets = base_targets.cuda(non_blocking=True)
+ arch_targets = arch_targets.cuda(non_blocking=True)
+ # measure data loading time
+ data_time.update(time.time() - end)
+
+ # Update the weights
+ network.zero_grad()
+ _, logits, _ = network(base_inputs)
+ base_loss = criterion(logits, base_targets)
+ base_loss.backward()
+ w_optimizer.step()
+ # record
+ base_prec1, base_prec5 = obtain_accuracy(
+ logits.data, base_targets.data, topk=(1, 5)
+ )
+ base_losses.update(base_loss.item(), base_inputs.size(0))
+ base_top1.update(base_prec1.item(), base_inputs.size(0))
+ base_top5.update(base_prec5.item(), base_inputs.size(0))
+
+ # update the architecture-weight
+ network.zero_grad()
+ a_optimizer.zero_grad()
+ _, logits, log_probs = network(arch_inputs)
+ arch_prec1, arch_prec5 = obtain_accuracy(
+ logits.data, arch_targets.data, topk=(1, 5)
+ )
+ if algo == "mask_rl":
+ with torch.no_grad():
+ RL_BASELINE_EMA.update(arch_prec1.item())
+ rl_advantage = arch_prec1 - RL_BASELINE_EMA.value
+ rl_log_prob = sum(log_probs)
+ arch_loss = -rl_advantage * rl_log_prob
+ elif algo == "tas" or algo == "mask_gumbel":
+ arch_loss = criterion(logits, arch_targets)
+ else:
+ raise ValueError("invalid algorightm name: {:}".format(algo))
+ if enable_controller:
+ arch_loss.backward()
+ a_optimizer.step()
+ # record
+ arch_losses.update(arch_loss.item(), arch_inputs.size(0))
+ arch_top1.update(arch_prec1.item(), arch_inputs.size(0))
+ arch_top5.update(arch_prec5.item(), arch_inputs.size(0))
+
+ # measure elapsed time
+ batch_time.update(time.time() - end)
+ end = time.time()
+
+ if step % print_freq == 0 or step + 1 == len(xloader):
+ Sstr = (
+ "*SEARCH* "
+ + time_string()
+ + " [{:}][{:03d}/{:03d}]".format(epoch_str, step, len(xloader))
+ )
+ Tstr = "Time {batch_time.val:.2f} ({batch_time.avg:.2f}) Data {data_time.val:.2f} ({data_time.avg:.2f})".format(
+ batch_time=batch_time, data_time=data_time
+ )
+ Wstr = "Base [Loss {loss.val:.3f} ({loss.avg:.3f}) Prec@1 {top1.val:.2f} ({top1.avg:.2f}) Prec@5 {top5.val:.2f} ({top5.avg:.2f})]".format(
+ loss=base_losses, top1=base_top1, top5=base_top5
+ )
+ Astr = "Arch [Loss {loss.val:.3f} ({loss.avg:.3f}) Prec@1 {top1.val:.2f} ({top1.avg:.2f}) Prec@5 {top5.val:.2f} ({top5.avg:.2f})]".format(
+ loss=arch_losses, top1=arch_top1, top5=arch_top5
+ )
+ logger.log(Sstr + " " + Tstr + " " + Wstr + " " + Astr)
+ return (
+ base_losses.avg,
+ base_top1.avg,
+ base_top5.avg,
+ arch_losses.avg,
+ arch_top1.avg,
+ arch_top5.avg,
+ )
+
+
+def valid_func(xloader, network, criterion, logger):
+ data_time, batch_time = AverageMeter(), AverageMeter()
+ arch_losses, arch_top1, arch_top5 = AverageMeter(), AverageMeter(), AverageMeter()
+ end = time.time()
+ with torch.no_grad():
+ network.eval()
+ for step, (arch_inputs, arch_targets) in enumerate(xloader):
+ arch_targets = arch_targets.cuda(non_blocking=True)
+ # measure data loading time
+ data_time.update(time.time() - end)
+ # prediction
+ _, logits, _ = network(arch_inputs.cuda(non_blocking=True))
+ arch_loss = criterion(logits, arch_targets)
+ # record
+ arch_prec1, arch_prec5 = obtain_accuracy(
+ logits.data, arch_targets.data, topk=(1, 5)
+ )
+ arch_losses.update(arch_loss.item(), arch_inputs.size(0))
+ arch_top1.update(arch_prec1.item(), arch_inputs.size(0))
+ arch_top5.update(arch_prec5.item(), arch_inputs.size(0))
+ # measure elapsed time
+ batch_time.update(time.time() - end)
+ end = time.time()
+ return arch_losses.avg, arch_top1.avg, arch_top5.avg
+
+
+def main(xargs):
+ assert torch.cuda.is_available(), "CUDA is not available."
+ torch.backends.cudnn.enabled = True
+ torch.backends.cudnn.benchmark = False
+ torch.backends.cudnn.deterministic = True
+ # torch.set_num_threads(xargs.workers)
+ prepare_seed(xargs.rand_seed)
+ logger = prepare_logger(args)
+
+ train_data, valid_data, xshape, class_num = get_datasets(
+ xargs.dataset, xargs.data_path, -1
+ )
+ if xargs.overwite_epochs is None:
+ extra_info = {"class_num": class_num, "xshape": xshape}
+ else:
+ extra_info = {
+ "class_num": class_num,
+ "xshape": xshape,
+ "epochs": xargs.overwite_epochs,
+ }
+ config = load_config(xargs.config_path, extra_info, logger)
+ search_loader, train_loader, valid_loader = get_nas_search_loaders(
+ train_data,
+ valid_data,
+ xargs.dataset,
+ "configs/nas-benchmark/",
+ (config.batch_size, config.test_batch_size),
+ xargs.workers,
+ )
+ logger.log(
+ "||||||| {:10s} ||||||| Search-Loader-Num={:}, Valid-Loader-Num={:}, batch size={:}".format(
+ xargs.dataset, len(search_loader), len(valid_loader), config.batch_size
+ )
+ )
+ logger.log("||||||| {:10s} ||||||| Config={:}".format(xargs.dataset, config))
+
+ search_space = get_search_spaces(xargs.search_space, "nats-bench")
+
+ model_config = dict2config(
+ dict(
+ name="generic",
+ super_type="search-shape",
+ candidate_Cs=search_space["candidates"],
+ max_num_Cs=search_space["numbers"],
+ num_classes=class_num,
+ genotype=args.genotype,
+ affine=bool(xargs.affine),
+ track_running_stats=bool(xargs.track_running_stats),
+ ),
+ None,
+ )
+ logger.log("search space : {:}".format(search_space))
+ logger.log("model config : {:}".format(model_config))
+ search_model = get_cell_based_tiny_net(model_config)
+ search_model.set_algo(xargs.algo)
+ logger.log("{:}".format(search_model))
+
+ w_optimizer, w_scheduler, criterion = get_optim_scheduler(
+ search_model.weights, config
+ )
+ a_optimizer = torch.optim.Adam(
+ search_model.alphas,
+ lr=xargs.arch_learning_rate,
+ betas=(0.5, 0.999),
+ weight_decay=xargs.arch_weight_decay,
+ eps=xargs.arch_eps,
+ )
+ logger.log("w-optimizer : {:}".format(w_optimizer))
+ logger.log("a-optimizer : {:}".format(a_optimizer))
+ logger.log("w-scheduler : {:}".format(w_scheduler))
+ logger.log("criterion : {:}".format(criterion))
+ params = count_parameters_in_MB(search_model)
+ logger.log("The parameters of the search model = {:.2f} MB".format(params))
+ logger.log("search-space : {:}".format(search_space))
+ if bool(xargs.use_api):
+ api = create(None, "size", fast_mode=True, verbose=False)
+ else:
+ api = None
+ logger.log("{:} create API = {:} done".format(time_string(), api))
+
+ last_info, model_base_path, model_best_path = (
+ logger.path("info"),
+ logger.path("model"),
+ logger.path("best"),
+ )
+ network, criterion = search_model.cuda(), criterion.cuda() # use a single GPU
+
+ last_info, model_base_path, model_best_path = (
+ logger.path("info"),
+ logger.path("model"),
+ logger.path("best"),
+ )
+
+ if last_info.exists(): # automatically resume from previous checkpoint
+ logger.log(
+ "=> loading checkpoint of the last-info '{:}' start".format(last_info)
+ )
+ last_info = torch.load(last_info)
+ start_epoch = last_info["epoch"]
+ checkpoint = torch.load(last_info["last_checkpoint"])
+ genotypes = checkpoint["genotypes"]
+ valid_accuracies = checkpoint["valid_accuracies"]
+ search_model.load_state_dict(checkpoint["search_model"])
+ w_scheduler.load_state_dict(checkpoint["w_scheduler"])
+ w_optimizer.load_state_dict(checkpoint["w_optimizer"])
+ a_optimizer.load_state_dict(checkpoint["a_optimizer"])
+ logger.log(
+ "=> loading checkpoint of the last-info '{:}' start with {:}-th epoch.".format(
+ last_info, start_epoch
+ )
+ )
+ else:
+ logger.log("=> do not find the last-info file : {:}".format(last_info))
+ start_epoch, valid_accuracies, genotypes = 0, {"best": -1}, {-1: network.random}
+
+ # start training
+ start_time, search_time, epoch_time, total_epoch = (
+ time.time(),
+ AverageMeter(),
+ AverageMeter(),
+ config.epochs + config.warmup,
+ )
+ for epoch in range(start_epoch, total_epoch):
+ w_scheduler.update(epoch, 0.0)
+ need_time = "Time Left: {:}".format(
+ convert_secs2time(epoch_time.val * (total_epoch - epoch), True)
+ )
+ epoch_str = "{:03d}-{:03d}".format(epoch, total_epoch)
+
+ if (
+ xargs.warmup_ratio is None
+ or xargs.warmup_ratio <= float(epoch) / total_epoch
+ ):
+ enable_controller = True
+ network.set_warmup_ratio(None)
+ else:
+ enable_controller = False
+ network.set_warmup_ratio(
+ 1.0 - float(epoch) / total_epoch / xargs.warmup_ratio
+ )
+
+ logger.log(
+ "\n[Search the {:}-th epoch] {:}, LR={:}, controller-warmup={:}, enable_controller={:}".format(
+ epoch_str,
+ need_time,
+ min(w_scheduler.get_lr()),
+ network.warmup_ratio,
+ enable_controller,
+ )
+ )
+
+ if xargs.algo == "mask_gumbel" or xargs.algo == "tas":
+ network.set_tau(
+ xargs.tau_max
+ - (xargs.tau_max - xargs.tau_min) * epoch / (total_epoch - 1)
+ )
+ logger.log("[RESET tau as : {:}]".format(network.tau))
+ (
+ search_w_loss,
+ search_w_top1,
+ search_w_top5,
+ search_a_loss,
+ search_a_top1,
+ search_a_top5,
+ ) = search_func(
+ search_loader,
+ network,
+ criterion,
+ w_scheduler,
+ w_optimizer,
+ a_optimizer,
+ enable_controller,
+ xargs.algo,
+ epoch_str,
+ xargs.print_freq,
+ logger,
+ )
+ search_time.update(time.time() - start_time)
+ logger.log(
+ "[{:}] search [base] : loss={:.2f}, accuracy@1={:.2f}%, accuracy@5={:.2f}%, time-cost={:.1f} s".format(
+ epoch_str, search_w_loss, search_w_top1, search_w_top5, search_time.sum
+ )
+ )
+ logger.log(
+ "[{:}] search [arch] : loss={:.2f}, accuracy@1={:.2f}%, accuracy@5={:.2f}%".format(
+ epoch_str, search_a_loss, search_a_top1, search_a_top5
+ )
+ )
+
+ genotype = network.genotype
+ logger.log("[{:}] - [get_best_arch] : {:}".format(epoch_str, genotype))
+ valid_a_loss, valid_a_top1, valid_a_top5 = valid_func(
+ valid_loader, network, criterion, logger
+ )
+ logger.log(
+ "[{:}] evaluate : loss={:.2f}, accuracy@1={:.2f}%, accuracy@5={:.2f}% | {:}".format(
+ epoch_str, valid_a_loss, valid_a_top1, valid_a_top5, genotype
+ )
+ )
+ valid_accuracies[epoch] = valid_a_top1
+
+ genotypes[epoch] = genotype
+ logger.log(
+ "<<<--->>> The {:}-th epoch : {:}".format(epoch_str, genotypes[epoch])
+ )
+ # save checkpoint
+ save_path = save_checkpoint(
+ {
+ "epoch": epoch + 1,
+ "args": deepcopy(xargs),
+ "search_model": search_model.state_dict(),
+ "w_optimizer": w_optimizer.state_dict(),
+ "a_optimizer": a_optimizer.state_dict(),
+ "w_scheduler": w_scheduler.state_dict(),
+ "genotypes": genotypes,
+ "valid_accuracies": valid_accuracies,
+ },
+ model_base_path,
+ logger,
+ )
+ last_info = save_checkpoint(
+ {
+ "epoch": epoch + 1,
+ "args": deepcopy(args),
+ "last_checkpoint": save_path,
+ },
+ logger.path("info"),
+ logger,
+ )
+ with torch.no_grad():
+ logger.log("{:}".format(search_model.show_alphas()))
+ if api is not None:
+ logger.log("{:}".format(api.query_by_arch(genotypes[epoch], "90")))
+ # measure elapsed time
+ epoch_time.update(time.time() - start_time)
+ start_time = time.time()
+
+ # the final post procedure : count the time
+ start_time = time.time()
+ genotype = network.genotype
+ search_time.update(time.time() - start_time)
+
+ valid_a_loss, valid_a_top1, valid_a_top5 = valid_func(
+ valid_loader, network, criterion, logger
+ )
+ logger.log(
+ "Last : the gentotype is : {:}, with the validation accuracy of {:.3f}%.".format(
+ genotype, valid_a_top1
+ )
+ )
+
+ logger.log("\n" + "-" * 100)
+ # check the performance from the architecture dataset
+ logger.log(
+ "[{:}] run {:} epochs, cost {:.1f} s, last-geno is {:}.".format(
+ xargs.algo, total_epoch, search_time.sum, genotype
+ )
+ )
+ if api is not None:
+ logger.log("{:}".format(api.query_by_arch(genotype, "90")))
+ logger.close()
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser("Weight sharing NAS methods to search for cells.")
+ parser.add_argument("--data_path", type=str, help="Path to dataset")
+ parser.add_argument(
+ "--dataset",
+ type=str,
+ choices=["cifar10", "cifar100", "ImageNet16-120"],
+ help="Choose between Cifar10/100 and ImageNet-16.",
+ )
+ parser.add_argument(
+ "--search_space",
+ type=str,
+ default="sss",
+ choices=["sss"],
+ help="The search space name.",
+ )
+ parser.add_argument(
+ "--algo",
+ type=str,
+ choices=["tas", "mask_gumbel", "mask_rl"],
+ help="The search space name.",
+ )
+ parser.add_argument(
+ "--genotype",
+ type=str,
+ default="|nor_conv_3x3~0|+|nor_conv_3x3~0|nor_conv_3x3~1|+|skip_connect~0|nor_conv_3x3~1|nor_conv_3x3~2|",
+ help="The genotype.",
+ )
+ parser.add_argument(
+ "--use_api",
+ type=int,
+ default=1,
+ choices=[0, 1],
+ help="Whether use API or not (which will cost much memory).",
+ )
+ # FOR GDAS
+ parser.add_argument(
+ "--tau_min", type=float, default=0.1, help="The minimum tau for Gumbel Softmax."
+ )
+ parser.add_argument(
+ "--tau_max", type=float, default=10, help="The maximum tau for Gumbel Softmax."
+ )
+ # FOR ALL
+ parser.add_argument(
+ "--warmup_ratio", type=float, help="The warmup ratio, if None, not use warmup."
+ )
+ #
+ parser.add_argument(
+ "--track_running_stats",
+ type=int,
+ default=0,
+ choices=[0, 1],
+ help="Whether use track_running_stats or not in the BN layer.",
+ )
+ parser.add_argument(
+ "--affine",
+ type=int,
+ default=0,
+ choices=[0, 1],
+ help="Whether use affine=True or False in the BN layer.",
+ )
+ parser.add_argument(
+ "--config_path",
+ type=str,
+ default="./configs/nas-benchmark/algos/weight-sharing.config",
+ help="The path of configuration.",
+ )
+ parser.add_argument(
+ "--overwite_epochs",
+ type=int,
+ help="The number of epochs to overwrite that value in config files.",
+ )
+ # architecture leraning rate
+ parser.add_argument(
+ "--arch_learning_rate",
+ type=float,
+ default=3e-4,
+ help="learning rate for arch encoding",
+ )
+ parser.add_argument(
+ "--arch_weight_decay",
+ type=float,
+ default=1e-3,
+ help="weight decay for arch encoding",
+ )
+ parser.add_argument(
+ "--arch_eps", type=float, default=1e-8, help="weight decay for arch encoding"
+ )
+ # log
+ parser.add_argument(
+ "--workers",
+ type=int,
+ default=2,
+ help="number of data loading workers (default: 2)",
+ )
+ parser.add_argument(
+ "--save_dir",
+ type=str,
+ default="./output/search",
+ help="Folder to save checkpoints and log.",
+ )
+ parser.add_argument(
+ "--print_freq", type=int, default=200, help="print frequency (default: 200)"
+ )
+ parser.add_argument("--rand_seed", type=int, help="manual seed")
+ args = parser.parse_args()
+ if args.rand_seed is None or args.rand_seed < 0:
+ args.rand_seed = random.randint(1, 100000)
+ dirname = "{:}-affine{:}_BN{:}-AWD{:}-WARM{:}".format(
+ args.algo,
+ args.affine,
+ args.track_running_stats,
+ args.arch_weight_decay,
+ args.warmup_ratio,
+ )
+ if args.overwite_epochs is not None:
+ dirname = dirname + "-E{:}".format(args.overwite_epochs)
+ args.save_dir = os.path.join(
+ "{:}-{:}".format(args.save_dir, args.search_space), args.dataset, dirname
+ )
+
+ main(args)
diff --git a/AutoDL-Projects/exps/TAS/prepare.py b/AutoDL-Projects/exps/TAS/prepare.py
new file mode 100644
index 0000000..94ff723
--- /dev/null
+++ b/AutoDL-Projects/exps/TAS/prepare.py
@@ -0,0 +1,91 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.01 #
+#####################################################
+# python exps/prepare.py --name cifar10 --root $TORCH_HOME/cifar.python --save ./data/cifar10.split.pth
+# python exps/prepare.py --name cifar100 --root $TORCH_HOME/cifar.python --save ./data/cifar100.split.pth
+# python exps/prepare.py --name imagenet-1k --root $TORCH_HOME/ILSVRC2012 --save ./data/imagenet-1k.split.pth
+#####################################################
+import sys, time, torch, random, argparse
+from collections import defaultdict
+import os.path as osp
+from PIL import ImageFile
+
+ImageFile.LOAD_TRUNCATED_IMAGES = True
+from copy import deepcopy
+from pathlib import Path
+import torchvision
+import torchvision.datasets as dset
+
+parser = argparse.ArgumentParser(
+ description="Prepare splits for searching",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+)
+parser.add_argument("--name", type=str, help="The dataset name.")
+parser.add_argument("--root", type=str, help="The directory to the dataset.")
+parser.add_argument("--save", type=str, help="The save path.")
+parser.add_argument("--ratio", type=float, help="The save path.")
+args = parser.parse_args()
+
+
+def main():
+ save_path = Path(args.save)
+ save_dir = save_path.parent
+ name = args.name
+ save_dir.mkdir(parents=True, exist_ok=True)
+ assert not save_path.exists(), "{:} already exists".format(save_path)
+ print("torchvision version : {:}".format(torchvision.__version__))
+
+ if name == "cifar10":
+ dataset = dset.CIFAR10(args.root, train=True, download=True)
+ elif name == "cifar100":
+ dataset = dset.CIFAR100(args.root, train=True, download=True)
+ elif name == "imagenet-1k":
+ dataset = dset.ImageFolder(osp.join(args.root, "train"))
+ else:
+ raise TypeError("Unknow dataset : {:}".format(name))
+
+ if hasattr(dataset, "targets"):
+ targets = dataset.targets
+ elif hasattr(dataset, "train_labels"):
+ targets = dataset.train_labels
+ elif hasattr(dataset, "imgs"):
+ targets = [x[1] for x in dataset.imgs]
+ else:
+ raise ValueError("invalid pattern")
+ print("There are {:} samples in this dataset.".format(len(targets)))
+
+ class2index = defaultdict(list)
+ train, valid = [], []
+ random.seed(111)
+ for index, cls in enumerate(targets):
+ class2index[cls].append(index)
+ classes = sorted(list(class2index.keys()))
+ for cls in classes:
+ xlist = class2index[cls]
+ xtrain = random.sample(xlist, int(len(xlist) * args.ratio))
+ xvalid = list(set(xlist) - set(xtrain))
+ train += xtrain
+ valid += xvalid
+ train.sort()
+ valid.sort()
+ ## for statistics
+ class2numT, class2numV = defaultdict(int), defaultdict(int)
+ for index in train:
+ class2numT[targets[index]] += 1
+ for index in valid:
+ class2numV[targets[index]] += 1
+ class2numT, class2numV = dict(class2numT), dict(class2numV)
+ torch.save(
+ {
+ "train": train,
+ "valid": valid,
+ "class2numTrain": class2numT,
+ "class2numValid": class2numV,
+ },
+ save_path,
+ )
+ print("-" * 80)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/AutoDL-Projects/exps/TAS/search-shape.py b/AutoDL-Projects/exps/TAS/search-shape.py
new file mode 100644
index 0000000..4112dd9
--- /dev/null
+++ b/AutoDL-Projects/exps/TAS/search-shape.py
@@ -0,0 +1,382 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.01 #
+#####################################################
+import sys, time, torch, random, argparse
+from PIL import ImageFile
+from os import path as osp
+
+ImageFile.LOAD_TRUNCATED_IMAGES = True
+import numpy as np
+from copy import deepcopy
+from pathlib import Path
+
+from xautodl.config_utils import (
+ load_config,
+ configure2str,
+ obtain_search_single_args as obtain_args,
+)
+from xautodl.procedures import (
+ prepare_seed,
+ prepare_logger,
+ save_checkpoint,
+ copy_checkpoint,
+)
+from xautodl.procedures import get_optim_scheduler, get_procedures
+from xautodl.datasets import get_datasets, SearchDataset
+from xautodl.models import obtain_search_model, obtain_model, change_key
+from xautodl.utils import get_model_infos
+from xautodl.log_utils import AverageMeter, time_string, convert_secs2time
+
+
+def main(args):
+ assert torch.cuda.is_available(), "CUDA is not available."
+ torch.backends.cudnn.enabled = True
+ torch.backends.cudnn.benchmark = True
+ # torch.backends.cudnn.deterministic = True
+ # torch.set_num_threads(args.workers)
+
+ prepare_seed(args.rand_seed)
+ logger = prepare_logger(args)
+
+ # prepare dataset
+ train_data, valid_data, xshape, class_num = get_datasets(
+ args.dataset, args.data_path, args.cutout_length
+ )
+ # train_loader = torch.utils.data.DataLoader(train_data, batch_size=args.batch_size, shuffle=True , num_workers=args.workers, pin_memory=True)
+ valid_loader = torch.utils.data.DataLoader(
+ valid_data,
+ batch_size=args.batch_size,
+ shuffle=False,
+ num_workers=args.workers,
+ pin_memory=True,
+ )
+
+ split_file_path = Path(args.split_path)
+ assert split_file_path.exists(), "{:} does not exist".format(split_file_path)
+ split_info = torch.load(split_file_path)
+
+ train_split, valid_split = split_info["train"], split_info["valid"]
+ assert (
+ len(set(train_split).intersection(set(valid_split))) == 0
+ ), "There should be 0 element that belongs to both train and valid"
+ assert len(train_split) + len(valid_split) == len(
+ train_data
+ ), "{:} + {:} vs {:}".format(len(train_split), len(valid_split), len(train_data))
+ search_dataset = SearchDataset(args.dataset, train_data, train_split, valid_split)
+
+ search_train_loader = torch.utils.data.DataLoader(
+ train_data,
+ batch_size=args.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(train_split),
+ pin_memory=True,
+ num_workers=args.workers,
+ )
+ search_valid_loader = torch.utils.data.DataLoader(
+ train_data,
+ batch_size=args.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(valid_split),
+ pin_memory=True,
+ num_workers=args.workers,
+ )
+ search_loader = torch.utils.data.DataLoader(
+ search_dataset,
+ batch_size=args.batch_size,
+ shuffle=True,
+ num_workers=args.workers,
+ pin_memory=True,
+ sampler=None,
+ )
+ # get configures
+ model_config = load_config(
+ args.model_config,
+ {"class_num": class_num, "search_mode": args.search_shape},
+ logger,
+ )
+
+ # obtain the model
+ search_model = obtain_search_model(model_config)
+ MAX_FLOP, param = get_model_infos(search_model, xshape)
+ optim_config = load_config(
+ args.optim_config, {"class_num": class_num, "FLOP": MAX_FLOP}, logger
+ )
+ logger.log("Model Information : {:}".format(search_model.get_message()))
+ logger.log("MAX_FLOP = {:} M".format(MAX_FLOP))
+ logger.log("Params = {:} M".format(param))
+ logger.log("train_data : {:}".format(train_data))
+ logger.log("search-data: {:}".format(search_dataset))
+ logger.log("search_train_loader : {:} samples".format(len(train_split)))
+ logger.log("search_valid_loader : {:} samples".format(len(valid_split)))
+ base_optimizer, scheduler, criterion = get_optim_scheduler(
+ search_model.base_parameters(), optim_config
+ )
+ arch_optimizer = torch.optim.Adam(
+ search_model.arch_parameters(),
+ lr=optim_config.arch_LR,
+ betas=(0.5, 0.999),
+ weight_decay=optim_config.arch_decay,
+ )
+ logger.log("base-optimizer : {:}".format(base_optimizer))
+ logger.log("arch-optimizer : {:}".format(arch_optimizer))
+ logger.log("scheduler : {:}".format(scheduler))
+ logger.log("criterion : {:}".format(criterion))
+
+ last_info, model_base_path, model_best_path = (
+ logger.path("info"),
+ logger.path("model"),
+ logger.path("best"),
+ )
+ network, criterion = torch.nn.DataParallel(search_model).cuda(), criterion.cuda()
+
+ # load checkpoint
+ if last_info.exists() or (
+ args.resume is not None and osp.isfile(args.resume)
+ ): # automatically resume from previous checkpoint
+ if args.resume is not None and osp.isfile(args.resume):
+ resume_path = Path(args.resume)
+ elif last_info.exists():
+ resume_path = last_info
+ else:
+ raise ValueError("Something is wrong.")
+ logger.log(
+ "=> loading checkpoint of the last-info '{:}' start".format(resume_path)
+ )
+ checkpoint = torch.load(resume_path)
+ if "last_checkpoint" in checkpoint:
+ last_checkpoint_path = checkpoint["last_checkpoint"]
+ if not last_checkpoint_path.exists():
+ logger.log(
+ "Does not find {:}, try another path".format(last_checkpoint_path)
+ )
+ last_checkpoint_path = (
+ resume_path.parent
+ / last_checkpoint_path.parent.name
+ / last_checkpoint_path.name
+ )
+ assert (
+ last_checkpoint_path.exists()
+ ), "can not find the checkpoint from {:}".format(last_checkpoint_path)
+ checkpoint = torch.load(last_checkpoint_path)
+ start_epoch = checkpoint["epoch"] + 1
+ search_model.load_state_dict(checkpoint["search_model"])
+ scheduler.load_state_dict(checkpoint["scheduler"])
+ base_optimizer.load_state_dict(checkpoint["base_optimizer"])
+ arch_optimizer.load_state_dict(checkpoint["arch_optimizer"])
+ valid_accuracies = checkpoint["valid_accuracies"]
+ arch_genotypes = checkpoint["arch_genotypes"]
+ discrepancies = checkpoint["discrepancies"]
+ logger.log(
+ "=> loading checkpoint of the last-info '{:}' start with {:}-th epoch.".format(
+ resume_path, start_epoch
+ )
+ )
+ else:
+ logger.log(
+ "=> do not find the last-info file : {:} or resume : {:}".format(
+ last_info, args.resume
+ )
+ )
+ start_epoch, valid_accuracies, arch_genotypes, discrepancies = (
+ 0,
+ {"best": -1},
+ {},
+ {},
+ )
+
+ # main procedure
+ train_func, valid_func = get_procedures(args.procedure)
+ total_epoch = optim_config.epochs + optim_config.warmup
+ start_time, epoch_time = time.time(), AverageMeter()
+ for epoch in range(start_epoch, total_epoch):
+ scheduler.update(epoch, 0.0)
+ search_model.set_tau(
+ args.gumbel_tau_max, args.gumbel_tau_min, epoch * 1.0 / total_epoch
+ )
+ need_time = "Time Left: {:}".format(
+ convert_secs2time(epoch_time.avg * (total_epoch - epoch), True)
+ )
+ epoch_str = "epoch={:03d}/{:03d}".format(epoch, total_epoch)
+ LRs = scheduler.get_lr()
+ find_best = False
+
+ logger.log(
+ "\n***{:s}*** start {:s} {:s}, LR=[{:.6f} ~ {:.6f}], scheduler={:}, tau={:}, FLOP={:.2f}".format(
+ time_string(),
+ epoch_str,
+ need_time,
+ min(LRs),
+ max(LRs),
+ scheduler,
+ search_model.tau,
+ MAX_FLOP,
+ )
+ )
+
+ # train for one epoch
+ train_base_loss, train_arch_loss, train_acc1, train_acc5 = train_func(
+ search_loader,
+ network,
+ criterion,
+ scheduler,
+ base_optimizer,
+ arch_optimizer,
+ optim_config,
+ {
+ "epoch-str": epoch_str,
+ "FLOP-exp": MAX_FLOP * args.FLOP_ratio,
+ "FLOP-weight": args.FLOP_weight,
+ "FLOP-tolerant": MAX_FLOP * args.FLOP_tolerant,
+ },
+ args.print_freq,
+ logger,
+ )
+ # log the results
+ logger.log(
+ "***{:s}*** TRAIN [{:}] base-loss = {:.6f}, arch-loss = {:.6f}, accuracy-1 = {:.2f}, accuracy-5 = {:.2f}".format(
+ time_string(),
+ epoch_str,
+ train_base_loss,
+ train_arch_loss,
+ train_acc1,
+ train_acc5,
+ )
+ )
+ cur_FLOP, genotype = search_model.get_flop(
+ "genotype", model_config._asdict(), None
+ )
+ arch_genotypes[epoch] = genotype
+ arch_genotypes["last"] = genotype
+ logger.log("[{:}] genotype : {:}".format(epoch_str, genotype))
+ arch_info, discrepancy = search_model.get_arch_info()
+ logger.log(arch_info)
+ discrepancies[epoch] = discrepancy
+ logger.log(
+ "[{:}] FLOP : {:.2f} MB, ratio : {:.4f}, Expected-ratio : {:.4f}, Discrepancy : {:.3f}".format(
+ epoch_str,
+ cur_FLOP,
+ cur_FLOP / MAX_FLOP,
+ args.FLOP_ratio,
+ np.mean(discrepancy),
+ )
+ )
+
+ # if cur_FLOP/MAX_FLOP > args.FLOP_ratio:
+ # init_flop_weight = init_flop_weight * args.FLOP_decay
+ # else:
+ # init_flop_weight = init_flop_weight / args.FLOP_decay
+
+ # evaluate the performance
+ if (epoch % args.eval_frequency == 0) or (epoch + 1 == total_epoch):
+ logger.log("-" * 150)
+ valid_loss, valid_acc1, valid_acc5 = valid_func(
+ search_valid_loader,
+ network,
+ criterion,
+ epoch_str,
+ args.print_freq_eval,
+ logger,
+ )
+ valid_accuracies[epoch] = valid_acc1
+ logger.log(
+ "***{:s}*** VALID [{:}] loss = {:.6f}, accuracy@1 = {:.2f}, accuracy@5 = {:.2f} | Best-Valid-Acc@1={:.2f}, Error@1={:.2f}".format(
+ time_string(),
+ epoch_str,
+ valid_loss,
+ valid_acc1,
+ valid_acc5,
+ valid_accuracies["best"],
+ 100 - valid_accuracies["best"],
+ )
+ )
+ if valid_acc1 > valid_accuracies["best"]:
+ valid_accuracies["best"] = valid_acc1
+ arch_genotypes["best"] = genotype
+ find_best = True
+ logger.log(
+ "Currently, the best validation accuracy found at {:03d}-epoch :: acc@1={:.2f}, acc@5={:.2f}, error@1={:.2f}, error@5={:.2f}, save into {:}.".format(
+ epoch,
+ valid_acc1,
+ valid_acc5,
+ 100 - valid_acc1,
+ 100 - valid_acc5,
+ model_best_path,
+ )
+ )
+
+ # save checkpoint
+ save_path = save_checkpoint(
+ {
+ "epoch": epoch,
+ "args": deepcopy(args),
+ "valid_accuracies": deepcopy(valid_accuracies),
+ "model-config": model_config._asdict(),
+ "optim-config": optim_config._asdict(),
+ "search_model": search_model.state_dict(),
+ "scheduler": scheduler.state_dict(),
+ "base_optimizer": base_optimizer.state_dict(),
+ "arch_optimizer": arch_optimizer.state_dict(),
+ "arch_genotypes": arch_genotypes,
+ "discrepancies": discrepancies,
+ },
+ model_base_path,
+ logger,
+ )
+ if find_best:
+ copy_checkpoint(model_base_path, model_best_path, logger)
+ last_info = save_checkpoint(
+ {
+ "epoch": epoch,
+ "args": deepcopy(args),
+ "last_checkpoint": save_path,
+ },
+ logger.path("info"),
+ logger,
+ )
+
+ # measure elapsed time
+ epoch_time.update(time.time() - start_time)
+ start_time = time.time()
+
+ logger.log("")
+ logger.log("-" * 100)
+ last_config_path = logger.path("log") / "seed-{:}-last.config".format(
+ args.rand_seed
+ )
+ configure2str(arch_genotypes["last"], str(last_config_path))
+ logger.log(
+ "save the last config int {:} :\n{:}".format(
+ last_config_path, arch_genotypes["last"]
+ )
+ )
+
+ best_arch, valid_acc = arch_genotypes["best"], valid_accuracies["best"]
+ for key, config in arch_genotypes.items():
+ if key == "last":
+ continue
+ FLOP_ratio = config["estimated_FLOP"] / MAX_FLOP
+ if abs(FLOP_ratio - args.FLOP_ratio) <= args.FLOP_tolerant:
+ if valid_acc < valid_accuracies[key]:
+ best_arch, valid_acc = config, valid_accuracies[key]
+ print(
+ "Best-Arch : {:}\nRatio={:}, Valid-ACC={:}".format(
+ best_arch, best_arch["estimated_FLOP"] / MAX_FLOP, valid_acc
+ )
+ )
+ best_config_path = logger.path("log") / "seed-{:}-best.config".format(
+ args.rand_seed
+ )
+ configure2str(best_arch, str(best_config_path))
+ logger.log(
+ "save the last config int {:} :\n{:}".format(best_config_path, best_arch)
+ )
+ logger.log("\n" + "-" * 200)
+ logger.log(
+ "Finish training/validation in {:}, and save final checkpoint into {:}".format(
+ convert_secs2time(epoch_time.sum, True), logger.path("info")
+ )
+ )
+ logger.close()
+
+
+if __name__ == "__main__":
+ args = obtain_args()
+ main(args)
diff --git a/AutoDL-Projects/exps/TAS/search-transformable.py b/AutoDL-Projects/exps/TAS/search-transformable.py
new file mode 100644
index 0000000..279371c
--- /dev/null
+++ b/AutoDL-Projects/exps/TAS/search-transformable.py
@@ -0,0 +1,420 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.01 #
+#######################################################################
+# Network Pruning via Transformable Architecture Search, NeurIPS 2019 #
+#######################################################################
+import sys, time, torch, random, argparse
+from PIL import ImageFile
+from os import path as osp
+
+ImageFile.LOAD_TRUNCATED_IMAGES = True
+import numpy as np
+from copy import deepcopy
+from pathlib import Path
+
+from xautodl.config_utils import (
+ load_config,
+ configure2str,
+ obtain_search_args as obtain_args,
+)
+from xautodl.procedures import (
+ prepare_seed,
+ prepare_logger,
+ save_checkpoint,
+ copy_checkpoint,
+)
+from xautodl.procedures import get_optim_scheduler, get_procedures
+from xautodl.datasets import get_datasets, SearchDataset
+from xautodl.models import obtain_search_model, obtain_model, change_key
+from xautodl.utils import get_model_infos
+from xautodl.log_utils import AverageMeter, time_string, convert_secs2time
+
+
+def main(args):
+ assert torch.cuda.is_available(), "CUDA is not available."
+ torch.backends.cudnn.enabled = True
+ torch.backends.cudnn.benchmark = True
+ # torch.backends.cudnn.deterministic = True
+ torch.set_num_threads(args.workers)
+
+ prepare_seed(args.rand_seed)
+ logger = prepare_logger(args)
+
+ # prepare dataset
+ train_data, valid_data, xshape, class_num = get_datasets(
+ args.dataset, args.data_path, args.cutout_length
+ )
+ # train_loader = torch.utils.data.DataLoader(train_data, batch_size=args.batch_size, shuffle=True , num_workers=args.workers, pin_memory=True)
+ valid_loader = torch.utils.data.DataLoader(
+ valid_data,
+ batch_size=args.batch_size,
+ shuffle=False,
+ num_workers=args.workers,
+ pin_memory=True,
+ )
+
+ split_file_path = Path(args.split_path)
+ assert split_file_path.exists(), "{:} does not exist".format(split_file_path)
+ split_info = torch.load(split_file_path)
+
+ train_split, valid_split = split_info["train"], split_info["valid"]
+ assert (
+ len(set(train_split).intersection(set(valid_split))) == 0
+ ), "There should be 0 element that belongs to both train and valid"
+ assert len(train_split) + len(valid_split) == len(
+ train_data
+ ), "{:} + {:} vs {:}".format(len(train_split), len(valid_split), len(train_data))
+ search_dataset = SearchDataset(args.dataset, train_data, train_split, valid_split)
+
+ search_train_loader = torch.utils.data.DataLoader(
+ train_data,
+ batch_size=args.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(train_split),
+ pin_memory=True,
+ num_workers=args.workers,
+ )
+ search_valid_loader = torch.utils.data.DataLoader(
+ train_data,
+ batch_size=args.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(valid_split),
+ pin_memory=True,
+ num_workers=args.workers,
+ )
+ search_loader = torch.utils.data.DataLoader(
+ search_dataset,
+ batch_size=args.batch_size,
+ shuffle=True,
+ num_workers=args.workers,
+ pin_memory=True,
+ sampler=None,
+ )
+ # get configures
+ if args.ablation_num_select is None or args.ablation_num_select <= 0:
+ model_config = load_config(
+ args.model_config, {"class_num": class_num, "search_mode": "shape"}, logger
+ )
+ else:
+ model_config = load_config(
+ args.model_config,
+ {
+ "class_num": class_num,
+ "search_mode": "ablation",
+ "num_random_select": args.ablation_num_select,
+ },
+ logger,
+ )
+
+ # obtain the model
+ search_model = obtain_search_model(model_config)
+ MAX_FLOP, param = get_model_infos(search_model, xshape)
+ optim_config = load_config(
+ args.optim_config, {"class_num": class_num, "FLOP": MAX_FLOP}, logger
+ )
+ logger.log("Model Information : {:}".format(search_model.get_message()))
+ logger.log("MAX_FLOP = {:} M".format(MAX_FLOP))
+ logger.log("Params = {:} M".format(param))
+ logger.log("train_data : {:}".format(train_data))
+ logger.log("search-data: {:}".format(search_dataset))
+ logger.log("search_train_loader : {:} samples".format(len(train_split)))
+ logger.log("search_valid_loader : {:} samples".format(len(valid_split)))
+ base_optimizer, scheduler, criterion = get_optim_scheduler(
+ search_model.base_parameters(), optim_config
+ )
+ arch_optimizer = torch.optim.Adam(
+ search_model.arch_parameters(optim_config.arch_LR),
+ lr=optim_config.arch_LR,
+ betas=(0.5, 0.999),
+ weight_decay=optim_config.arch_decay,
+ )
+ logger.log("base-optimizer : {:}".format(base_optimizer))
+ logger.log("arch-optimizer : {:}".format(arch_optimizer))
+ logger.log("scheduler : {:}".format(scheduler))
+ logger.log("criterion : {:}".format(criterion))
+
+ last_info, model_base_path, model_best_path = (
+ logger.path("info"),
+ logger.path("model"),
+ logger.path("best"),
+ )
+ network, criterion = torch.nn.DataParallel(search_model).cuda(), criterion.cuda()
+
+ # load checkpoint
+ if last_info.exists() or (
+ args.resume is not None and osp.isfile(args.resume)
+ ): # automatically resume from previous checkpoint
+ if args.resume is not None and osp.isfile(args.resume):
+ resume_path = Path(args.resume)
+ elif last_info.exists():
+ resume_path = last_info
+ else:
+ raise ValueError("Something is wrong.")
+ logger.log(
+ "=> loading checkpoint of the last-info '{:}' start".format(resume_path)
+ )
+ checkpoint = torch.load(resume_path)
+ if "last_checkpoint" in checkpoint:
+ last_checkpoint_path = checkpoint["last_checkpoint"]
+ if not last_checkpoint_path.exists():
+ logger.log(
+ "Does not find {:}, try another path".format(last_checkpoint_path)
+ )
+ last_checkpoint_path = (
+ resume_path.parent
+ / last_checkpoint_path.parent.name
+ / last_checkpoint_path.name
+ )
+ assert (
+ last_checkpoint_path.exists()
+ ), "can not find the checkpoint from {:}".format(last_checkpoint_path)
+ checkpoint = torch.load(last_checkpoint_path)
+ start_epoch = checkpoint["epoch"] + 1
+ # for key, value in checkpoint['search_model'].items():
+ # print('K {:} = Shape={:}'.format(key, value.shape))
+ search_model.load_state_dict(checkpoint["search_model"])
+ scheduler.load_state_dict(checkpoint["scheduler"])
+ base_optimizer.load_state_dict(checkpoint["base_optimizer"])
+ arch_optimizer.load_state_dict(checkpoint["arch_optimizer"])
+ valid_accuracies = checkpoint["valid_accuracies"]
+ arch_genotypes = checkpoint["arch_genotypes"]
+ discrepancies = checkpoint["discrepancies"]
+ max_bytes = checkpoint["max_bytes"]
+ logger.log(
+ "=> loading checkpoint of the last-info '{:}' start with {:}-th epoch.".format(
+ resume_path, start_epoch
+ )
+ )
+ else:
+ logger.log(
+ "=> do not find the last-info file : {:} or resume : {:}".format(
+ last_info, args.resume
+ )
+ )
+ start_epoch, valid_accuracies, arch_genotypes, discrepancies, max_bytes = (
+ 0,
+ {"best": -1},
+ {},
+ {},
+ {},
+ )
+
+ # main procedure
+ train_func, valid_func = get_procedures(args.procedure)
+ total_epoch = optim_config.epochs + optim_config.warmup
+ start_time, epoch_time = time.time(), AverageMeter()
+ for epoch in range(start_epoch, total_epoch):
+ scheduler.update(epoch, 0.0)
+ search_model.set_tau(
+ args.gumbel_tau_max, args.gumbel_tau_min, epoch * 1.0 / total_epoch
+ )
+ need_time = "Time Left: {:}".format(
+ convert_secs2time(epoch_time.avg * (total_epoch - epoch), True)
+ )
+ epoch_str = "epoch={:03d}/{:03d}".format(epoch, total_epoch)
+ LRs = scheduler.get_lr()
+ find_best = False
+
+ logger.log(
+ "\n***{:s}*** start {:s} {:s}, LR=[{:.6f} ~ {:.6f}], scheduler={:}, tau={:}, FLOP={:.2f}".format(
+ time_string(),
+ epoch_str,
+ need_time,
+ min(LRs),
+ max(LRs),
+ scheduler,
+ search_model.tau,
+ MAX_FLOP,
+ )
+ )
+
+ # train for one epoch
+ train_base_loss, train_arch_loss, train_acc1, train_acc5 = train_func(
+ search_loader,
+ network,
+ criterion,
+ scheduler,
+ base_optimizer,
+ arch_optimizer,
+ optim_config,
+ {
+ "epoch-str": epoch_str,
+ "FLOP-exp": MAX_FLOP * args.FLOP_ratio,
+ "FLOP-weight": args.FLOP_weight,
+ "FLOP-tolerant": MAX_FLOP * args.FLOP_tolerant,
+ },
+ args.print_freq,
+ logger,
+ )
+ # log the results
+ logger.log(
+ "***{:s}*** TRAIN [{:}] base-loss = {:.6f}, arch-loss = {:.6f}, accuracy-1 = {:.2f}, accuracy-5 = {:.2f}".format(
+ time_string(),
+ epoch_str,
+ train_base_loss,
+ train_arch_loss,
+ train_acc1,
+ train_acc5,
+ )
+ )
+ cur_FLOP, genotype = search_model.get_flop(
+ "genotype", model_config._asdict(), None
+ )
+ arch_genotypes[epoch] = genotype
+ arch_genotypes["last"] = genotype
+ logger.log("[{:}] genotype : {:}".format(epoch_str, genotype))
+ # save the configuration
+ configure2str(
+ genotype,
+ str(logger.path("log") / "seed-{:}-temp.config".format(args.rand_seed)),
+ )
+ arch_info, discrepancy = search_model.get_arch_info()
+ logger.log(arch_info)
+ discrepancies[epoch] = discrepancy
+ logger.log(
+ "[{:}] FLOP : {:.2f} MB, ratio : {:.4f}, Expected-ratio : {:.4f}, Discrepancy : {:.3f}".format(
+ epoch_str,
+ cur_FLOP,
+ cur_FLOP / MAX_FLOP,
+ args.FLOP_ratio,
+ np.mean(discrepancy),
+ )
+ )
+
+ # if cur_FLOP/MAX_FLOP > args.FLOP_ratio:
+ # init_flop_weight = init_flop_weight * args.FLOP_decay
+ # else:
+ # init_flop_weight = init_flop_weight / args.FLOP_decay
+
+ # evaluate the performance
+ if (epoch % args.eval_frequency == 0) or (epoch + 1 == total_epoch):
+ logger.log("-" * 150)
+ valid_loss, valid_acc1, valid_acc5 = valid_func(
+ search_valid_loader,
+ network,
+ criterion,
+ epoch_str,
+ args.print_freq_eval,
+ logger,
+ )
+ valid_accuracies[epoch] = valid_acc1
+ logger.log(
+ "***{:s}*** VALID [{:}] loss = {:.6f}, accuracy@1 = {:.2f}, accuracy@5 = {:.2f} | Best-Valid-Acc@1={:.2f}, Error@1={:.2f}".format(
+ time_string(),
+ epoch_str,
+ valid_loss,
+ valid_acc1,
+ valid_acc5,
+ valid_accuracies["best"],
+ 100 - valid_accuracies["best"],
+ )
+ )
+ if valid_acc1 > valid_accuracies["best"]:
+ valid_accuracies["best"] = valid_acc1
+ arch_genotypes["best"] = genotype
+ find_best = True
+ logger.log(
+ "Currently, the best validation accuracy found at {:03d}-epoch :: acc@1={:.2f}, acc@5={:.2f}, error@1={:.2f}, error@5={:.2f}, save into {:}.".format(
+ epoch,
+ valid_acc1,
+ valid_acc5,
+ 100 - valid_acc1,
+ 100 - valid_acc5,
+ model_best_path,
+ )
+ )
+ # log the GPU memory usage
+ # num_bytes = torch.cuda.max_memory_allocated( next(network.parameters()).device ) * 1.0
+ num_bytes = (
+ torch.cuda.max_memory_cached(next(network.parameters()).device) * 1.0
+ )
+ logger.log(
+ "[GPU-Memory-Usage on {:} is {:} bytes, {:.2f} KB, {:.2f} MB, {:.2f} GB.]".format(
+ next(network.parameters()).device,
+ int(num_bytes),
+ num_bytes / 1e3,
+ num_bytes / 1e6,
+ num_bytes / 1e9,
+ )
+ )
+ max_bytes[epoch] = num_bytes
+
+ # save checkpoint
+ save_path = save_checkpoint(
+ {
+ "epoch": epoch,
+ "args": deepcopy(args),
+ "max_bytes": deepcopy(max_bytes),
+ "valid_accuracies": deepcopy(valid_accuracies),
+ "model-config": model_config._asdict(),
+ "optim-config": optim_config._asdict(),
+ "search_model": search_model.state_dict(),
+ "scheduler": scheduler.state_dict(),
+ "base_optimizer": base_optimizer.state_dict(),
+ "arch_optimizer": arch_optimizer.state_dict(),
+ "arch_genotypes": arch_genotypes,
+ "discrepancies": discrepancies,
+ },
+ model_base_path,
+ logger,
+ )
+ if find_best:
+ copy_checkpoint(model_base_path, model_best_path, logger)
+ last_info = save_checkpoint(
+ {
+ "epoch": epoch,
+ "args": deepcopy(args),
+ "last_checkpoint": save_path,
+ },
+ logger.path("info"),
+ logger,
+ )
+
+ # measure elapsed time
+ epoch_time.update(time.time() - start_time)
+ start_time = time.time()
+
+ logger.log("")
+ logger.log("-" * 100)
+ last_config_path = logger.path("log") / "seed-{:}-last.config".format(
+ args.rand_seed
+ )
+ configure2str(arch_genotypes["last"], str(last_config_path))
+ logger.log(
+ "save the last config int {:} :\n{:}".format(
+ last_config_path, arch_genotypes["last"]
+ )
+ )
+
+ best_arch, valid_acc = arch_genotypes["best"], valid_accuracies["best"]
+ for key, config in arch_genotypes.items():
+ if key == "last":
+ continue
+ FLOP_ratio = config["estimated_FLOP"] / MAX_FLOP
+ if abs(FLOP_ratio - args.FLOP_ratio) <= args.FLOP_tolerant:
+ if valid_acc <= valid_accuracies[key]:
+ best_arch, valid_acc = config, valid_accuracies[key]
+ print(
+ "Best-Arch : {:}\nRatio={:}, Valid-ACC={:}".format(
+ best_arch, best_arch["estimated_FLOP"] / MAX_FLOP, valid_acc
+ )
+ )
+ best_config_path = logger.path("log") / "seed-{:}-best.config".format(
+ args.rand_seed
+ )
+ configure2str(best_arch, str(best_config_path))
+ logger.log(
+ "save the last config int {:} :\n{:}".format(best_config_path, best_arch)
+ )
+ logger.log("\n" + "-" * 200)
+ logger.log(
+ "Finish training/validation in {:} with Max-GPU-Memory of {:.2f} GB, and save final checkpoint into {:}".format(
+ convert_secs2time(epoch_time.sum, True),
+ max(v for k, v in max_bytes.items()) / 1e9,
+ logger.path("info"),
+ )
+ )
+ logger.close()
+
+
+if __name__ == "__main__":
+ args = obtain_args()
+ main(args)
diff --git a/AutoDL-Projects/exps/basic/KD-main.py b/AutoDL-Projects/exps/basic/KD-main.py
new file mode 100644
index 0000000..99a9b67
--- /dev/null
+++ b/AutoDL-Projects/exps/basic/KD-main.py
@@ -0,0 +1,289 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.01 #
+#####################################################
+import sys, time, torch, random, argparse
+from PIL import ImageFile
+
+ImageFile.LOAD_TRUNCATED_IMAGES = True
+from copy import deepcopy
+from pathlib import Path
+
+from xautodl.config_utils import load_config, obtain_cls_kd_args as obtain_args
+from xautodl.procedures import (
+ prepare_seed,
+ prepare_logger,
+ save_checkpoint,
+ copy_checkpoint,
+)
+from xautodl.procedures import get_optim_scheduler, get_procedures
+from xautodl.datasets import get_datasets
+from xautodl.models import obtain_model, load_net_from_checkpoint
+from xautodl.utils import get_model_infos
+from xautodl.log_utils import AverageMeter, time_string, convert_secs2time
+
+
+def main(args):
+ assert torch.cuda.is_available(), "CUDA is not available."
+ torch.backends.cudnn.enabled = True
+ torch.backends.cudnn.benchmark = True
+ # torch.backends.cudnn.deterministic = True
+ # torch.set_num_threads(args.workers)
+
+ prepare_seed(args.rand_seed)
+ logger = prepare_logger(args)
+
+ train_data, valid_data, xshape, class_num = get_datasets(
+ args.dataset, args.data_path, args.cutout_length
+ )
+ train_loader = torch.utils.data.DataLoader(
+ train_data,
+ batch_size=args.batch_size,
+ shuffle=True,
+ num_workers=args.workers,
+ pin_memory=True,
+ )
+ valid_loader = torch.utils.data.DataLoader(
+ valid_data,
+ batch_size=args.batch_size,
+ shuffle=False,
+ num_workers=args.workers,
+ pin_memory=True,
+ )
+ # get configures
+ model_config = load_config(args.model_config, {"class_num": class_num}, logger)
+ optim_config = load_config(
+ args.optim_config,
+ {
+ "class_num": class_num,
+ "KD_alpha": args.KD_alpha,
+ "KD_temperature": args.KD_temperature,
+ },
+ logger,
+ )
+
+ # load checkpoint
+ teacher_base = load_net_from_checkpoint(args.KD_checkpoint)
+ teacher = torch.nn.DataParallel(teacher_base).cuda()
+
+ base_model = obtain_model(model_config)
+ flop, param = get_model_infos(base_model, xshape)
+ logger.log("Student ====>>>>:\n{:}".format(base_model))
+ logger.log("Teacher ====>>>>:\n{:}".format(teacher_base))
+ logger.log("model information : {:}".format(base_model.get_message()))
+ logger.log("-" * 50)
+ logger.log(
+ "Params={:.2f} MB, FLOPs={:.2f} M ... = {:.2f} G".format(
+ param, flop, flop / 1e3
+ )
+ )
+ logger.log("-" * 50)
+ logger.log("train_data : {:}".format(train_data))
+ logger.log("valid_data : {:}".format(valid_data))
+ optimizer, scheduler, criterion = get_optim_scheduler(
+ base_model.parameters(), optim_config
+ )
+ logger.log("optimizer : {:}".format(optimizer))
+ logger.log("scheduler : {:}".format(scheduler))
+ logger.log("criterion : {:}".format(criterion))
+
+ last_info, model_base_path, model_best_path = (
+ logger.path("info"),
+ logger.path("model"),
+ logger.path("best"),
+ )
+ network, criterion = torch.nn.DataParallel(base_model).cuda(), criterion.cuda()
+
+ if last_info.exists(): # automatically resume from previous checkpoint
+ logger.log(
+ "=> loading checkpoint of the last-info '{:}' start".format(last_info)
+ )
+ last_info = torch.load(last_info)
+ start_epoch = last_info["epoch"] + 1
+ checkpoint = torch.load(last_info["last_checkpoint"])
+ base_model.load_state_dict(checkpoint["base-model"])
+ scheduler.load_state_dict(checkpoint["scheduler"])
+ optimizer.load_state_dict(checkpoint["optimizer"])
+ valid_accuracies = checkpoint["valid_accuracies"]
+ max_bytes = checkpoint["max_bytes"]
+ logger.log(
+ "=> loading checkpoint of the last-info '{:}' start with {:}-th epoch.".format(
+ last_info, start_epoch
+ )
+ )
+ elif args.resume is not None:
+ assert Path(args.resume).exists(), "Can not find the resume file : {:}".format(
+ args.resume
+ )
+ checkpoint = torch.load(args.resume)
+ start_epoch = checkpoint["epoch"] + 1
+ base_model.load_state_dict(checkpoint["base-model"])
+ scheduler.load_state_dict(checkpoint["scheduler"])
+ optimizer.load_state_dict(checkpoint["optimizer"])
+ valid_accuracies = checkpoint["valid_accuracies"]
+ max_bytes = checkpoint["max_bytes"]
+ logger.log(
+ "=> loading checkpoint from '{:}' start with {:}-th epoch.".format(
+ args.resume, start_epoch
+ )
+ )
+ elif args.init_model is not None:
+ assert Path(
+ args.init_model
+ ).exists(), "Can not find the initialization file : {:}".format(args.init_model)
+ checkpoint = torch.load(args.init_model)
+ base_model.load_state_dict(checkpoint["base-model"])
+ start_epoch, valid_accuracies, max_bytes = 0, {"best": -1}, {}
+ logger.log("=> initialize the model from {:}".format(args.init_model))
+ else:
+ logger.log("=> do not find the last-info file : {:}".format(last_info))
+ start_epoch, valid_accuracies, max_bytes = 0, {"best": -1}, {}
+
+ train_func, valid_func = get_procedures(args.procedure)
+
+ total_epoch = optim_config.epochs + optim_config.warmup
+ # Main Training and Evaluation Loop
+ start_time = time.time()
+ epoch_time = AverageMeter()
+ for epoch in range(start_epoch, total_epoch):
+ scheduler.update(epoch, 0.0)
+ need_time = "Time Left: {:}".format(
+ convert_secs2time(epoch_time.avg * (total_epoch - epoch), True)
+ )
+ epoch_str = "epoch={:03d}/{:03d}".format(epoch, total_epoch)
+ LRs = scheduler.get_lr()
+ find_best = False
+
+ logger.log(
+ "\n***{:s}*** start {:s} {:s}, LR=[{:.6f} ~ {:.6f}], scheduler={:}".format(
+ time_string(), epoch_str, need_time, min(LRs), max(LRs), scheduler
+ )
+ )
+
+ # train for one epoch
+ train_loss, train_acc1, train_acc5 = train_func(
+ train_loader,
+ teacher,
+ network,
+ criterion,
+ scheduler,
+ optimizer,
+ optim_config,
+ epoch_str,
+ args.print_freq,
+ logger,
+ )
+ # log the results
+ logger.log(
+ "***{:s}*** TRAIN [{:}] loss = {:.6f}, accuracy-1 = {:.2f}, accuracy-5 = {:.2f}".format(
+ time_string(), epoch_str, train_loss, train_acc1, train_acc5
+ )
+ )
+
+ # evaluate the performance
+ if (epoch % args.eval_frequency == 0) or (epoch + 1 == total_epoch):
+ logger.log("-" * 150)
+ valid_loss, valid_acc1, valid_acc5 = valid_func(
+ valid_loader,
+ teacher,
+ network,
+ criterion,
+ optim_config,
+ epoch_str,
+ args.print_freq_eval,
+ logger,
+ )
+ valid_accuracies[epoch] = valid_acc1
+ logger.log(
+ "***{:s}*** VALID [{:}] loss = {:.6f}, accuracy@1 = {:.2f}, accuracy@5 = {:.2f} | Best-Valid-Acc@1={:.2f}, Error@1={:.2f}".format(
+ time_string(),
+ epoch_str,
+ valid_loss,
+ valid_acc1,
+ valid_acc5,
+ valid_accuracies["best"],
+ 100 - valid_accuracies["best"],
+ )
+ )
+ if valid_acc1 > valid_accuracies["best"]:
+ valid_accuracies["best"] = valid_acc1
+ find_best = True
+ logger.log(
+ "Currently, the best validation accuracy found at {:03d}-epoch :: acc@1={:.2f}, acc@5={:.2f}, error@1={:.2f}, error@5={:.2f}, save into {:}.".format(
+ epoch,
+ valid_acc1,
+ valid_acc5,
+ 100 - valid_acc1,
+ 100 - valid_acc5,
+ model_best_path,
+ )
+ )
+ num_bytes = (
+ torch.cuda.max_memory_cached(next(network.parameters()).device) * 1.0
+ )
+ logger.log(
+ "[GPU-Memory-Usage on {:} is {:} bytes, {:.2f} KB, {:.2f} MB, {:.2f} GB.]".format(
+ next(network.parameters()).device,
+ int(num_bytes),
+ num_bytes / 1e3,
+ num_bytes / 1e6,
+ num_bytes / 1e9,
+ )
+ )
+ max_bytes[epoch] = num_bytes
+ if epoch % 10 == 0:
+ torch.cuda.empty_cache()
+
+ # save checkpoint
+ save_path = save_checkpoint(
+ {
+ "epoch": epoch,
+ "args": deepcopy(args),
+ "max_bytes": deepcopy(max_bytes),
+ "FLOP": flop,
+ "PARAM": param,
+ "valid_accuracies": deepcopy(valid_accuracies),
+ "model-config": model_config._asdict(),
+ "optim-config": optim_config._asdict(),
+ "base-model": base_model.state_dict(),
+ "scheduler": scheduler.state_dict(),
+ "optimizer": optimizer.state_dict(),
+ },
+ model_base_path,
+ logger,
+ )
+ if find_best:
+ copy_checkpoint(model_base_path, model_best_path, logger)
+ last_info = save_checkpoint(
+ {
+ "epoch": epoch,
+ "args": deepcopy(args),
+ "last_checkpoint": save_path,
+ },
+ logger.path("info"),
+ logger,
+ )
+
+ # measure elapsed time
+ epoch_time.update(time.time() - start_time)
+ start_time = time.time()
+
+ logger.log("\n" + "-" * 200)
+ logger.log(
+ "||| Params={:.2f} MB, FLOPs={:.2f} M ... = {:.2f} G".format(
+ param, flop, flop / 1e3
+ )
+ )
+ logger.log(
+ "Finish training/validation in {:} with Max-GPU-Memory of {:.2f} MB, and save final checkpoint into {:}".format(
+ convert_secs2time(epoch_time.sum, True),
+ max(v for k, v in max_bytes.items()) / 1e6,
+ logger.path("info"),
+ )
+ )
+ logger.log("-" * 200 + "\n")
+ logger.close()
+
+
+if __name__ == "__main__":
+ args = obtain_args()
+ main(args)
diff --git a/AutoDL-Projects/exps/basic/basic-eval.py b/AutoDL-Projects/exps/basic/basic-eval.py
new file mode 100644
index 0000000..a9d173d
--- /dev/null
+++ b/AutoDL-Projects/exps/basic/basic-eval.py
@@ -0,0 +1,115 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.01 #
+#####################################################
+import os, sys, time, torch, random, argparse
+from PIL import ImageFile
+
+ImageFile.LOAD_TRUNCATED_IMAGES = True
+from copy import deepcopy
+
+from xautodl.config_utils import load_config, dict2config
+from xautodl.procedures import get_procedures, get_optim_scheduler
+from xautodl.datasets import get_datasets
+from xautodl.models import obtain_model
+from xautodl.utils import get_model_infos
+from xautodl.log_utils import PrintLogger, time_string
+
+
+def main(args):
+
+ assert os.path.isdir(args.data_path), "invalid data-path : {:}".format(
+ args.data_path
+ )
+ assert os.path.isfile(args.checkpoint), "invalid checkpoint : {:}".format(
+ args.checkpoint
+ )
+
+ checkpoint = torch.load(args.checkpoint)
+ xargs = checkpoint["args"]
+ train_data, valid_data, xshape, class_num = get_datasets(
+ xargs.dataset, args.data_path, xargs.cutout_length
+ )
+ valid_loader = torch.utils.data.DataLoader(
+ valid_data,
+ batch_size=xargs.batch_size,
+ shuffle=False,
+ num_workers=xargs.workers,
+ pin_memory=True,
+ )
+
+ logger = PrintLogger()
+ model_config = dict2config(checkpoint["model-config"], logger)
+ base_model = obtain_model(model_config)
+ flop, param = get_model_infos(base_model, xshape)
+ logger.log("model ====>>>>:\n{:}".format(base_model))
+ logger.log("model information : {:}".format(base_model.get_message()))
+ logger.log("-" * 50)
+ logger.log(
+ "Params={:.2f} MB, FLOPs={:.2f} M ... = {:.2f} G".format(
+ param, flop, flop / 1e3
+ )
+ )
+ logger.log("-" * 50)
+ logger.log("valid_data : {:}".format(valid_data))
+ optim_config = dict2config(checkpoint["optim-config"], logger)
+ _, _, criterion = get_optim_scheduler(base_model.parameters(), optim_config)
+ logger.log("criterion : {:}".format(criterion))
+ base_model.load_state_dict(checkpoint["base-model"])
+ _, valid_func = get_procedures(xargs.procedure)
+ logger.log("initialize the CNN done, evaluate it using {:}".format(valid_func))
+ network = torch.nn.DataParallel(base_model).cuda()
+
+ try:
+ valid_loss, valid_acc1, valid_acc5 = valid_func(
+ valid_loader,
+ network,
+ criterion,
+ optim_config,
+ "pure-evaluation",
+ xargs.print_freq_eval,
+ logger,
+ )
+ except:
+ _, valid_func = get_procedures("basic")
+ valid_loss, valid_acc1, valid_acc5 = valid_func(
+ valid_loader,
+ network,
+ criterion,
+ optim_config,
+ "pure-evaluation",
+ xargs.print_freq_eval,
+ logger,
+ )
+
+ num_bytes = torch.cuda.max_memory_cached(next(network.parameters()).device) * 1.0
+ logger.log(
+ "***{:s}*** EVALUATION loss = {:.6f}, accuracy@1 = {:.2f}, accuracy@5 = {:.2f}, error@1 = {:.2f}, error@5 = {:.2f}".format(
+ time_string(),
+ valid_loss,
+ valid_acc1,
+ valid_acc5,
+ 100 - valid_acc1,
+ 100 - valid_acc5,
+ )
+ )
+ logger.log(
+ "[GPU-Memory-Usage on {:} is {:} bytes, {:.2f} KB, {:.2f} MB, {:.2f} GB.]".format(
+ next(network.parameters()).device,
+ int(num_bytes),
+ num_bytes / 1e3,
+ num_bytes / 1e6,
+ num_bytes / 1e9,
+ )
+ )
+ logger.close()
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser("Evaluate-CNN")
+ parser.add_argument("--data_path", type=str, help="Path to dataset.")
+ parser.add_argument(
+ "--checkpoint", type=str, help="Choose between Cifar10/100 and ImageNet."
+ )
+ args = parser.parse_args()
+ assert torch.cuda.is_available(), "torch.cuda is not available"
+ main(args)
diff --git a/AutoDL-Projects/exps/basic/basic-main.py b/AutoDL-Projects/exps/basic/basic-main.py
new file mode 100644
index 0000000..1fa72e2
--- /dev/null
+++ b/AutoDL-Projects/exps/basic/basic-main.py
@@ -0,0 +1,291 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.01 #
+#####################################################
+import sys, time, torch, random, argparse
+from PIL import ImageFile
+
+ImageFile.LOAD_TRUNCATED_IMAGES = True
+from copy import deepcopy
+from pathlib import Path
+
+from xautodl.datasets import get_datasets
+from xautodl.config_utils import load_config, obtain_basic_args as obtain_args
+from xautodl.procedures import (
+ prepare_seed,
+ prepare_logger,
+ save_checkpoint,
+ copy_checkpoint,
+)
+from xautodl.procedures import get_optim_scheduler, get_procedures
+from xautodl.models import obtain_model
+from xautodl.nas_infer_model import obtain_nas_infer_model
+from xautodl.utils import get_model_infos
+from xautodl.log_utils import AverageMeter, time_string, convert_secs2time
+
+
+def main(args):
+ assert torch.cuda.is_available(), "CUDA is not available."
+ torch.backends.cudnn.enabled = True
+ torch.backends.cudnn.benchmark = True
+ # torch.backends.cudnn.deterministic = True
+ # torch.set_num_threads(args.workers)
+
+ prepare_seed(args.rand_seed)
+ logger = prepare_logger(args)
+
+ train_data, valid_data, xshape, class_num = get_datasets(
+ args.dataset, args.data_path, args.cutout_length
+ )
+ train_loader = torch.utils.data.DataLoader(
+ train_data,
+ batch_size=args.batch_size,
+ shuffle=True,
+ num_workers=args.workers,
+ pin_memory=True,
+ )
+ valid_loader = torch.utils.data.DataLoader(
+ valid_data,
+ batch_size=args.batch_size,
+ shuffle=False,
+ num_workers=args.workers,
+ pin_memory=True,
+ )
+ # get configures
+ model_config = load_config(args.model_config, {"class_num": class_num}, logger)
+ optim_config = load_config(args.optim_config, {"class_num": class_num}, logger)
+
+ if args.model_source == "normal":
+ base_model = obtain_model(model_config)
+ elif args.model_source == "nas":
+ base_model = obtain_nas_infer_model(model_config, args.extra_model_path)
+ elif args.model_source == "autodl-searched":
+ base_model = obtain_model(model_config, args.extra_model_path)
+ else:
+ raise ValueError("invalid model-source : {:}".format(args.model_source))
+ flop, param = get_model_infos(base_model, xshape)
+ logger.log("model ====>>>>:\n{:}".format(base_model))
+ logger.log("model information : {:}".format(base_model.get_message()))
+ logger.log("-" * 50)
+ logger.log(
+ "Params={:.2f} MB, FLOPs={:.2f} M ... = {:.2f} G".format(
+ param, flop, flop / 1e3
+ )
+ )
+ logger.log("-" * 50)
+ logger.log("train_data : {:}".format(train_data))
+ logger.log("valid_data : {:}".format(valid_data))
+ optimizer, scheduler, criterion = get_optim_scheduler(
+ base_model.parameters(), optim_config
+ )
+ logger.log("optimizer : {:}".format(optimizer))
+ logger.log("scheduler : {:}".format(scheduler))
+ logger.log("criterion : {:}".format(criterion))
+
+ last_info, model_base_path, model_best_path = (
+ logger.path("info"),
+ logger.path("model"),
+ logger.path("best"),
+ )
+ network, criterion = torch.nn.DataParallel(base_model).cuda(), criterion.cuda()
+
+ if last_info.exists(): # automatically resume from previous checkpoint
+ logger.log(
+ "=> loading checkpoint of the last-info '{:}' start".format(last_info)
+ )
+ last_infox = torch.load(last_info)
+ start_epoch = last_infox["epoch"] + 1
+ last_checkpoint_path = last_infox["last_checkpoint"]
+ if not last_checkpoint_path.exists():
+ logger.log(
+ "Does not find {:}, try another path".format(last_checkpoint_path)
+ )
+ last_checkpoint_path = (
+ last_info.parent
+ / last_checkpoint_path.parent.name
+ / last_checkpoint_path.name
+ )
+ checkpoint = torch.load(last_checkpoint_path)
+ base_model.load_state_dict(checkpoint["base-model"])
+ scheduler.load_state_dict(checkpoint["scheduler"])
+ optimizer.load_state_dict(checkpoint["optimizer"])
+ valid_accuracies = checkpoint["valid_accuracies"]
+ max_bytes = checkpoint["max_bytes"]
+ logger.log(
+ "=> loading checkpoint of the last-info '{:}' start with {:}-th epoch.".format(
+ last_info, start_epoch
+ )
+ )
+ elif args.resume is not None:
+ assert Path(args.resume).exists(), "Can not find the resume file : {:}".format(
+ args.resume
+ )
+ checkpoint = torch.load(args.resume)
+ start_epoch = checkpoint["epoch"] + 1
+ base_model.load_state_dict(checkpoint["base-model"])
+ scheduler.load_state_dict(checkpoint["scheduler"])
+ optimizer.load_state_dict(checkpoint["optimizer"])
+ valid_accuracies = checkpoint["valid_accuracies"]
+ max_bytes = checkpoint["max_bytes"]
+ logger.log(
+ "=> loading checkpoint from '{:}' start with {:}-th epoch.".format(
+ args.resume, start_epoch
+ )
+ )
+ elif args.init_model is not None:
+ assert Path(
+ args.init_model
+ ).exists(), "Can not find the initialization file : {:}".format(args.init_model)
+ checkpoint = torch.load(args.init_model)
+ base_model.load_state_dict(checkpoint["base-model"])
+ start_epoch, valid_accuracies, max_bytes = 0, {"best": -1}, {}
+ logger.log("=> initialize the model from {:}".format(args.init_model))
+ else:
+ logger.log("=> do not find the last-info file : {:}".format(last_info))
+ start_epoch, valid_accuracies, max_bytes = 0, {"best": -1}, {}
+
+ train_func, valid_func = get_procedures(args.procedure)
+
+ total_epoch = optim_config.epochs + optim_config.warmup
+ # Main Training and Evaluation Loop
+ start_time = time.time()
+ epoch_time = AverageMeter()
+ for epoch in range(start_epoch, total_epoch):
+ scheduler.update(epoch, 0.0)
+ need_time = "Time Left: {:}".format(
+ convert_secs2time(epoch_time.avg * (total_epoch - epoch), True)
+ )
+ epoch_str = "epoch={:03d}/{:03d}".format(epoch, total_epoch)
+ LRs = scheduler.get_lr()
+ find_best = False
+ # set-up drop-out ratio
+ if hasattr(base_model, "update_drop_path"):
+ base_model.update_drop_path(
+ model_config.drop_path_prob * epoch / total_epoch
+ )
+ logger.log(
+ "\n***{:s}*** start {:s} {:s}, LR=[{:.6f} ~ {:.6f}], scheduler={:}".format(
+ time_string(), epoch_str, need_time, min(LRs), max(LRs), scheduler
+ )
+ )
+
+ # train for one epoch
+ train_loss, train_acc1, train_acc5 = train_func(
+ train_loader,
+ network,
+ criterion,
+ scheduler,
+ optimizer,
+ optim_config,
+ epoch_str,
+ args.print_freq,
+ logger,
+ )
+ # log the results
+ logger.log(
+ "***{:s}*** TRAIN [{:}] loss = {:.6f}, accuracy-1 = {:.2f}, accuracy-5 = {:.2f}".format(
+ time_string(), epoch_str, train_loss, train_acc1, train_acc5
+ )
+ )
+
+ # evaluate the performance
+ if (epoch % args.eval_frequency == 0) or (epoch + 1 == total_epoch):
+ logger.log("-" * 150)
+ valid_loss, valid_acc1, valid_acc5 = valid_func(
+ valid_loader,
+ network,
+ criterion,
+ optim_config,
+ epoch_str,
+ args.print_freq_eval,
+ logger,
+ )
+ valid_accuracies[epoch] = valid_acc1
+ logger.log(
+ "***{:s}*** VALID [{:}] loss = {:.6f}, accuracy@1 = {:.2f}, accuracy@5 = {:.2f} | Best-Valid-Acc@1={:.2f}, Error@1={:.2f}".format(
+ time_string(),
+ epoch_str,
+ valid_loss,
+ valid_acc1,
+ valid_acc5,
+ valid_accuracies["best"],
+ 100 - valid_accuracies["best"],
+ )
+ )
+ if valid_acc1 > valid_accuracies["best"]:
+ valid_accuracies["best"] = valid_acc1
+ find_best = True
+ logger.log(
+ "Currently, the best validation accuracy found at {:03d}-epoch :: acc@1={:.2f}, acc@5={:.2f}, error@1={:.2f}, error@5={:.2f}, save into {:}.".format(
+ epoch,
+ valid_acc1,
+ valid_acc5,
+ 100 - valid_acc1,
+ 100 - valid_acc5,
+ model_best_path,
+ )
+ )
+ num_bytes = (
+ torch.cuda.max_memory_cached(next(network.parameters()).device) * 1.0
+ )
+ logger.log(
+ "[GPU-Memory-Usage on {:} is {:} bytes, {:.2f} KB, {:.2f} MB, {:.2f} GB.]".format(
+ next(network.parameters()).device,
+ int(num_bytes),
+ num_bytes / 1e3,
+ num_bytes / 1e6,
+ num_bytes / 1e9,
+ )
+ )
+ max_bytes[epoch] = num_bytes
+ if epoch % 10 == 0:
+ torch.cuda.empty_cache()
+
+ # save checkpoint
+ save_path = save_checkpoint(
+ {
+ "epoch": epoch,
+ "args": deepcopy(args),
+ "max_bytes": deepcopy(max_bytes),
+ "FLOP": flop,
+ "PARAM": param,
+ "valid_accuracies": deepcopy(valid_accuracies),
+ "model-config": model_config._asdict(),
+ "optim-config": optim_config._asdict(),
+ "base-model": base_model.state_dict(),
+ "scheduler": scheduler.state_dict(),
+ "optimizer": optimizer.state_dict(),
+ },
+ model_base_path,
+ logger,
+ )
+ if find_best:
+ copy_checkpoint(model_base_path, model_best_path, logger)
+ last_info = save_checkpoint(
+ {
+ "epoch": epoch,
+ "args": deepcopy(args),
+ "last_checkpoint": save_path,
+ },
+ logger.path("info"),
+ logger,
+ )
+
+ # measure elapsed time
+ epoch_time.update(time.time() - start_time)
+ start_time = time.time()
+
+ logger.log("\n" + "-" * 200)
+ logger.log(
+ "Finish training/validation in {:} with Max-GPU-Memory of {:.2f} MB, and save final checkpoint into {:}".format(
+ convert_secs2time(epoch_time.sum, True),
+ max(v for k, v in max_bytes.items()) / 1e6,
+ logger.path("info"),
+ )
+ )
+ logger.log("-" * 200 + "\n")
+ logger.close()
+
+
+if __name__ == "__main__":
+ args = obtain_args()
+ main(args)
diff --git a/AutoDL-Projects/exps/basic/xmain.py b/AutoDL-Projects/exps/basic/xmain.py
new file mode 100644
index 0000000..faffdc1
--- /dev/null
+++ b/AutoDL-Projects/exps/basic/xmain.py
@@ -0,0 +1,157 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.06 #
+#####################################################
+# python exps/basic/xmain.py --save_dir outputs/x #
+#####################################################
+import os, sys, time, torch, random, argparse
+from copy import deepcopy
+from pathlib import Path
+
+lib_dir = (Path(__file__).parent / ".." / "..").resolve()
+print("LIB-DIR: {:}".format(lib_dir))
+if str(lib_dir) not in sys.path:
+ sys.path.insert(0, str(lib_dir))
+
+from xautodl import xmisc
+
+
+def main(args):
+
+ train_data = xmisc.nested_call_by_yaml(args.train_data_config, args.data_path)
+ valid_data = xmisc.nested_call_by_yaml(args.valid_data_config, args.data_path)
+ logger = xmisc.Logger(args.save_dir, prefix="seed-{:}-".format(args.rand_seed))
+
+ logger.log("Create the logger: {:}".format(logger))
+ logger.log("Arguments : -------------------------------")
+ for name, value in args._get_kwargs():
+ logger.log("{:16} : {:}".format(name, value))
+ logger.log("Python Version : {:}".format(sys.version.replace("\n", " ")))
+ logger.log("PyTorch Version : {:}".format(torch.__version__))
+ logger.log("cuDNN Version : {:}".format(torch.backends.cudnn.version()))
+ logger.log("CUDA available : {:}".format(torch.cuda.is_available()))
+ logger.log("CUDA GPU numbers : {:}".format(torch.cuda.device_count()))
+ logger.log(
+ "CUDA_VISIBLE_DEVICES : {:}".format(
+ os.environ["CUDA_VISIBLE_DEVICES"]
+ if "CUDA_VISIBLE_DEVICES" in os.environ
+ else "None"
+ )
+ )
+ logger.log("The training data is:\n{:}".format(train_data))
+ logger.log("The validation data is:\n{:}".format(valid_data))
+
+ model = xmisc.nested_call_by_yaml(args.model_config)
+ logger.log("The model is:\n{:}".format(model))
+ logger.log("The model size is {:.4f} M".format(xmisc.count_parameters(model)))
+
+ train_loader = torch.utils.data.DataLoader(
+ train_data,
+ batch_sampler=xmisc.BatchSampler(train_data, args.batch_size, args.steps),
+ num_workers=args.workers,
+ pin_memory=True,
+ )
+ valid_loader = torch.utils.data.DataLoader(
+ valid_data,
+ batch_size=args.batch_size,
+ shuffle=False,
+ num_workers=args.workers,
+ pin_memory=True,
+ drop_last=False,
+ )
+ iters_per_epoch = len(train_data) // args.batch_size
+
+ logger.log("The training loader: {:}".format(train_loader))
+ logger.log("The validation loader: {:}".format(valid_loader))
+ optimizer = xmisc.nested_call_by_yaml(
+ args.optim_config,
+ model.parameters(),
+ lr=args.lr,
+ weight_decay=args.weight_decay,
+ )
+ objective = xmisc.nested_call_by_yaml(args.loss_config)
+ metric = xmisc.nested_call_by_yaml(args.metric_config)
+
+ logger.log("The optimizer is:\n{:}".format(optimizer))
+ logger.log("The objective is {:}".format(objective))
+ logger.log("The metric is {:}".format(metric))
+ logger.log(
+ "The iters_per_epoch = {:}, estimated epochs = {:}".format(
+ iters_per_epoch, args.steps // iters_per_epoch
+ )
+ )
+
+ model, objective = torch.nn.DataParallel(model).cuda(), objective.cuda()
+ scheduler = xmisc.LRMultiplier(
+ optimizer, xmisc.get_scheduler(args.scheduler, args.lr), args.steps
+ )
+
+ start_time, iter_time = time.time(), xmisc.AverageMeter()
+ for xiter, data in enumerate(train_loader):
+ need_time = "Time Left: {:}".format(
+ xmisc.time_utils.convert_secs2time(
+ iter_time.avg * (len(train_loader) - xiter), True
+ )
+ )
+ iter_str = "{:6d}/{:06d}".format(xiter, len(train_loader))
+
+ inputs, targets = data
+ targets = targets.cuda(non_blocking=True)
+ model.train()
+
+ optimizer.zero_grad()
+ outputs = model(inputs)
+ loss = objective(outputs, targets)
+
+ loss.backward()
+ optimizer.step()
+ scheduler.step()
+
+ if xiter % iters_per_epoch == 0:
+ logger.log("TRAIN [{:}] loss = {:.6f}".format(iter_str, loss.item()))
+
+ # measure elapsed time
+ iter_time.update(time.time() - start_time)
+ start_time = time.time()
+
+ logger.log("-" * 200 + "\n")
+ logger.close()
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(
+ description="Train a classification model with a loss function.",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ )
+ parser.add_argument(
+ "--save_dir", type=str, help="Folder to save checkpoints and log."
+ )
+ parser.add_argument("--resume", type=str, help="Resume path.")
+ parser.add_argument("--init_model", type=str, help="The initialization model path.")
+ parser.add_argument("--model_config", type=str, help="The path to the model config")
+ parser.add_argument("--optim_config", type=str, help="The optimizer config file.")
+ parser.add_argument("--loss_config", type=str, help="The loss config file.")
+ parser.add_argument("--metric_config", type=str, help="The metric config file.")
+ parser.add_argument(
+ "--train_data_config", type=str, help="The training dataset config path."
+ )
+ parser.add_argument(
+ "--valid_data_config", type=str, help="The validation dataset config path."
+ )
+ parser.add_argument("--data_path", type=str, help="The path to the dataset.")
+ # Optimization options
+ parser.add_argument("--lr", type=float, help="The learning rate")
+ parser.add_argument("--weight_decay", type=float, help="The weight decay")
+ parser.add_argument("--scheduler", type=str, help="The scheduler indicator.")
+ parser.add_argument("--steps", type=int, help="The total number of steps.")
+ parser.add_argument("--batch_size", type=int, default=256, help="The batch size.")
+ parser.add_argument("--workers", type=int, default=4, help="The number of workers")
+ # Random Seed
+ parser.add_argument("--rand_seed", type=int, default=-1, help="manual seed")
+
+ args = parser.parse_args()
+ if args.rand_seed is None or args.rand_seed < 0:
+ args.rand_seed = random.randint(1, 100000)
+ if args.save_dir is None:
+ raise ValueError("The save-path argument can not be None")
+
+ main(args)
diff --git a/AutoDL-Projects/exps/experimental/GeMOSA/baselines/maml-ft.py b/AutoDL-Projects/exps/experimental/GeMOSA/baselines/maml-ft.py
new file mode 100644
index 0000000..4dadb20
--- /dev/null
+++ b/AutoDL-Projects/exps/experimental/GeMOSA/baselines/maml-ft.py
@@ -0,0 +1,319 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.04 #
+#####################################################
+# python exps/GeMOSA/baselines/maml-ft.py --env_version v1 --hidden_dim 16 --inner_step 5 --device cuda
+# python exps/GeMOSA/baselines/maml-ft.py --env_version v2 --hidden_dim 16 --inner_step 5 --device cuda
+# python exps/GeMOSA/baselines/maml-ft.py --env_version v3 --hidden_dim 32 --inner_step 5 --device cuda
+# python exps/GeMOSA/baselines/maml-ft.py --env_version v4 --hidden_dim 32 --inner_step 5 --device cuda
+#####################################################
+import sys, time, copy, torch, random, argparse
+from tqdm import tqdm
+from copy import deepcopy
+from pathlib import Path
+
+lib_dir = (Path(__file__).parent / ".." / ".." / "..").resolve()
+print(lib_dir)
+if str(lib_dir) not in sys.path:
+ sys.path.insert(0, str(lib_dir))
+from xautodl.procedures import (
+ prepare_seed,
+ prepare_logger,
+ save_checkpoint,
+ copy_checkpoint,
+)
+from xautodl.log_utils import time_string
+from xautodl.log_utils import AverageMeter, convert_secs2time
+
+from xautodl.procedures.metric_utils import SaveMetric, MSEMetric, Top1AccMetric
+from xautodl.datasets.synthetic_core import get_synthetic_env
+from xautodl.models.xcore import get_model
+from xautodl.xlayers import super_core
+
+
+class MAML:
+ """A LFNA meta-model that uses the MLP as delta-net."""
+
+ def __init__(
+ self, network, criterion, epochs, meta_lr, inner_lr=0.01, inner_step=1
+ ):
+ self.criterion = criterion
+ self.network = network
+ self.meta_optimizer = torch.optim.Adam(
+ self.network.parameters(), lr=meta_lr, amsgrad=True
+ )
+ self.inner_lr = inner_lr
+ self.inner_step = inner_step
+ self._best_info = dict(state_dict=None, iepoch=None, score=None)
+ print("There are {:} weights.".format(self.network.get_w_container().numel()))
+
+ def adapt(self, x, y):
+ # create a container for the future timestamp
+ container = self.network.get_w_container()
+
+ for k in range(0, self.inner_step):
+ y_hat = self.network.forward_with_container(x, container)
+ loss = self.criterion(y_hat, y)
+ grads = torch.autograd.grad(loss, container.parameters())
+ container = container.additive([-self.inner_lr * grad for grad in grads])
+ return container
+
+ def predict(self, x, container=None):
+ if container is not None:
+ y_hat = self.network.forward_with_container(x, container)
+ else:
+ y_hat = self.network(x)
+ return y_hat
+
+ def step(self):
+ torch.nn.utils.clip_grad_norm_(self.network.parameters(), 1.0)
+ self.meta_optimizer.step()
+
+ def zero_grad(self):
+ self.meta_optimizer.zero_grad()
+
+ def load_state_dict(self, state_dict):
+ self.criterion.load_state_dict(state_dict["criterion"])
+ self.network.load_state_dict(state_dict["network"])
+ self.meta_optimizer.load_state_dict(state_dict["meta_optimizer"])
+
+ def state_dict(self):
+ state_dict = dict()
+ state_dict["criterion"] = self.criterion.state_dict()
+ state_dict["network"] = self.network.state_dict()
+ state_dict["meta_optimizer"] = self.meta_optimizer.state_dict()
+ return state_dict
+
+ def save_best(self, score):
+ success, best_score = self.network.save_best(score)
+ return success, best_score
+
+ def load_best(self):
+ self.network.load_best()
+
+
+def main(args):
+ prepare_seed(args.rand_seed)
+ logger = prepare_logger(args)
+ train_env = get_synthetic_env(mode="train", version=args.env_version)
+ valid_env = get_synthetic_env(mode="valid", version=args.env_version)
+ trainval_env = get_synthetic_env(mode="trainval", version=args.env_version)
+ test_env = get_synthetic_env(mode="test", version=args.env_version)
+ all_env = get_synthetic_env(mode=None, version=args.env_version)
+ logger.log("The training enviornment: {:}".format(train_env))
+ logger.log("The validation enviornment: {:}".format(valid_env))
+ logger.log("The trainval enviornment: {:}".format(trainval_env))
+ logger.log("The total enviornment: {:}".format(all_env))
+ logger.log("The test enviornment: {:}".format(test_env))
+ model_kwargs = dict(
+ config=dict(model_type="norm_mlp"),
+ input_dim=all_env.meta_info["input_dim"],
+ output_dim=all_env.meta_info["output_dim"],
+ hidden_dims=[args.hidden_dim] * 2,
+ act_cls="relu",
+ norm_cls="layer_norm_1d",
+ )
+
+ model = get_model(**model_kwargs)
+ model = model.to(args.device)
+ if all_env.meta_info["task"] == "regression":
+ criterion = torch.nn.MSELoss()
+ metric_cls = MSEMetric
+ elif all_env.meta_info["task"] == "classification":
+ criterion = torch.nn.CrossEntropyLoss()
+ metric_cls = Top1AccMetric
+ else:
+ raise ValueError(
+ "This task ({:}) is not supported.".format(all_env.meta_info["task"])
+ )
+
+ maml = MAML(
+ model, criterion, args.epochs, args.meta_lr, args.inner_lr, args.inner_step
+ )
+
+ # meta-training
+ last_success_epoch = 0
+ per_epoch_time, start_time = AverageMeter(), time.time()
+ for iepoch in range(args.epochs):
+ need_time = "Time Left: {:}".format(
+ convert_secs2time(per_epoch_time.avg * (args.epochs - iepoch), True)
+ )
+ head_str = (
+ "[{:}] [{:04d}/{:04d}] ".format(time_string(), iepoch, args.epochs)
+ + need_time
+ )
+
+ maml.zero_grad()
+ meta_losses = []
+ for ibatch in range(args.meta_batch):
+ future_idx = random.randint(0, len(trainval_env) - 1)
+ future_t, (future_x, future_y) = trainval_env[future_idx]
+ # -->>
+ seq_times = trainval_env.get_seq_times(future_idx, args.seq_length)
+ _, (allxs, allys) = trainval_env.seq_call(seq_times)
+ allxs, allys = allxs.view(-1, allxs.shape[-1]), allys.view(-1, 1)
+ if trainval_env.meta_info["task"] == "classification":
+ allys = allys.view(-1)
+ historical_x, historical_y = allxs.to(args.device), allys.to(args.device)
+ future_container = maml.adapt(historical_x, historical_y)
+
+ future_x, future_y = future_x.to(args.device), future_y.to(args.device)
+ future_y_hat = maml.predict(future_x, future_container)
+ future_loss = maml.criterion(future_y_hat, future_y)
+ meta_losses.append(future_loss)
+ meta_loss = torch.stack(meta_losses).mean()
+ meta_loss.backward()
+ maml.step()
+
+ logger.log(head_str + " meta-loss: {:.4f}".format(meta_loss.item()))
+ success, best_score = maml.save_best(-meta_loss.item())
+ if success:
+ logger.log("Achieve the best with best_score = {:.3f}".format(best_score))
+ save_checkpoint(maml.state_dict(), logger.path("model"), logger)
+ last_success_epoch = iepoch
+ if iepoch - last_success_epoch >= args.early_stop_thresh:
+ logger.log("Early stop at {:}".format(iepoch))
+ break
+
+ per_epoch_time.update(time.time() - start_time)
+ start_time = time.time()
+
+ # meta-test
+ maml.load_best()
+
+ def finetune(index):
+ seq_times = test_env.get_seq_times(index, args.seq_length)
+ _, (allxs, allys) = test_env.seq_call(seq_times)
+ allxs, allys = allxs.view(-1, allxs.shape[-1]), allys.view(-1, 1)
+ if test_env.meta_info["task"] == "classification":
+ allys = allys.view(-1)
+ historical_x, historical_y = allxs.to(args.device), allys.to(args.device)
+ future_container = maml.adapt(historical_x, historical_y)
+
+ historical_y_hat = maml.predict(historical_x, future_container)
+ train_metric = metric_cls(True)
+ # model.analyze_weights()
+ with torch.no_grad():
+ train_metric(historical_y_hat, historical_y)
+ train_results = train_metric.get_info()
+ return train_results, future_container
+
+ metric = metric_cls(True)
+ per_timestamp_time, start_time = AverageMeter(), time.time()
+ for idx, (future_time, (future_x, future_y)) in enumerate(test_env):
+
+ need_time = "Time Left: {:}".format(
+ convert_secs2time(per_timestamp_time.avg * (len(test_env) - idx), True)
+ )
+ logger.log(
+ "[{:}]".format(time_string())
+ + " [{:04d}/{:04d}]".format(idx, len(test_env))
+ + " "
+ + need_time
+ )
+
+ # build optimizer
+ train_results, future_container = finetune(idx)
+
+ future_x, future_y = future_x.to(args.device), future_y.to(args.device)
+ future_y_hat = maml.predict(future_x, future_container)
+ future_loss = criterion(future_y_hat, future_y)
+ metric(future_y_hat, future_y)
+ log_str = (
+ "[{:}]".format(time_string())
+ + " [{:04d}/{:04d}]".format(idx, len(test_env))
+ + " train-score: {:.5f}, eval-score: {:.5f}".format(
+ train_results["score"], metric.get_info()["score"]
+ )
+ )
+ logger.log(log_str)
+ logger.log("")
+ per_timestamp_time.update(time.time() - start_time)
+ start_time = time.time()
+
+ logger.log("-" * 200 + "\n")
+ logger.close()
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser("Use the maml.")
+ parser.add_argument(
+ "--save_dir",
+ type=str,
+ default="./outputs/GeMOSA-synthetic/use-maml-ft",
+ help="The checkpoint directory.",
+ )
+ parser.add_argument(
+ "--env_version",
+ type=str,
+ required=True,
+ help="The synthetic enviornment version.",
+ )
+ parser.add_argument(
+ "--hidden_dim",
+ type=int,
+ default=16,
+ help="The hidden dimension.",
+ )
+ parser.add_argument(
+ "--meta_lr",
+ type=float,
+ default=0.02,
+ help="The learning rate for the MAML optimizer (default is Adam)",
+ )
+ parser.add_argument(
+ "--inner_lr",
+ type=float,
+ default=0.005,
+ help="The learning rate for the inner optimization",
+ )
+ parser.add_argument(
+ "--inner_step", type=int, default=1, help="The inner loop steps for MAML."
+ )
+ parser.add_argument(
+ "--seq_length", type=int, default=20, help="The sequence length."
+ )
+ parser.add_argument(
+ "--meta_batch",
+ type=int,
+ default=256,
+ help="The batch size for the meta-model",
+ )
+ parser.add_argument(
+ "--epochs",
+ type=int,
+ default=2000,
+ help="The total number of epochs.",
+ )
+ parser.add_argument(
+ "--early_stop_thresh",
+ type=int,
+ default=50,
+ help="The maximum epochs for early stop.",
+ )
+ parser.add_argument(
+ "--device",
+ type=str,
+ default="cpu",
+ help="",
+ )
+ parser.add_argument(
+ "--workers",
+ type=int,
+ default=4,
+ help="The number of data loading workers (default: 4)",
+ )
+ # Random Seed
+ parser.add_argument("--rand_seed", type=int, default=-1, help="manual seed")
+ args = parser.parse_args()
+ if args.rand_seed is None or args.rand_seed < 0:
+ args.rand_seed = random.randint(1, 100000)
+ assert args.save_dir is not None, "The save dir argument can not be None"
+ args.save_dir = "{:}-s{:}-mlr{:}-d{:}-e{:}-env{:}".format(
+ args.save_dir,
+ args.inner_step,
+ args.meta_lr,
+ args.hidden_dim,
+ args.epochs,
+ args.env_version,
+ )
+ main(args)
diff --git a/AutoDL-Projects/exps/experimental/GeMOSA/baselines/maml-nof.py b/AutoDL-Projects/exps/experimental/GeMOSA/baselines/maml-nof.py
new file mode 100644
index 0000000..88ed819
--- /dev/null
+++ b/AutoDL-Projects/exps/experimental/GeMOSA/baselines/maml-nof.py
@@ -0,0 +1,319 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.04 #
+#####################################################
+# python exps/GeMOSA/baselines/maml-nof.py --env_version v1 --hidden_dim 16 --inner_step 5 --device cuda
+# python exps/GeMOSA/baselines/maml-nof.py --env_version v2 --hidden_dim 16 --inner_step 5 --device cuda
+# python exps/GeMOSA/baselines/maml-nof.py --env_version v3 --hidden_dim 32 --inner_step 5 --device cuda
+# python exps/GeMOSA/baselines/maml-nof.py --env_version v4 --hidden_dim 32 --inner_step 5 --device cuda
+#####################################################
+import sys, time, copy, torch, random, argparse
+from tqdm import tqdm
+from copy import deepcopy
+from pathlib import Path
+
+lib_dir = (Path(__file__).parent / ".." / ".." / "..").resolve()
+print(lib_dir)
+if str(lib_dir) not in sys.path:
+ sys.path.insert(0, str(lib_dir))
+from xautodl.procedures import (
+ prepare_seed,
+ prepare_logger,
+ save_checkpoint,
+ copy_checkpoint,
+)
+from xautodl.log_utils import time_string
+from xautodl.log_utils import AverageMeter, convert_secs2time
+
+from xautodl.procedures.metric_utils import SaveMetric, MSEMetric, Top1AccMetric
+from xautodl.datasets.synthetic_core import get_synthetic_env
+from xautodl.models.xcore import get_model
+from xautodl.xlayers import super_core
+
+
+class MAML:
+ """A LFNA meta-model that uses the MLP as delta-net."""
+
+ def __init__(
+ self, network, criterion, epochs, meta_lr, inner_lr=0.01, inner_step=1
+ ):
+ self.criterion = criterion
+ self.network = network
+ self.meta_optimizer = torch.optim.Adam(
+ self.network.parameters(), lr=meta_lr, amsgrad=True
+ )
+ self.inner_lr = inner_lr
+ self.inner_step = inner_step
+ self._best_info = dict(state_dict=None, iepoch=None, score=None)
+ print("There are {:} weights.".format(self.network.get_w_container().numel()))
+
+ def adapt(self, x, y):
+ # create a container for the future timestamp
+ container = self.network.get_w_container()
+
+ for k in range(0, self.inner_step):
+ y_hat = self.network.forward_with_container(x, container)
+ loss = self.criterion(y_hat, y)
+ grads = torch.autograd.grad(loss, container.parameters())
+ container = container.additive([-self.inner_lr * grad for grad in grads])
+ return container
+
+ def predict(self, x, container=None):
+ if container is not None:
+ y_hat = self.network.forward_with_container(x, container)
+ else:
+ y_hat = self.network(x)
+ return y_hat
+
+ def step(self):
+ torch.nn.utils.clip_grad_norm_(self.network.parameters(), 1.0)
+ self.meta_optimizer.step()
+
+ def zero_grad(self):
+ self.meta_optimizer.zero_grad()
+
+ def load_state_dict(self, state_dict):
+ self.criterion.load_state_dict(state_dict["criterion"])
+ self.network.load_state_dict(state_dict["network"])
+ self.meta_optimizer.load_state_dict(state_dict["meta_optimizer"])
+
+ def state_dict(self):
+ state_dict = dict()
+ state_dict["criterion"] = self.criterion.state_dict()
+ state_dict["network"] = self.network.state_dict()
+ state_dict["meta_optimizer"] = self.meta_optimizer.state_dict()
+ return state_dict
+
+ def save_best(self, score):
+ success, best_score = self.network.save_best(score)
+ return success, best_score
+
+ def load_best(self):
+ self.network.load_best()
+
+
+def main(args):
+ prepare_seed(args.rand_seed)
+ logger = prepare_logger(args)
+ train_env = get_synthetic_env(mode="train", version=args.env_version)
+ valid_env = get_synthetic_env(mode="valid", version=args.env_version)
+ trainval_env = get_synthetic_env(mode="trainval", version=args.env_version)
+ test_env = get_synthetic_env(mode="test", version=args.env_version)
+ all_env = get_synthetic_env(mode=None, version=args.env_version)
+ logger.log("The training enviornment: {:}".format(train_env))
+ logger.log("The validation enviornment: {:}".format(valid_env))
+ logger.log("The trainval enviornment: {:}".format(trainval_env))
+ logger.log("The total enviornment: {:}".format(all_env))
+ logger.log("The test enviornment: {:}".format(test_env))
+ model_kwargs = dict(
+ config=dict(model_type="norm_mlp"),
+ input_dim=all_env.meta_info["input_dim"],
+ output_dim=all_env.meta_info["output_dim"],
+ hidden_dims=[args.hidden_dim] * 2,
+ act_cls="relu",
+ norm_cls="layer_norm_1d",
+ )
+
+ model = get_model(**model_kwargs)
+ model = model.to(args.device)
+ if all_env.meta_info["task"] == "regression":
+ criterion = torch.nn.MSELoss()
+ metric_cls = MSEMetric
+ elif all_env.meta_info["task"] == "classification":
+ criterion = torch.nn.CrossEntropyLoss()
+ metric_cls = Top1AccMetric
+ else:
+ raise ValueError(
+ "This task ({:}) is not supported.".format(all_env.meta_info["task"])
+ )
+
+ maml = MAML(
+ model, criterion, args.epochs, args.meta_lr, args.inner_lr, args.inner_step
+ )
+
+ # meta-training
+ last_success_epoch = 0
+ per_epoch_time, start_time = AverageMeter(), time.time()
+ for iepoch in range(args.epochs):
+ need_time = "Time Left: {:}".format(
+ convert_secs2time(per_epoch_time.avg * (args.epochs - iepoch), True)
+ )
+ head_str = (
+ "[{:}] [{:04d}/{:04d}] ".format(time_string(), iepoch, args.epochs)
+ + need_time
+ )
+
+ maml.zero_grad()
+ meta_losses = []
+ for ibatch in range(args.meta_batch):
+ future_idx = random.randint(0, len(trainval_env) - 1)
+ future_t, (future_x, future_y) = trainval_env[future_idx]
+ # -->>
+ seq_times = trainval_env.get_seq_times(future_idx, args.seq_length)
+ _, (allxs, allys) = trainval_env.seq_call(seq_times)
+ allxs, allys = allxs.view(-1, allxs.shape[-1]), allys.view(-1, 1)
+ if trainval_env.meta_info["task"] == "classification":
+ allys = allys.view(-1)
+ historical_x, historical_y = allxs.to(args.device), allys.to(args.device)
+ future_container = maml.adapt(historical_x, historical_y)
+
+ future_x, future_y = future_x.to(args.device), future_y.to(args.device)
+ future_y_hat = maml.predict(future_x, future_container)
+ future_loss = maml.criterion(future_y_hat, future_y)
+ meta_losses.append(future_loss)
+ meta_loss = torch.stack(meta_losses).mean()
+ meta_loss.backward()
+ maml.step()
+
+ logger.log(head_str + " meta-loss: {:.4f}".format(meta_loss.item()))
+ success, best_score = maml.save_best(-meta_loss.item())
+ if success:
+ logger.log("Achieve the best with best_score = {:.3f}".format(best_score))
+ save_checkpoint(maml.state_dict(), logger.path("model"), logger)
+ last_success_epoch = iepoch
+ if iepoch - last_success_epoch >= args.early_stop_thresh:
+ logger.log("Early stop at {:}".format(iepoch))
+ break
+
+ per_epoch_time.update(time.time() - start_time)
+ start_time = time.time()
+
+ # meta-test
+ maml.load_best()
+
+ def finetune(index):
+ seq_times = test_env.get_seq_times(index, args.seq_length)
+ _, (allxs, allys) = test_env.seq_call(seq_times)
+ allxs, allys = allxs.view(-1, allxs.shape[-1]), allys.view(-1, 1)
+ if test_env.meta_info["task"] == "classification":
+ allys = allys.view(-1)
+ historical_x, historical_y = allxs.to(args.device), allys.to(args.device)
+ future_container = maml.adapt(historical_x, historical_y)
+
+ historical_y_hat = maml.predict(historical_x, future_container)
+ train_metric = metric_cls(True)
+ # model.analyze_weights()
+ with torch.no_grad():
+ train_metric(historical_y_hat, historical_y)
+ train_results = train_metric.get_info()
+ return train_results, future_container
+
+ train_results, future_container = finetune(0)
+
+ metric = metric_cls(True)
+ per_timestamp_time, start_time = AverageMeter(), time.time()
+ for idx, (future_time, (future_x, future_y)) in enumerate(test_env):
+
+ need_time = "Time Left: {:}".format(
+ convert_secs2time(per_timestamp_time.avg * (len(test_env) - idx), True)
+ )
+ logger.log(
+ "[{:}]".format(time_string())
+ + " [{:04d}/{:04d}]".format(idx, len(test_env))
+ + " "
+ + need_time
+ )
+
+ # build optimizer
+ future_x, future_y = future_x.to(args.device), future_y.to(args.device)
+ future_y_hat = maml.predict(future_x, future_container)
+ future_loss = criterion(future_y_hat, future_y)
+ metric(future_y_hat, future_y)
+ log_str = (
+ "[{:}]".format(time_string())
+ + " [{:04d}/{:04d}]".format(idx, len(test_env))
+ + " train-score: {:.5f}, eval-score: {:.5f}".format(
+ train_results["score"], metric.get_info()["score"]
+ )
+ )
+ logger.log(log_str)
+ logger.log("")
+ per_timestamp_time.update(time.time() - start_time)
+ start_time = time.time()
+
+ logger.log("-" * 200 + "\n")
+ logger.close()
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser("Use the maml.")
+ parser.add_argument(
+ "--save_dir",
+ type=str,
+ default="./outputs/GeMOSA-synthetic/use-maml-nft",
+ help="The checkpoint directory.",
+ )
+ parser.add_argument(
+ "--env_version",
+ type=str,
+ required=True,
+ help="The synthetic enviornment version.",
+ )
+ parser.add_argument(
+ "--hidden_dim",
+ type=int,
+ default=16,
+ help="The hidden dimension.",
+ )
+ parser.add_argument(
+ "--meta_lr",
+ type=float,
+ default=0.02,
+ help="The learning rate for the MAML optimizer (default is Adam)",
+ )
+ parser.add_argument(
+ "--inner_lr",
+ type=float,
+ default=0.005,
+ help="The learning rate for the inner optimization",
+ )
+ parser.add_argument(
+ "--inner_step", type=int, default=1, help="The inner loop steps for MAML."
+ )
+ parser.add_argument(
+ "--seq_length", type=int, default=20, help="The sequence length."
+ )
+ parser.add_argument(
+ "--meta_batch",
+ type=int,
+ default=256,
+ help="The batch size for the meta-model",
+ )
+ parser.add_argument(
+ "--epochs",
+ type=int,
+ default=2000,
+ help="The total number of epochs.",
+ )
+ parser.add_argument(
+ "--early_stop_thresh",
+ type=int,
+ default=50,
+ help="The maximum epochs for early stop.",
+ )
+ parser.add_argument(
+ "--device",
+ type=str,
+ default="cpu",
+ help="",
+ )
+ parser.add_argument(
+ "--workers",
+ type=int,
+ default=4,
+ help="The number of data loading workers (default: 4)",
+ )
+ # Random Seed
+ parser.add_argument("--rand_seed", type=int, default=-1, help="manual seed")
+ args = parser.parse_args()
+ if args.rand_seed is None or args.rand_seed < 0:
+ args.rand_seed = random.randint(1, 100000)
+ assert args.save_dir is not None, "The save dir argument can not be None"
+ args.save_dir = "{:}-s{:}-mlr{:}-d{:}-e{:}-env{:}".format(
+ args.save_dir,
+ args.inner_step,
+ args.meta_lr,
+ args.hidden_dim,
+ args.epochs,
+ args.env_version,
+ )
+ main(args)
diff --git a/AutoDL-Projects/exps/experimental/GeMOSA/baselines/slbm-ft.py b/AutoDL-Projects/exps/experimental/GeMOSA/baselines/slbm-ft.py
new file mode 100644
index 0000000..8d98a5e
--- /dev/null
+++ b/AutoDL-Projects/exps/experimental/GeMOSA/baselines/slbm-ft.py
@@ -0,0 +1,228 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.04 #
+#####################################################
+# python exps/GeMOSA/baselines/slbm-ft.py --env_version v1 --hidden_dim 16 --epochs 500 --init_lr 0.1 --device cuda
+# python exps/GeMOSA/baselines/slbm-ft.py --env_version v2 --hidden_dim 16 --epochs 500 --init_lr 0.1 --device cuda
+# python exps/GeMOSA/baselines/slbm-ft.py --env_version v3 --hidden_dim 32 --epochs 1000 --init_lr 0.05 --device cuda
+# python exps/GeMOSA/baselines/slbm-ft.py --env_version v4 --hidden_dim 32 --epochs 1000 --init_lr 0.05 --device cuda
+#####################################################
+import sys, time, copy, torch, random, argparse
+from tqdm import tqdm
+from copy import deepcopy
+from pathlib import Path
+
+lib_dir = (Path(__file__).parent / ".." / ".." / "..").resolve()
+print("LIB-DIR: {:}".format(lib_dir))
+if str(lib_dir) not in sys.path:
+ sys.path.insert(0, str(lib_dir))
+
+
+from xautodl.procedures import (
+ prepare_seed,
+ prepare_logger,
+ save_checkpoint,
+ copy_checkpoint,
+)
+from xautodl.log_utils import time_string
+from xautodl.log_utils import AverageMeter, convert_secs2time
+
+from xautodl.procedures.metric_utils import (
+ SaveMetric,
+ MSEMetric,
+ Top1AccMetric,
+ ComposeMetric,
+)
+from xautodl.datasets.synthetic_core import get_synthetic_env
+from xautodl.models.xcore import get_model
+from xautodl.utils import show_mean_var
+
+
+def subsample(historical_x, historical_y, maxn=10000):
+ total = historical_x.size(0)
+ if total <= maxn:
+ return historical_x, historical_y
+ else:
+ indexes = torch.randint(low=0, high=total, size=[maxn])
+ return historical_x[indexes], historical_y[indexes]
+
+
+def main(args):
+ prepare_seed(args.rand_seed)
+ logger = prepare_logger(args)
+ env = get_synthetic_env(mode="test", version=args.env_version)
+ model_kwargs = dict(
+ config=dict(model_type="norm_mlp"),
+ input_dim=env.meta_info["input_dim"],
+ output_dim=env.meta_info["output_dim"],
+ hidden_dims=[args.hidden_dim] * 2,
+ act_cls="relu",
+ norm_cls="layer_norm_1d",
+ )
+ logger.log("The total enviornment: {:}".format(env))
+ w_containers = dict()
+
+ if env.meta_info["task"] == "regression":
+ criterion = torch.nn.MSELoss()
+ metric_cls = MSEMetric
+ elif env.meta_info["task"] == "classification":
+ criterion = torch.nn.CrossEntropyLoss()
+ metric_cls = Top1AccMetric
+ else:
+ raise ValueError(
+ "This task ({:}) is not supported.".format(all_env.meta_info["task"])
+ )
+
+ def finetune(index):
+ seq_times = env.get_seq_times(index, args.seq_length)
+ _, (allxs, allys) = env.seq_call(seq_times)
+ allxs, allys = allxs.view(-1, allxs.shape[-1]), allys.view(-1, 1)
+ if env.meta_info["task"] == "classification":
+ allys = allys.view(-1)
+ historical_x, historical_y = allxs.to(args.device), allys.to(args.device)
+ model = get_model(**model_kwargs)
+ model = model.to(args.device)
+
+ optimizer = torch.optim.Adam(model.parameters(), lr=args.init_lr, amsgrad=True)
+ lr_scheduler = torch.optim.lr_scheduler.MultiStepLR(
+ optimizer,
+ milestones=[
+ int(args.epochs * 0.25),
+ int(args.epochs * 0.5),
+ int(args.epochs * 0.75),
+ ],
+ gamma=0.3,
+ )
+
+ train_metric = metric_cls(True)
+ best_loss, best_param = None, None
+ for _iepoch in range(args.epochs):
+ preds = model(historical_x)
+ optimizer.zero_grad()
+ loss = criterion(preds, historical_y)
+ loss.backward()
+ optimizer.step()
+ lr_scheduler.step()
+ # save best
+ if best_loss is None or best_loss > loss.item():
+ best_loss = loss.item()
+ best_param = copy.deepcopy(model.state_dict())
+ model.load_state_dict(best_param)
+ # model.analyze_weights()
+ with torch.no_grad():
+ train_metric(preds, historical_y)
+ train_results = train_metric.get_info()
+ return train_results, model
+
+ metric = metric_cls(True)
+ per_timestamp_time, start_time = AverageMeter(), time.time()
+ for idx, (future_time, (future_x, future_y)) in enumerate(env):
+
+ need_time = "Time Left: {:}".format(
+ convert_secs2time(per_timestamp_time.avg * (len(env) - idx), True)
+ )
+ logger.log(
+ "[{:}]".format(time_string())
+ + " [{:04d}/{:04d}]".format(idx, len(env))
+ + " "
+ + need_time
+ )
+ # train the same data
+ train_results, model = finetune(idx)
+
+ # build optimizer
+ xmetric = ComposeMetric(metric_cls(True), SaveMetric())
+ future_x, future_y = future_x.to(args.device), future_y.to(args.device)
+ future_y_hat = model(future_x)
+ future_loss = criterion(future_y_hat, future_y)
+ metric(future_y_hat, future_y)
+ log_str = (
+ "[{:}]".format(time_string())
+ + " [{:04d}/{:04d}]".format(idx, len(env))
+ + " train-score: {:.5f}, eval-score: {:.5f}".format(
+ train_results["score"], metric.get_info()["score"]
+ )
+ )
+ logger.log(log_str)
+ logger.log("")
+ per_timestamp_time.update(time.time() - start_time)
+ start_time = time.time()
+
+ save_checkpoint(
+ {"w_containers": w_containers},
+ logger.path(None) / "final-ckp.pth",
+ logger,
+ )
+
+ logger.log("-" * 200 + "\n")
+ logger.close()
+ return metric.get_info()["score"]
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser("Use the data in the past.")
+ parser.add_argument(
+ "--save_dir",
+ type=str,
+ default="./outputs/GeMOSA-synthetic/use-same-ft-timestamp",
+ help="The checkpoint directory.",
+ )
+ parser.add_argument(
+ "--env_version",
+ type=str,
+ required=True,
+ help="The synthetic enviornment version.",
+ )
+ parser.add_argument(
+ "--hidden_dim",
+ type=int,
+ required=True,
+ help="The hidden dimension.",
+ )
+ parser.add_argument(
+ "--init_lr",
+ type=float,
+ default=0.1,
+ help="The initial learning rate for the optimizer (default is Adam)",
+ )
+ parser.add_argument(
+ "--seq_length", type=int, default=20, help="The sequence length."
+ )
+ parser.add_argument(
+ "--batch_size",
+ type=int,
+ default=512,
+ help="The batch size",
+ )
+ parser.add_argument(
+ "--epochs",
+ type=int,
+ default=300,
+ help="The total number of epochs.",
+ )
+ parser.add_argument(
+ "--device",
+ type=str,
+ default="cpu",
+ help="",
+ )
+ parser.add_argument(
+ "--workers",
+ type=int,
+ default=4,
+ help="The number of data loading workers (default: 4)",
+ )
+ # Random Seed
+ parser.add_argument("--rand_seed", type=int, default=-1, help="manual seed")
+ args = parser.parse_args()
+ args.save_dir = "{:}-d{:}_e{:}_lr{:}-env{:}".format(
+ args.save_dir, args.hidden_dim, args.epochs, args.init_lr, args.env_version
+ )
+ if args.rand_seed is None or args.rand_seed < 0:
+ results = []
+ for iseed in range(3):
+ args.rand_seed = random.randint(1, 100000)
+ result = main(args)
+ results.append(result)
+ show_mean_var(results)
+ else:
+ main(args)
diff --git a/AutoDL-Projects/exps/experimental/GeMOSA/baselines/slbm-nof.py b/AutoDL-Projects/exps/experimental/GeMOSA/baselines/slbm-nof.py
new file mode 100644
index 0000000..144f874
--- /dev/null
+++ b/AutoDL-Projects/exps/experimental/GeMOSA/baselines/slbm-nof.py
@@ -0,0 +1,227 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.04 #
+#####################################################
+# python exps/GeMOSA/baselines/slbm-nof.py --env_version v1 --hidden_dim 16 --epochs 500 --init_lr 0.1 --device cuda
+# python exps/GeMOSA/baselines/slbm-nof.py --env_version v2 --hidden_dim 16 --epochs 500 --init_lr 0.1 --device cuda
+# python exps/GeMOSA/baselines/slbm-nof.py --env_version v3 --hidden_dim 32 --epochs 1000 --init_lr 0.05 --device cuda
+# python exps/GeMOSA/baselines/slbm-nof.py --env_version v4 --hidden_dim 32 --epochs 1000 --init_lr 0.05 --device cuda
+#####################################################
+import sys, time, copy, torch, random, argparse
+from tqdm import tqdm
+from copy import deepcopy
+from pathlib import Path
+
+lib_dir = (Path(__file__).parent / ".." / ".." / "..").resolve()
+print("LIB-DIR: {:}".format(lib_dir))
+if str(lib_dir) not in sys.path:
+ sys.path.insert(0, str(lib_dir))
+
+
+from xautodl.procedures import (
+ prepare_seed,
+ prepare_logger,
+ save_checkpoint,
+ copy_checkpoint,
+)
+from xautodl.log_utils import time_string
+from xautodl.log_utils import AverageMeter, convert_secs2time
+
+from xautodl.procedures.metric_utils import (
+ SaveMetric,
+ MSEMetric,
+ Top1AccMetric,
+ ComposeMetric,
+)
+from xautodl.datasets.synthetic_core import get_synthetic_env
+from xautodl.models.xcore import get_model
+from xautodl.utils import show_mean_var
+
+
+def subsample(historical_x, historical_y, maxn=10000):
+ total = historical_x.size(0)
+ if total <= maxn:
+ return historical_x, historical_y
+ else:
+ indexes = torch.randint(low=0, high=total, size=[maxn])
+ return historical_x[indexes], historical_y[indexes]
+
+
+def main(args):
+ prepare_seed(args.rand_seed)
+ logger = prepare_logger(args)
+ env = get_synthetic_env(mode="test", version=args.env_version)
+ model_kwargs = dict(
+ config=dict(model_type="norm_mlp"),
+ input_dim=env.meta_info["input_dim"],
+ output_dim=env.meta_info["output_dim"],
+ hidden_dims=[args.hidden_dim] * 2,
+ act_cls="relu",
+ norm_cls="layer_norm_1d",
+ )
+ logger.log("The total enviornment: {:}".format(env))
+ w_containers = dict()
+
+ if env.meta_info["task"] == "regression":
+ criterion = torch.nn.MSELoss()
+ metric_cls = MSEMetric
+ elif env.meta_info["task"] == "classification":
+ criterion = torch.nn.CrossEntropyLoss()
+ metric_cls = Top1AccMetric
+ else:
+ raise ValueError(
+ "This task ({:}) is not supported.".format(all_env.meta_info["task"])
+ )
+
+ seq_times = env.get_seq_times(0, args.seq_length)
+ _, (allxs, allys) = env.seq_call(seq_times)
+ allxs, allys = allxs.view(-1, allxs.shape[-1]), allys.view(-1, 1)
+ if env.meta_info["task"] == "classification":
+ allys = allys.view(-1)
+
+ historical_x, historical_y = allxs.to(args.device), allys.to(args.device)
+ model = get_model(**model_kwargs)
+ model = model.to(args.device)
+
+ optimizer = torch.optim.Adam(model.parameters(), lr=args.init_lr, amsgrad=True)
+ lr_scheduler = torch.optim.lr_scheduler.MultiStepLR(
+ optimizer,
+ milestones=[
+ int(args.epochs * 0.25),
+ int(args.epochs * 0.5),
+ int(args.epochs * 0.75),
+ ],
+ gamma=0.3,
+ )
+
+ train_metric = metric_cls(True)
+ best_loss, best_param = None, None
+ for _iepoch in range(args.epochs):
+ preds = model(historical_x)
+ optimizer.zero_grad()
+ loss = criterion(preds, historical_y)
+ loss.backward()
+ optimizer.step()
+ lr_scheduler.step()
+ # save best
+ if best_loss is None or best_loss > loss.item():
+ best_loss = loss.item()
+ best_param = copy.deepcopy(model.state_dict())
+ model.load_state_dict(best_param)
+ model.analyze_weights()
+ with torch.no_grad():
+ train_metric(preds, historical_y)
+ train_results = train_metric.get_info()
+ print(train_results)
+
+ metric = metric_cls(True)
+ per_timestamp_time, start_time = AverageMeter(), time.time()
+ for idx, (future_time, (future_x, future_y)) in enumerate(env):
+
+ need_time = "Time Left: {:}".format(
+ convert_secs2time(per_timestamp_time.avg * (len(env) - idx), True)
+ )
+ logger.log(
+ "[{:}]".format(time_string())
+ + " [{:04d}/{:04d}]".format(idx, len(env))
+ + " "
+ + need_time
+ )
+ # train the same data
+
+ # build optimizer
+ xmetric = ComposeMetric(metric_cls(True), SaveMetric())
+ future_x, future_y = future_x.to(args.device), future_y.to(args.device)
+ future_y_hat = model(future_x)
+ future_loss = criterion(future_y_hat, future_y)
+ metric(future_y_hat, future_y)
+ log_str = (
+ "[{:}]".format(time_string())
+ + " [{:04d}/{:04d}]".format(idx, len(env))
+ + " train-score: {:.5f}, eval-score: {:.5f}".format(
+ train_results["score"], metric.get_info()["score"]
+ )
+ )
+ logger.log(log_str)
+ logger.log("")
+ per_timestamp_time.update(time.time() - start_time)
+ start_time = time.time()
+
+ save_checkpoint(
+ {"w_containers": w_containers},
+ logger.path(None) / "final-ckp.pth",
+ logger,
+ )
+
+ logger.log("-" * 200 + "\n")
+ logger.close()
+ return metric.get_info()["score"]
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser("Use the data in the past.")
+ parser.add_argument(
+ "--save_dir",
+ type=str,
+ default="./outputs/GeMOSA-synthetic/use-same-nof-timestamp",
+ help="The checkpoint directory.",
+ )
+ parser.add_argument(
+ "--env_version",
+ type=str,
+ required=True,
+ help="The synthetic enviornment version.",
+ )
+ parser.add_argument(
+ "--hidden_dim",
+ type=int,
+ required=True,
+ help="The hidden dimension.",
+ )
+ parser.add_argument(
+ "--seq_length", type=int, default=20, help="The sequence length."
+ )
+ parser.add_argument(
+ "--init_lr",
+ type=float,
+ default=0.1,
+ help="The initial learning rate for the optimizer (default is Adam)",
+ )
+ parser.add_argument(
+ "--batch_size",
+ type=int,
+ default=512,
+ help="The batch size",
+ )
+ parser.add_argument(
+ "--epochs",
+ type=int,
+ default=300,
+ help="The total number of epochs.",
+ )
+ parser.add_argument(
+ "--device",
+ type=str,
+ default="cpu",
+ help="",
+ )
+ parser.add_argument(
+ "--workers",
+ type=int,
+ default=4,
+ help="The number of data loading workers (default: 4)",
+ )
+ # Random Seed
+ parser.add_argument("--rand_seed", type=int, default=-1, help="manual seed")
+ args = parser.parse_args()
+ args.save_dir = "{:}-d{:}_e{:}_lr{:}-env{:}".format(
+ args.save_dir, args.hidden_dim, args.epochs, args.init_lr, args.env_version
+ )
+ if args.rand_seed is None or args.rand_seed < 0:
+ results = []
+ for iseed in range(3):
+ args.rand_seed = random.randint(1, 100000)
+ result = main(args)
+ results.append(result)
+ show_mean_var(results)
+ else:
+ main(args)
diff --git a/AutoDL-Projects/exps/experimental/GeMOSA/basic-his.py b/AutoDL-Projects/exps/experimental/GeMOSA/basic-his.py
new file mode 100644
index 0000000..0752098
--- /dev/null
+++ b/AutoDL-Projects/exps/experimental/GeMOSA/basic-his.py
@@ -0,0 +1,206 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.04 #
+#####################################################
+# python exps/LFNA/basic-his.py --srange 1-999 --env_version v1 --hidden_dim 16
+#####################################################
+import sys, time, copy, torch, random, argparse
+from tqdm import tqdm
+from copy import deepcopy
+
+from xautodl.procedures import (
+ prepare_seed,
+ prepare_logger,
+ save_checkpoint,
+ copy_checkpoint,
+)
+from xautodl.log_utils import time_string
+from xautodl.log_utils import AverageMeter, convert_secs2time
+
+from xautodl.utils import split_str2indexes
+
+from xautodl.procedures.advanced_main import basic_train_fn, basic_eval_fn
+from xautodl.procedures.metric_utils import SaveMetric, MSEMetric, ComposeMetric
+from xautodl.datasets.synthetic_core import get_synthetic_env
+from xautodl.models.xcore import get_model
+
+
+from lfna_utils import lfna_setup
+
+
+def subsample(historical_x, historical_y, maxn=10000):
+ total = historical_x.size(0)
+ if total <= maxn:
+ return historical_x, historical_y
+ else:
+ indexes = torch.randint(low=0, high=total, size=[maxn])
+ return historical_x[indexes], historical_y[indexes]
+
+
+def main(args):
+ logger, env_info, model_kwargs = lfna_setup(args)
+
+ # check indexes to be evaluated
+ to_evaluate_indexes = split_str2indexes(args.srange, env_info["total"], None)
+ logger.log(
+ "Evaluate {:}, which has {:} timestamps in total.".format(
+ args.srange, len(to_evaluate_indexes)
+ )
+ )
+
+ w_container_per_epoch = dict()
+
+ per_timestamp_time, start_time = AverageMeter(), time.time()
+ for i, idx in enumerate(to_evaluate_indexes):
+
+ need_time = "Time Left: {:}".format(
+ convert_secs2time(
+ per_timestamp_time.avg * (len(to_evaluate_indexes) - i), True
+ )
+ )
+ logger.log(
+ "[{:}]".format(time_string())
+ + " [{:04d}/{:04d}][{:04d}]".format(i, len(to_evaluate_indexes), idx)
+ + " "
+ + need_time
+ )
+ # train the same data
+ assert idx != 0
+ historical_x, historical_y = [], []
+ for past_i in range(idx):
+ historical_x.append(env_info["{:}-x".format(past_i)])
+ historical_y.append(env_info["{:}-y".format(past_i)])
+ historical_x, historical_y = torch.cat(historical_x), torch.cat(historical_y)
+ historical_x, historical_y = subsample(historical_x, historical_y)
+ # build model
+ model = get_model(dict(model_type="simple_mlp"), **model_kwargs)
+ # build optimizer
+ optimizer = torch.optim.Adam(model.parameters(), lr=args.init_lr, amsgrad=True)
+ criterion = torch.nn.MSELoss()
+ lr_scheduler = torch.optim.lr_scheduler.MultiStepLR(
+ optimizer,
+ milestones=[
+ int(args.epochs * 0.25),
+ int(args.epochs * 0.5),
+ int(args.epochs * 0.75),
+ ],
+ gamma=0.3,
+ )
+ train_metric = MSEMetric()
+ best_loss, best_param = None, None
+ for _iepoch in range(args.epochs):
+ preds = model(historical_x)
+ optimizer.zero_grad()
+ loss = criterion(preds, historical_y)
+ loss.backward()
+ optimizer.step()
+ lr_scheduler.step()
+ # save best
+ if best_loss is None or best_loss > loss.item():
+ best_loss = loss.item()
+ best_param = copy.deepcopy(model.state_dict())
+ model.load_state_dict(best_param)
+ with torch.no_grad():
+ train_metric(preds, historical_y)
+ train_results = train_metric.get_info()
+
+ metric = ComposeMetric(MSEMetric(), SaveMetric())
+ eval_dataset = torch.utils.data.TensorDataset(
+ env_info["{:}-x".format(idx)], env_info["{:}-y".format(idx)]
+ )
+ eval_loader = torch.utils.data.DataLoader(
+ eval_dataset, batch_size=args.batch_size, shuffle=False, num_workers=0
+ )
+ results = basic_eval_fn(eval_loader, model, metric, logger)
+ log_str = (
+ "[{:}]".format(time_string())
+ + " [{:04d}/{:04d}]".format(idx, env_info["total"])
+ + " train-mse: {:.5f}, eval-mse: {:.5f}".format(
+ train_results["mse"], results["mse"]
+ )
+ )
+ logger.log(log_str)
+
+ save_path = logger.path(None) / "{:04d}-{:04d}.pth".format(
+ idx, env_info["total"]
+ )
+ w_container_per_epoch[idx] = model.get_w_container().no_grad_clone()
+ save_checkpoint(
+ {
+ "model_state_dict": model.state_dict(),
+ "model": model,
+ "index": idx,
+ "timestamp": env_info["{:}-timestamp".format(idx)],
+ },
+ save_path,
+ logger,
+ )
+ logger.log("")
+ per_timestamp_time.update(time.time() - start_time)
+ start_time = time.time()
+
+ save_checkpoint(
+ {"w_container_per_epoch": w_container_per_epoch},
+ logger.path(None) / "final-ckp.pth",
+ logger,
+ )
+ logger.log("-" * 200 + "\n")
+ logger.close()
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser("Use all the past data to train.")
+ parser.add_argument(
+ "--save_dir",
+ type=str,
+ default="./outputs/lfna-synthetic/use-all-past-data",
+ help="The checkpoint directory.",
+ )
+ parser.add_argument(
+ "--env_version",
+ type=str,
+ required=True,
+ help="The synthetic enviornment version.",
+ )
+ parser.add_argument(
+ "--hidden_dim",
+ type=int,
+ required=True,
+ help="The hidden dimension.",
+ )
+ parser.add_argument(
+ "--init_lr",
+ type=float,
+ default=0.1,
+ help="The initial learning rate for the optimizer (default is Adam)",
+ )
+ parser.add_argument(
+ "--batch_size",
+ type=int,
+ default=512,
+ help="The batch size",
+ )
+ parser.add_argument(
+ "--epochs",
+ type=int,
+ default=1000,
+ help="The total number of epochs.",
+ )
+ parser.add_argument(
+ "--srange", type=str, required=True, help="The range of models to be evaluated"
+ )
+ parser.add_argument(
+ "--workers",
+ type=int,
+ default=4,
+ help="The number of data loading workers (default: 4)",
+ )
+ # Random Seed
+ parser.add_argument("--rand_seed", type=int, default=-1, help="manual seed")
+ args = parser.parse_args()
+ if args.rand_seed is None or args.rand_seed < 0:
+ args.rand_seed = random.randint(1, 100000)
+ assert args.save_dir is not None, "The save dir argument can not be None"
+ args.save_dir = "{:}-{:}-d{:}".format(
+ args.save_dir, args.env_version, args.hidden_dim
+ )
+ main(args)
diff --git a/AutoDL-Projects/exps/experimental/GeMOSA/basic-prev.py b/AutoDL-Projects/exps/experimental/GeMOSA/basic-prev.py
new file mode 100644
index 0000000..84dfbf2
--- /dev/null
+++ b/AutoDL-Projects/exps/experimental/GeMOSA/basic-prev.py
@@ -0,0 +1,207 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.04 #
+#####################################################
+# python exps/GeMOSA/basic-prev.py --env_version v1 --prev_time 5 --hidden_dim 16 --epochs 500 --init_lr 0.1
+# python exps/GeMOSA/basic-prev.py --env_version v2 --hidden_dim 16 --epochs 1000 --init_lr 0.05
+#####################################################
+import sys, time, copy, torch, random, argparse
+from tqdm import tqdm
+from copy import deepcopy
+from pathlib import Path
+
+lib_dir = (Path(__file__).parent / ".." / "..").resolve()
+if str(lib_dir) not in sys.path:
+ sys.path.insert(0, str(lib_dir))
+
+from xautodl.procedures import (
+ prepare_seed,
+ prepare_logger,
+ save_checkpoint,
+ copy_checkpoint,
+)
+from xautodl.log_utils import time_string
+from xautodl.log_utils import AverageMeter, convert_secs2time
+
+from xautodl.utils import split_str2indexes
+
+from xautodl.procedures.advanced_main import basic_train_fn, basic_eval_fn
+from xautodl.procedures.metric_utils import SaveMetric, MSEMetric, ComposeMetric
+from xautodl.datasets.synthetic_core import get_synthetic_env
+from xautodl.models.xcore import get_model
+
+from lfna_utils import lfna_setup
+
+
+def subsample(historical_x, historical_y, maxn=10000):
+ total = historical_x.size(0)
+ if total <= maxn:
+ return historical_x, historical_y
+ else:
+ indexes = torch.randint(low=0, high=total, size=[maxn])
+ return historical_x[indexes], historical_y[indexes]
+
+
+def main(args):
+ logger, model_kwargs = lfna_setup(args)
+
+ w_containers = dict()
+
+ per_timestamp_time, start_time = AverageMeter(), time.time()
+ for idx in range(args.prev_time, env_info["total"]):
+
+ need_time = "Time Left: {:}".format(
+ convert_secs2time(per_timestamp_time.avg * (env_info["total"] - idx), True)
+ )
+ logger.log(
+ "[{:}]".format(time_string())
+ + " [{:04d}/{:04d}]".format(idx, env_info["total"])
+ + " "
+ + need_time
+ )
+ # train the same data
+ historical_x = env_info["{:}-x".format(idx - args.prev_time)]
+ historical_y = env_info["{:}-y".format(idx - args.prev_time)]
+ # build model
+ model = get_model(**model_kwargs)
+ print(model)
+ # build optimizer
+ optimizer = torch.optim.Adam(model.parameters(), lr=args.init_lr, amsgrad=True)
+ criterion = torch.nn.MSELoss()
+ lr_scheduler = torch.optim.lr_scheduler.MultiStepLR(
+ optimizer,
+ milestones=[
+ int(args.epochs * 0.25),
+ int(args.epochs * 0.5),
+ int(args.epochs * 0.75),
+ ],
+ gamma=0.3,
+ )
+ train_metric = MSEMetric()
+ best_loss, best_param = None, None
+ for _iepoch in range(args.epochs):
+ preds = model(historical_x)
+ optimizer.zero_grad()
+ loss = criterion(preds, historical_y)
+ loss.backward()
+ optimizer.step()
+ lr_scheduler.step()
+ # save best
+ if best_loss is None or best_loss > loss.item():
+ best_loss = loss.item()
+ best_param = copy.deepcopy(model.state_dict())
+ model.load_state_dict(best_param)
+ model.analyze_weights()
+ with torch.no_grad():
+ train_metric(preds, historical_y)
+ train_results = train_metric.get_info()
+
+ metric = ComposeMetric(MSEMetric(), SaveMetric())
+ eval_dataset = torch.utils.data.TensorDataset(
+ env_info["{:}-x".format(idx)], env_info["{:}-y".format(idx)]
+ )
+ eval_loader = torch.utils.data.DataLoader(
+ eval_dataset, batch_size=args.batch_size, shuffle=False, num_workers=0
+ )
+ results = basic_eval_fn(eval_loader, model, metric, logger)
+ log_str = (
+ "[{:}]".format(time_string())
+ + " [{:04d}/{:04d}]".format(idx, env_info["total"])
+ + " train-mse: {:.5f}, eval-mse: {:.5f}".format(
+ train_results["mse"], results["mse"]
+ )
+ )
+ logger.log(log_str)
+
+ save_path = logger.path(None) / "{:04d}-{:04d}.pth".format(
+ idx, env_info["total"]
+ )
+ w_containers[idx] = model.get_w_container().no_grad_clone()
+ save_checkpoint(
+ {
+ "model_state_dict": model.state_dict(),
+ "model": model,
+ "index": idx,
+ "timestamp": env_info["{:}-timestamp".format(idx)],
+ },
+ save_path,
+ logger,
+ )
+ logger.log("")
+ per_timestamp_time.update(time.time() - start_time)
+ start_time = time.time()
+
+ save_checkpoint(
+ {"w_containers": w_containers},
+ logger.path(None) / "final-ckp.pth",
+ logger,
+ )
+
+ logger.log("-" * 200 + "\n")
+ logger.close()
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser("Use the data in the last timestamp.")
+ parser.add_argument(
+ "--save_dir",
+ type=str,
+ default="./outputs/lfna-synthetic/use-prev-timestamp",
+ help="The checkpoint directory.",
+ )
+ parser.add_argument(
+ "--env_version",
+ type=str,
+ required=True,
+ help="The synthetic enviornment version.",
+ )
+ parser.add_argument(
+ "--hidden_dim",
+ type=int,
+ required=True,
+ help="The hidden dimension.",
+ )
+ parser.add_argument(
+ "--init_lr",
+ type=float,
+ default=0.1,
+ help="The initial learning rate for the optimizer (default is Adam)",
+ )
+ parser.add_argument(
+ "--prev_time",
+ type=int,
+ default=5,
+ help="The gap between prev_time and current_timestamp",
+ )
+ parser.add_argument(
+ "--batch_size",
+ type=int,
+ default=512,
+ help="The batch size",
+ )
+ parser.add_argument(
+ "--epochs",
+ type=int,
+ default=300,
+ help="The total number of epochs.",
+ )
+ parser.add_argument(
+ "--workers",
+ type=int,
+ default=4,
+ help="The number of data loading workers (default: 4)",
+ )
+ # Random Seed
+ parser.add_argument("--rand_seed", type=int, default=-1, help="manual seed")
+ args = parser.parse_args()
+ if args.rand_seed is None or args.rand_seed < 0:
+ args.rand_seed = random.randint(1, 100000)
+ assert args.save_dir is not None, "The save dir argument can not be None"
+ args.save_dir = "{:}-d{:}_e{:}_lr{:}-prev{:}-env{:}".format(
+ args.save_dir,
+ args.hidden_dim,
+ args.epochs,
+ args.init_lr,
+ args.prev_time,
+ args.env_version,
+ )
+ main(args)
diff --git a/AutoDL-Projects/exps/experimental/GeMOSA/basic-same.py b/AutoDL-Projects/exps/experimental/GeMOSA/basic-same.py
new file mode 100644
index 0000000..5e7f739
--- /dev/null
+++ b/AutoDL-Projects/exps/experimental/GeMOSA/basic-same.py
@@ -0,0 +1,228 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.04 #
+#####################################################
+# python exps/GeMOSA/basic-same.py --env_version v1 --hidden_dim 16 --epochs 500 --init_lr 0.1 --device cuda
+# python exps/GeMOSA/basic-same.py --env_version v2 --hidden_dim 16 --epochs 500 --init_lr 0.1 --device cuda
+# python exps/GeMOSA/basic-same.py --env_version v3 --hidden_dim 32 --epochs 1000 --init_lr 0.05 --device cuda
+# python exps/GeMOSA/basic-same.py --env_version v4 --hidden_dim 32 --epochs 1000 --init_lr 0.05 --device cuda
+#####################################################
+import sys, time, copy, torch, random, argparse
+from tqdm import tqdm
+from copy import deepcopy
+from pathlib import Path
+
+lib_dir = (Path(__file__).parent / ".." / "..").resolve()
+print("LIB-DIR: {:}".format(lib_dir))
+if str(lib_dir) not in sys.path:
+ sys.path.insert(0, str(lib_dir))
+
+
+from xautodl.procedures import (
+ prepare_seed,
+ prepare_logger,
+ save_checkpoint,
+ copy_checkpoint,
+)
+from xautodl.log_utils import time_string
+from xautodl.log_utils import AverageMeter, convert_secs2time
+
+from xautodl.utils import split_str2indexes
+
+from xautodl.procedures.metric_utils import (
+ SaveMetric,
+ MSEMetric,
+ Top1AccMetric,
+ ComposeMetric,
+)
+from xautodl.datasets.synthetic_core import get_synthetic_env
+from xautodl.models.xcore import get_model
+
+
+def subsample(historical_x, historical_y, maxn=10000):
+ total = historical_x.size(0)
+ if total <= maxn:
+ return historical_x, historical_y
+ else:
+ indexes = torch.randint(low=0, high=total, size=[maxn])
+ return historical_x[indexes], historical_y[indexes]
+
+
+def main(args):
+ prepare_seed(args.rand_seed)
+ logger = prepare_logger(args)
+ env = get_synthetic_env(mode=None, version=args.env_version)
+ model_kwargs = dict(
+ config=dict(model_type="norm_mlp"),
+ input_dim=env.meta_info["input_dim"],
+ output_dim=env.meta_info["output_dim"],
+ hidden_dims=[args.hidden_dim] * 2,
+ act_cls="relu",
+ norm_cls="layer_norm_1d",
+ )
+ logger.log("The total enviornment: {:}".format(env))
+ w_containers = dict()
+
+ if env.meta_info["task"] == "regression":
+ criterion = torch.nn.MSELoss()
+ metric_cls = MSEMetric
+ elif env.meta_info["task"] == "classification":
+ criterion = torch.nn.CrossEntropyLoss()
+ metric_cls = Top1AccMetric
+ else:
+ raise ValueError(
+ "This task ({:}) is not supported.".format(all_env.meta_info["task"])
+ )
+
+ per_timestamp_time, start_time = AverageMeter(), time.time()
+ for idx, (future_time, (future_x, future_y)) in enumerate(env):
+
+ need_time = "Time Left: {:}".format(
+ convert_secs2time(per_timestamp_time.avg * (len(env) - idx), True)
+ )
+ logger.log(
+ "[{:}]".format(time_string())
+ + " [{:04d}/{:04d}]".format(idx, len(env))
+ + " "
+ + need_time
+ )
+ # train the same data
+ historical_x = future_x.to(args.device)
+ historical_y = future_y.to(args.device)
+ # build model
+ model = get_model(**model_kwargs)
+ model = model.to(args.device)
+ if idx == 0:
+ print(model)
+ # build optimizer
+ optimizer = torch.optim.Adam(model.parameters(), lr=args.init_lr, amsgrad=True)
+ lr_scheduler = torch.optim.lr_scheduler.MultiStepLR(
+ optimizer,
+ milestones=[
+ int(args.epochs * 0.25),
+ int(args.epochs * 0.5),
+ int(args.epochs * 0.75),
+ ],
+ gamma=0.3,
+ )
+ train_metric = metric_cls(True)
+ best_loss, best_param = None, None
+ for _iepoch in range(args.epochs):
+ preds = model(historical_x)
+ optimizer.zero_grad()
+ loss = criterion(preds, historical_y)
+ loss.backward()
+ optimizer.step()
+ lr_scheduler.step()
+ # save best
+ if best_loss is None or best_loss > loss.item():
+ best_loss = loss.item()
+ best_param = copy.deepcopy(model.state_dict())
+ model.load_state_dict(best_param)
+ model.analyze_weights()
+ with torch.no_grad():
+ train_metric(preds, historical_y)
+ train_results = train_metric.get_info()
+
+ xmetric = ComposeMetric(metric_cls(True), SaveMetric())
+ eval_dataset = torch.utils.data.TensorDataset(
+ future_x.to(args.device), future_y.to(args.device)
+ )
+ eval_loader = torch.utils.data.DataLoader(
+ eval_dataset, batch_size=args.batch_size, shuffle=False, num_workers=0
+ )
+ results = basic_eval_fn(eval_loader, model, xmetric, logger)
+ log_str = (
+ "[{:}]".format(time_string())
+ + " [{:04d}/{:04d}]".format(idx, len(env))
+ + " train-score: {:.5f}, eval-score: {:.5f}".format(
+ train_results["score"], results["score"]
+ )
+ )
+ logger.log(log_str)
+
+ save_path = logger.path(None) / "{:04d}-{:04d}.pth".format(idx, len(env))
+ w_containers[idx] = model.get_w_container().no_grad_clone()
+ save_checkpoint(
+ {
+ "model_state_dict": model.state_dict(),
+ "model": model,
+ "index": idx,
+ "timestamp": future_time.item(),
+ },
+ save_path,
+ logger,
+ )
+ logger.log("")
+ per_timestamp_time.update(time.time() - start_time)
+ start_time = time.time()
+
+ save_checkpoint(
+ {"w_containers": w_containers},
+ logger.path(None) / "final-ckp.pth",
+ logger,
+ )
+
+ logger.log("-" * 200 + "\n")
+ logger.close()
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser("Use the data in the past.")
+ parser.add_argument(
+ "--save_dir",
+ type=str,
+ default="./outputs/GeMOSA-synthetic/use-same-timestamp",
+ help="The checkpoint directory.",
+ )
+ parser.add_argument(
+ "--env_version",
+ type=str,
+ required=True,
+ help="The synthetic enviornment version.",
+ )
+ parser.add_argument(
+ "--hidden_dim",
+ type=int,
+ required=True,
+ help="The hidden dimension.",
+ )
+ parser.add_argument(
+ "--init_lr",
+ type=float,
+ default=0.1,
+ help="The initial learning rate for the optimizer (default is Adam)",
+ )
+ parser.add_argument(
+ "--batch_size",
+ type=int,
+ default=512,
+ help="The batch size",
+ )
+ parser.add_argument(
+ "--epochs",
+ type=int,
+ default=300,
+ help="The total number of epochs.",
+ )
+ parser.add_argument(
+ "--device",
+ type=str,
+ default="cpu",
+ help="",
+ )
+ parser.add_argument(
+ "--workers",
+ type=int,
+ default=4,
+ help="The number of data loading workers (default: 4)",
+ )
+ # Random Seed
+ parser.add_argument("--rand_seed", type=int, default=-1, help="manual seed")
+ args = parser.parse_args()
+ if args.rand_seed is None or args.rand_seed < 0:
+ args.rand_seed = random.randint(1, 100000)
+ assert args.save_dir is not None, "The save dir argument can not be None"
+ args.save_dir = "{:}-d{:}_e{:}_lr{:}-env{:}".format(
+ args.save_dir, args.hidden_dim, args.epochs, args.init_lr, args.env_version
+ )
+ main(args)
diff --git a/AutoDL-Projects/exps/experimental/GeMOSA/main.py b/AutoDL-Projects/exps/experimental/GeMOSA/main.py
new file mode 100644
index 0000000..5058860
--- /dev/null
+++ b/AutoDL-Projects/exps/experimental/GeMOSA/main.py
@@ -0,0 +1,438 @@
+##########################################################
+# Learning to Efficiently Generate Models One Step Ahead #
+##########################################################
+# <----> run on CPU
+# python exps/GeMOSA/main.py --env_version v1 --workers 0
+# <----> run on a GPU
+# python exps/GeMOSA/main.py --env_version v1 --lr 0.002 --hidden_dim 16 --meta_batch 256 --device cuda
+# python exps/GeMOSA/main.py --env_version v2 --lr 0.002 --hidden_dim 16 --meta_batch 256 --device cuda
+# python exps/GeMOSA/main.py --env_version v3 --lr 0.002 --hidden_dim 32 --time_dim 32 --meta_batch 256 --device cuda
+# python exps/GeMOSA/main.py --env_version v4 --lr 0.002 --hidden_dim 32 --time_dim 32 --meta_batch 256 --device cuda
+# <----> ablation commands
+# python exps/GeMOSA/main.py --env_version v1 --lr 0.002 --hidden_dim 16 --meta_batch 256 --ablation old --device cuda
+# python exps/GeMOSA/main.py --env_version v2 --lr 0.002 --hidden_dim 16 --meta_batch 256 --ablation old --device cuda
+# python exps/GeMOSA/main.py --env_version v3 --lr 0.002 --hidden_dim 32 --time_dim 32 --meta_batch 256 --ablation old --device cuda
+# python exps/GeMOSA/main.py --env_version v4 --lr 0.002 --hidden_dim 32 --time_dim 32 --meta_batch 256 --ablation old --device cuda
+##########################################################
+import sys, time, copy, torch, random, argparse
+from tqdm import tqdm
+from copy import deepcopy
+from pathlib import Path
+from torch.nn import functional as F
+
+lib_dir = (Path(__file__).parent / ".." / "..").resolve()
+print("LIB-DIR: {:}".format(lib_dir))
+if str(lib_dir) not in sys.path:
+ sys.path.insert(0, str(lib_dir))
+
+from xautodl.procedures import (
+ prepare_seed,
+ prepare_logger,
+ save_checkpoint,
+ copy_checkpoint,
+)
+from xautodl.log_utils import time_string
+from xautodl.log_utils import AverageMeter, convert_secs2time
+
+from xautodl.utils import split_str2indexes
+
+from xautodl.procedures.advanced_main import basic_train_fn, basic_eval_fn
+from xautodl.procedures.metric_utils import SaveMetric, MSEMetric, ComposeMetric
+from xautodl.datasets.synthetic_core import get_synthetic_env
+from xautodl.models.xcore import get_model
+from xautodl.procedures.metric_utils import MSEMetric, Top1AccMetric
+
+from meta_model import MetaModelV1
+from meta_model_ablation import MetaModel_TraditionalAtt
+
+
+def online_evaluate(
+ env,
+ meta_model,
+ base_model,
+ criterion,
+ metric,
+ args,
+ logger,
+ save=False,
+ easy_adapt=False,
+):
+ logger.log("Online evaluate: {:}".format(env))
+ metric.reset()
+ loss_meter = AverageMeter()
+ w_containers = dict()
+ for idx, (future_time, (future_x, future_y)) in enumerate(env):
+ with torch.no_grad():
+ meta_model.eval()
+ base_model.eval()
+ future_time_embed = meta_model.gen_time_embed(
+ future_time.to(args.device).view(-1)
+ )
+ [future_container] = meta_model.gen_model(future_time_embed)
+ if save:
+ w_containers[idx] = future_container.no_grad_clone()
+ future_x, future_y = future_x.to(args.device), future_y.to(args.device)
+ future_y_hat = base_model.forward_with_container(future_x, future_container)
+ future_loss = criterion(future_y_hat, future_y)
+ loss_meter.update(future_loss.item())
+ # accumulate the metric scores
+ score = metric(future_y_hat, future_y)
+ if easy_adapt:
+ meta_model.easy_adapt(future_time.item(), future_time_embed)
+ refine, post_refine_loss = False, -1
+ else:
+ refine, post_refine_loss = meta_model.adapt(
+ base_model,
+ criterion,
+ future_time.item(),
+ future_x,
+ future_y,
+ args.refine_lr,
+ args.refine_epochs,
+ {"param": future_time_embed, "loss": future_loss.item()},
+ )
+ logger.log(
+ "[ONLINE] [{:03d}/{:03d}] loss={:.4f}, score={:.4f}".format(
+ idx, len(env), future_loss.item(), score
+ )
+ + ", post-loss={:.4f}".format(post_refine_loss if refine else -1)
+ )
+ meta_model.clear_fixed()
+ meta_model.clear_learnt()
+ return w_containers, loss_meter.avg, metric.get_info()["score"]
+
+
+def meta_train_procedure(base_model, meta_model, criterion, xenv, args, logger):
+ base_model.train()
+ meta_model.train()
+ optimizer = torch.optim.Adam(
+ meta_model.get_parameters(True, True, True),
+ lr=args.lr,
+ weight_decay=args.weight_decay,
+ amsgrad=True,
+ )
+ logger.log("Pre-train the meta-model")
+ logger.log("Using the optimizer: {:}".format(optimizer))
+
+ meta_model.set_best_dir(logger.path(None) / "ckps-pretrain-v2")
+ final_best_name = "final-pretrain-{:}.pth".format(args.rand_seed)
+ if meta_model.has_best(final_best_name):
+ meta_model.load_best(final_best_name)
+ logger.log("Directly load the best model from {:}".format(final_best_name))
+ return
+
+ total_indexes = list(range(meta_model.meta_length))
+ meta_model.set_best_name("pretrain-{:}.pth".format(args.rand_seed))
+ last_success_epoch, early_stop_thresh = 0, args.pretrain_early_stop_thresh
+ per_epoch_time, start_time = AverageMeter(), time.time()
+ device = args.device
+ for iepoch in range(args.epochs):
+ left_time = "Time Left: {:}".format(
+ convert_secs2time(per_epoch_time.avg * (args.epochs - iepoch), True)
+ )
+ optimizer.zero_grad()
+
+ generated_time_embeds = meta_model.gen_time_embed(meta_model.meta_timestamps)
+
+ batch_indexes = random.choices(total_indexes, k=args.meta_batch)
+
+ raw_time_steps = meta_model.meta_timestamps[batch_indexes]
+
+ regularization_loss = F.l1_loss(
+ generated_time_embeds, meta_model.super_meta_embed, reduction="mean"
+ )
+ # future loss
+ total_future_losses, total_present_losses = [], []
+ future_containers = meta_model.gen_model(generated_time_embeds[batch_indexes])
+ present_containers = meta_model.gen_model(
+ meta_model.super_meta_embed[batch_indexes]
+ )
+ for ibatch, time_step in enumerate(raw_time_steps.cpu().tolist()):
+ _, (inputs, targets) = xenv(time_step)
+ inputs, targets = inputs.to(device), targets.to(device)
+
+ predictions = base_model.forward_with_container(
+ inputs, future_containers[ibatch]
+ )
+ total_future_losses.append(criterion(predictions, targets))
+
+ predictions = base_model.forward_with_container(
+ inputs, present_containers[ibatch]
+ )
+ total_present_losses.append(criterion(predictions, targets))
+
+ with torch.no_grad():
+ meta_std = torch.stack(total_future_losses).std().item()
+ loss_future = torch.stack(total_future_losses).mean()
+ loss_present = torch.stack(total_present_losses).mean()
+ total_loss = loss_future + loss_present + regularization_loss
+ total_loss.backward()
+ optimizer.step()
+ # success
+ success, best_score = meta_model.save_best(-total_loss.item())
+ logger.log(
+ "{:} [META {:04d}/{:}] loss : {:.4f} +- {:.4f} = {:.4f} + {:.4f} + {:.4f}".format(
+ time_string(),
+ iepoch,
+ args.epochs,
+ total_loss.item(),
+ meta_std,
+ loss_future.item(),
+ loss_present.item(),
+ regularization_loss.item(),
+ )
+ + ", batch={:}".format(len(total_future_losses))
+ + ", success={:}, best={:.4f}".format(success, -best_score)
+ + ", LS={:}/{:}".format(iepoch - last_success_epoch, early_stop_thresh)
+ + ", {:}".format(left_time)
+ )
+ if success:
+ last_success_epoch = iepoch
+ if iepoch - last_success_epoch >= early_stop_thresh:
+ logger.log("Early stop the pre-training at {:}".format(iepoch))
+ break
+ per_epoch_time.update(time.time() - start_time)
+ start_time = time.time()
+ meta_model.load_best()
+ # save to the final model
+ meta_model.set_best_name(final_best_name)
+ success, _ = meta_model.save_best(best_score + 1e-6)
+ assert success
+ logger.log("Save the best model into {:}".format(final_best_name))
+
+
+def main(args):
+ prepare_seed(args.rand_seed)
+ logger = prepare_logger(args)
+ train_env = get_synthetic_env(mode="train", version=args.env_version)
+ valid_env = get_synthetic_env(mode="valid", version=args.env_version)
+ trainval_env = get_synthetic_env(mode="trainval", version=args.env_version)
+ test_env = get_synthetic_env(mode="test", version=args.env_version)
+ all_env = get_synthetic_env(mode=None, version=args.env_version)
+ logger.log("The training enviornment: {:}".format(train_env))
+ logger.log("The validation enviornment: {:}".format(valid_env))
+ logger.log("The trainval enviornment: {:}".format(trainval_env))
+ logger.log("The total enviornment: {:}".format(all_env))
+ logger.log("The test enviornment: {:}".format(test_env))
+ model_kwargs = dict(
+ config=dict(model_type="norm_mlp"),
+ input_dim=all_env.meta_info["input_dim"],
+ output_dim=all_env.meta_info["output_dim"],
+ hidden_dims=[args.hidden_dim] * 2,
+ act_cls="relu",
+ norm_cls="layer_norm_1d",
+ )
+
+ base_model = get_model(**model_kwargs)
+ base_model = base_model.to(args.device)
+ if all_env.meta_info["task"] == "regression":
+ criterion = torch.nn.MSELoss()
+ metric = MSEMetric(True)
+ elif all_env.meta_info["task"] == "classification":
+ criterion = torch.nn.CrossEntropyLoss()
+ metric = Top1AccMetric(True)
+ else:
+ raise ValueError(
+ "This task ({:}) is not supported.".format(all_env.meta_info["task"])
+ )
+
+ shape_container = base_model.get_w_container().to_shape_container()
+
+ # pre-train the hypernetwork
+ timestamps = trainval_env.get_timestamp(None)
+ if args.ablation is None:
+ MetaModel_cls = MetaModelV1
+ elif args.ablation == "old":
+ MetaModel_cls = MetaModel_TraditionalAtt
+ else:
+ raise ValueError("Unknown ablation : {:}".format(args.ablation))
+ meta_model = MetaModel_cls(
+ shape_container,
+ args.layer_dim,
+ args.time_dim,
+ timestamps,
+ seq_length=args.seq_length,
+ interval=trainval_env.time_interval,
+ )
+ meta_model = meta_model.to(args.device)
+
+ logger.log("The base-model has {:} weights.".format(base_model.numel()))
+ logger.log("The meta-model has {:} weights.".format(meta_model.numel()))
+ logger.log("The base-model is\n{:}".format(base_model))
+ logger.log("The meta-model is\n{:}".format(meta_model))
+
+ meta_train_procedure(base_model, meta_model, criterion, trainval_env, args, logger)
+
+ # try to evaluate once
+ # online_evaluate(train_env, meta_model, base_model, criterion, args, logger)
+ # online_evaluate(valid_env, meta_model, base_model, criterion, args, logger)
+ """
+ w_containers, loss_meter = online_evaluate(
+ all_env, meta_model, base_model, criterion, args, logger, True
+ )
+ logger.log("In this enviornment, the total loss-meter is {:}".format(loss_meter))
+ """
+ w_containers_care_adapt, loss_adapt_v1, metric_adapt_v1 = online_evaluate(
+ test_env, meta_model, base_model, criterion, metric, args, logger, True, False
+ )
+ w_containers_easy_adapt, loss_adapt_v2, metric_adapt_v2 = online_evaluate(
+ test_env, meta_model, base_model, criterion, metric, args, logger, True, True
+ )
+ logger.log(
+ "[Refine-Adapt] loss = {:.6f}, metric = {:.6f}".format(
+ loss_adapt_v1, metric_adapt_v1
+ )
+ )
+ logger.log(
+ "[Easy-Adapt] loss = {:.6f}, metric = {:.6f}".format(
+ loss_adapt_v2, metric_adapt_v2
+ )
+ )
+
+ save_checkpoint(
+ {
+ "w_containers_care_adapt": w_containers_care_adapt,
+ "w_containers_easy_adapt": w_containers_easy_adapt,
+ "test_loss_adapt_v1": loss_adapt_v1,
+ "test_loss_adapt_v2": loss_adapt_v2,
+ "test_metric_adapt_v1": metric_adapt_v1,
+ "test_metric_adapt_v2": metric_adapt_v2,
+ },
+ logger.path(None) / "final-ckp-{:}.pth".format(args.rand_seed),
+ logger,
+ )
+
+ logger.log("-" * 200 + "\n")
+ logger.close()
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(".")
+ parser.add_argument(
+ "--save_dir",
+ type=str,
+ default="./outputs/GeMOSA-synthetic/GeMOSA",
+ help="The checkpoint directory.",
+ )
+ parser.add_argument(
+ "--env_version",
+ type=str,
+ required=True,
+ help="The synthetic enviornment version.",
+ )
+ parser.add_argument(
+ "--hidden_dim",
+ type=int,
+ default=16,
+ help="The hidden dimension.",
+ )
+ parser.add_argument(
+ "--layer_dim",
+ type=int,
+ default=16,
+ help="The layer chunk dimension.",
+ )
+ parser.add_argument(
+ "--time_dim",
+ type=int,
+ default=16,
+ help="The timestamp dimension.",
+ )
+ #####
+ parser.add_argument(
+ "--lr",
+ type=float,
+ default=0.002,
+ help="The initial learning rate for the optimizer (default is Adam)",
+ )
+ parser.add_argument(
+ "--weight_decay",
+ type=float,
+ default=0.00001,
+ help="The weight decay for the optimizer (default is Adam)",
+ )
+ parser.add_argument(
+ "--meta_batch",
+ type=int,
+ default=64,
+ help="The batch size for the meta-model",
+ )
+ parser.add_argument(
+ "--sampler_enlarge",
+ type=int,
+ default=5,
+ help="Enlarge the #iterations for an epoch",
+ )
+ parser.add_argument("--epochs", type=int, default=10000, help="The total #epochs.")
+ parser.add_argument(
+ "--refine_lr",
+ type=float,
+ default=0.001,
+ help="The learning rate for the optimizer, during refine",
+ )
+ parser.add_argument(
+ "--refine_epochs", type=int, default=150, help="The final refine #epochs."
+ )
+ parser.add_argument(
+ "--early_stop_thresh",
+ type=int,
+ default=20,
+ help="The #epochs for early stop.",
+ )
+ parser.add_argument(
+ "--pretrain_early_stop_thresh",
+ type=int,
+ default=300,
+ help="The #epochs for early stop.",
+ )
+ parser.add_argument(
+ "--seq_length", type=int, default=10, help="The sequence length."
+ )
+ parser.add_argument(
+ "--workers", type=int, default=4, help="The number of workers in parallel."
+ )
+ parser.add_argument(
+ "--ablation", type=str, default=None, help="The ablation indicator."
+ )
+ parser.add_argument(
+ "--device",
+ type=str,
+ default="cpu",
+ help="",
+ )
+ # Random Seed
+ parser.add_argument("--rand_seed", type=int, default=-1, help="manual seed")
+ args = parser.parse_args()
+ if args.rand_seed is None or args.rand_seed < 0:
+ args.rand_seed = random.randint(1, 100000)
+ assert args.save_dir is not None, "The save dir argument can not be None"
+ if args.ablation is None:
+ args.save_dir = "{:}-bs{:}-d{:}_{:}_{:}-s{:}-lr{:}-wd{:}-e{:}-env{:}".format(
+ args.save_dir,
+ args.meta_batch,
+ args.hidden_dim,
+ args.layer_dim,
+ args.time_dim,
+ args.seq_length,
+ args.lr,
+ args.weight_decay,
+ args.epochs,
+ args.env_version,
+ )
+ else:
+ args.save_dir = (
+ "{:}-bs{:}-d{:}_{:}_{:}-s{:}-lr{:}-wd{:}-e{:}-ab{:}-env{:}".format(
+ args.save_dir,
+ args.meta_batch,
+ args.hidden_dim,
+ args.layer_dim,
+ args.time_dim,
+ args.seq_length,
+ args.lr,
+ args.weight_decay,
+ args.epochs,
+ args.ablation,
+ args.env_version,
+ )
+ )
+ main(args)
diff --git a/AutoDL-Projects/exps/experimental/GeMOSA/meta_model.py b/AutoDL-Projects/exps/experimental/GeMOSA/meta_model.py
new file mode 100644
index 0000000..dd289d6
--- /dev/null
+++ b/AutoDL-Projects/exps/experimental/GeMOSA/meta_model.py
@@ -0,0 +1,257 @@
+import torch
+
+import torch.nn.functional as F
+
+from xautodl.xlayers import super_core
+from xautodl.xlayers import trunc_normal_
+from xautodl.xmodels.xcore import get_model
+
+
+class MetaModelV1(super_core.SuperModule):
+ """Learning to Generate Models One Step Ahead (Meta Model Design)."""
+
+ def __init__(
+ self,
+ shape_container,
+ layer_dim,
+ time_dim,
+ meta_timestamps,
+ dropout: float = 0.1,
+ seq_length: int = None,
+ interval: float = None,
+ thresh: float = None,
+ ):
+ super(MetaModelV1, self).__init__()
+ self._shape_container = shape_container
+ self._num_layers = len(shape_container)
+ self._numel_per_layer = []
+ for ilayer in range(self._num_layers):
+ self._numel_per_layer.append(shape_container[ilayer].numel())
+ self._raw_meta_timestamps = meta_timestamps
+ assert interval is not None
+ self._interval = interval
+ self._thresh = interval * seq_length if thresh is None else thresh
+
+ self.register_parameter(
+ "_super_layer_embed",
+ torch.nn.Parameter(torch.Tensor(self._num_layers, layer_dim)),
+ )
+ self.register_parameter(
+ "_super_meta_embed",
+ torch.nn.Parameter(torch.Tensor(len(meta_timestamps), time_dim)),
+ )
+ self.register_buffer("_meta_timestamps", torch.Tensor(meta_timestamps))
+ self._time_embed_dim = time_dim
+ self._append_meta_embed = dict(fixed=None, learnt=None)
+ self._append_meta_timestamps = dict(fixed=None, learnt=None)
+
+ self._tscalar_embed = super_core.SuperDynamicPositionE(
+ time_dim, scale=1 / interval
+ )
+
+ # build transformer
+ self._trans_att = super_core.SuperQKVAttentionV2(
+ qk_att_dim=time_dim,
+ in_v_dim=time_dim,
+ hidden_dim=time_dim,
+ num_heads=4,
+ proj_dim=time_dim,
+ qkv_bias=True,
+ attn_drop=None,
+ proj_drop=dropout,
+ )
+
+ model_kwargs = dict(
+ config=dict(model_type="dual_norm_mlp"),
+ input_dim=layer_dim + time_dim,
+ output_dim=max(self._numel_per_layer),
+ hidden_dims=[(layer_dim + time_dim) * 2] * 3,
+ act_cls="gelu",
+ norm_cls="layer_norm_1d",
+ dropout=dropout,
+ )
+ self._generator = get_model(**model_kwargs)
+
+ # initialization
+ trunc_normal_(
+ [self._super_layer_embed, self._super_meta_embed],
+ std=0.02,
+ )
+
+ def get_parameters(self, time_embed, attention, generator):
+ parameters = []
+ if time_embed:
+ parameters.append(self._super_meta_embed)
+ if attention:
+ parameters.extend(list(self._trans_att.parameters()))
+ if generator:
+ parameters.append(self._super_layer_embed)
+ parameters.extend(list(self._generator.parameters()))
+ return parameters
+
+ @property
+ def meta_timestamps(self):
+ with torch.no_grad():
+ meta_timestamps = [self._meta_timestamps]
+ for key in ("fixed", "learnt"):
+ if self._append_meta_timestamps[key] is not None:
+ meta_timestamps.append(self._append_meta_timestamps[key])
+ return torch.cat(meta_timestamps)
+
+ @property
+ def super_meta_embed(self):
+ meta_embed = [self._super_meta_embed]
+ for key in ("fixed", "learnt"):
+ if self._append_meta_embed[key] is not None:
+ meta_embed.append(self._append_meta_embed[key])
+ return torch.cat(meta_embed)
+
+ def create_meta_embed(self):
+ param = torch.Tensor(1, self._time_embed_dim)
+ trunc_normal_(param, std=0.02)
+ param = param.to(self._super_meta_embed.device)
+ param = torch.nn.Parameter(param, True)
+ return param
+
+ def get_closest_meta_distance(self, timestamp):
+ with torch.no_grad():
+ distances = torch.abs(self.meta_timestamps - timestamp)
+ return torch.min(distances).item()
+
+ def replace_append_learnt(self, timestamp, meta_embed):
+ self._append_meta_timestamps["learnt"] = timestamp
+ self._append_meta_embed["learnt"] = meta_embed
+
+ @property
+ def meta_length(self):
+ return self.meta_timestamps.numel()
+
+ def clear_fixed(self):
+ self._append_meta_timestamps["fixed"] = None
+ self._append_meta_embed["fixed"] = None
+
+ def clear_learnt(self):
+ self.replace_append_learnt(None, None)
+
+ def append_fixed(self, timestamp, meta_embed):
+ with torch.no_grad():
+ device = self._super_meta_embed.device
+ timestamp = timestamp.detach().clone().to(device)
+ meta_embed = meta_embed.detach().clone().to(device)
+ if self._append_meta_timestamps["fixed"] is None:
+ self._append_meta_timestamps["fixed"] = timestamp
+ else:
+ self._append_meta_timestamps["fixed"] = torch.cat(
+ (self._append_meta_timestamps["fixed"], timestamp), dim=0
+ )
+ if self._append_meta_embed["fixed"] is None:
+ self._append_meta_embed["fixed"] = meta_embed
+ else:
+ self._append_meta_embed["fixed"] = torch.cat(
+ (self._append_meta_embed["fixed"], meta_embed), dim=0
+ )
+
+ def gen_time_embed(self, timestamps):
+ # timestamps is a batch of timestamps
+ [B] = timestamps.shape
+ # batch, seq = timestamps.shape
+ timestamps = timestamps.view(-1, 1)
+ meta_timestamps, meta_embeds = self.meta_timestamps, self.super_meta_embed
+ timestamp_v_embed = meta_embeds.unsqueeze(dim=0)
+ timestamp_qk_att_embed = self._tscalar_embed(
+ torch.unsqueeze(timestamps, dim=-1) - meta_timestamps
+ )
+ # create the mask
+ mask = (
+ torch.unsqueeze(timestamps, dim=-1) <= meta_timestamps.view(1, 1, -1)
+ ) | (
+ torch.abs(
+ torch.unsqueeze(timestamps, dim=-1) - meta_timestamps.view(1, 1, -1)
+ )
+ > self._thresh
+ )
+ timestamp_embeds = self._trans_att(
+ timestamp_qk_att_embed,
+ timestamp_v_embed,
+ mask,
+ )
+ return timestamp_embeds[:, -1, :]
+
+ def gen_model(self, time_embeds):
+ B, _ = time_embeds.shape
+ # create joint embed
+ num_layer, _ = self._super_layer_embed.shape
+ # The shape of `joint_embed` is batch * num-layers * input-dim
+ joint_embeds = torch.cat(
+ (
+ time_embeds.view(B, 1, -1).expand(-1, num_layer, -1),
+ self._super_layer_embed.view(1, num_layer, -1).expand(B, -1, -1),
+ ),
+ dim=-1,
+ )
+ batch_weights = self._generator(joint_embeds)
+ batch_containers = []
+ for weights in torch.split(batch_weights, 1):
+ batch_containers.append(
+ self._shape_container.translate(torch.split(weights.squeeze(0), 1))
+ )
+ return batch_containers
+
+ def forward_raw(self, timestamps, time_embeds, tembed_only=False):
+ raise NotImplementedError
+
+ def forward_candidate(self, input):
+ raise NotImplementedError
+
+ def easy_adapt(self, timestamp, time_embed):
+ with torch.no_grad():
+ timestamp = torch.Tensor([timestamp]).to(self._meta_timestamps.device)
+ self.replace_append_learnt(None, None)
+ self.append_fixed(timestamp, time_embed)
+
+ def adapt(self, base_model, criterion, timestamp, x, y, lr, epochs, init_info):
+ distance = self.get_closest_meta_distance(timestamp)
+ if distance + self._interval * 1e-2 <= self._interval:
+ return False, None
+ x, y = x.to(self._meta_timestamps.device), y.to(self._meta_timestamps.device)
+ with torch.set_grad_enabled(True):
+ new_param = self.create_meta_embed()
+
+ optimizer = torch.optim.Adam(
+ [new_param], lr=lr, weight_decay=1e-5, amsgrad=True
+ )
+ timestamp = torch.Tensor([timestamp]).to(new_param.device)
+ self.replace_append_learnt(timestamp, new_param)
+ self.train()
+ base_model.train()
+ if init_info is not None:
+ best_loss = init_info["loss"]
+ new_param.data.copy_(init_info["param"].data)
+ else:
+ best_loss = 1e9
+ with torch.no_grad():
+ best_new_param = new_param.detach().clone()
+ for iepoch in range(epochs):
+ optimizer.zero_grad()
+ time_embed = self.gen_time_embed(timestamp.view(1))
+ match_loss = F.l1_loss(new_param, time_embed)
+
+ [container] = self.gen_model(new_param.view(1, -1))
+ y_hat = base_model.forward_with_container(x, container)
+ meta_loss = criterion(y_hat, y)
+ loss = meta_loss + match_loss
+ loss.backward()
+ optimizer.step()
+ if meta_loss.item() < best_loss:
+ with torch.no_grad():
+ best_loss = meta_loss.item()
+ best_new_param = new_param.detach().clone()
+ self.easy_adapt(timestamp, best_new_param)
+ return True, best_loss
+
+ def extra_repr(self) -> str:
+ return "(_super_layer_embed): {:}, (_super_meta_embed): {:}, (_meta_timestamps): {:}".format(
+ list(self._super_layer_embed.shape),
+ list(self._super_meta_embed.shape),
+ list(self._meta_timestamps.shape),
+ )
diff --git a/AutoDL-Projects/exps/experimental/GeMOSA/meta_model_ablation.py b/AutoDL-Projects/exps/experimental/GeMOSA/meta_model_ablation.py
new file mode 100644
index 0000000..f2e856a
--- /dev/null
+++ b/AutoDL-Projects/exps/experimental/GeMOSA/meta_model_ablation.py
@@ -0,0 +1,260 @@
+#
+# This is used for the ablation studies:
+# The meta-model in this file uses the traditional attention in
+# transformer.
+#
+import torch
+
+import torch.nn.functional as F
+
+from xautodl.xlayers import super_core
+from xautodl.xlayers import trunc_normal_
+from xautodl.models.xcore import get_model
+
+
+class MetaModel_TraditionalAtt(super_core.SuperModule):
+ """Learning to Generate Models One Step Ahead (Meta Model Design)."""
+
+ def __init__(
+ self,
+ shape_container,
+ layer_dim,
+ time_dim,
+ meta_timestamps,
+ dropout: float = 0.1,
+ seq_length: int = None,
+ interval: float = None,
+ thresh: float = None,
+ ):
+ super(MetaModel_TraditionalAtt, self).__init__()
+ self._shape_container = shape_container
+ self._num_layers = len(shape_container)
+ self._numel_per_layer = []
+ for ilayer in range(self._num_layers):
+ self._numel_per_layer.append(shape_container[ilayer].numel())
+ self._raw_meta_timestamps = meta_timestamps
+ assert interval is not None
+ self._interval = interval
+ self._thresh = interval * seq_length if thresh is None else thresh
+
+ self.register_parameter(
+ "_super_layer_embed",
+ torch.nn.Parameter(torch.Tensor(self._num_layers, layer_dim)),
+ )
+ self.register_parameter(
+ "_super_meta_embed",
+ torch.nn.Parameter(torch.Tensor(len(meta_timestamps), time_dim)),
+ )
+ self.register_buffer("_meta_timestamps", torch.Tensor(meta_timestamps))
+ self._time_embed_dim = time_dim
+ self._append_meta_embed = dict(fixed=None, learnt=None)
+ self._append_meta_timestamps = dict(fixed=None, learnt=None)
+
+ self._tscalar_embed = super_core.SuperDynamicPositionE(
+ time_dim, scale=1 / interval
+ )
+
+ # build transformer
+ self._trans_att = super_core.SuperQKVAttention(
+ in_q_dim=time_dim,
+ in_k_dim=time_dim,
+ in_v_dim=time_dim,
+ num_heads=4,
+ proj_dim=time_dim,
+ qkv_bias=True,
+ attn_drop=None,
+ proj_drop=dropout,
+ )
+
+ model_kwargs = dict(
+ config=dict(model_type="dual_norm_mlp"),
+ input_dim=layer_dim + time_dim,
+ output_dim=max(self._numel_per_layer),
+ hidden_dims=[(layer_dim + time_dim) * 2] * 3,
+ act_cls="gelu",
+ norm_cls="layer_norm_1d",
+ dropout=dropout,
+ )
+ self._generator = get_model(**model_kwargs)
+
+ # initialization
+ trunc_normal_(
+ [self._super_layer_embed, self._super_meta_embed],
+ std=0.02,
+ )
+
+ def get_parameters(self, time_embed, attention, generator):
+ parameters = []
+ if time_embed:
+ parameters.append(self._super_meta_embed)
+ if attention:
+ parameters.extend(list(self._trans_att.parameters()))
+ if generator:
+ parameters.append(self._super_layer_embed)
+ parameters.extend(list(self._generator.parameters()))
+ return parameters
+
+ @property
+ def meta_timestamps(self):
+ with torch.no_grad():
+ meta_timestamps = [self._meta_timestamps]
+ for key in ("fixed", "learnt"):
+ if self._append_meta_timestamps[key] is not None:
+ meta_timestamps.append(self._append_meta_timestamps[key])
+ return torch.cat(meta_timestamps)
+
+ @property
+ def super_meta_embed(self):
+ meta_embed = [self._super_meta_embed]
+ for key in ("fixed", "learnt"):
+ if self._append_meta_embed[key] is not None:
+ meta_embed.append(self._append_meta_embed[key])
+ return torch.cat(meta_embed)
+
+ def create_meta_embed(self):
+ param = torch.Tensor(1, self._time_embed_dim)
+ trunc_normal_(param, std=0.02)
+ param = param.to(self._super_meta_embed.device)
+ param = torch.nn.Parameter(param, True)
+ return param
+
+ def get_closest_meta_distance(self, timestamp):
+ with torch.no_grad():
+ distances = torch.abs(self.meta_timestamps - timestamp)
+ return torch.min(distances).item()
+
+ def replace_append_learnt(self, timestamp, meta_embed):
+ self._append_meta_timestamps["learnt"] = timestamp
+ self._append_meta_embed["learnt"] = meta_embed
+
+ @property
+ def meta_length(self):
+ return self.meta_timestamps.numel()
+
+ def clear_fixed(self):
+ self._append_meta_timestamps["fixed"] = None
+ self._append_meta_embed["fixed"] = None
+
+ def clear_learnt(self):
+ self.replace_append_learnt(None, None)
+
+ def append_fixed(self, timestamp, meta_embed):
+ with torch.no_grad():
+ device = self._super_meta_embed.device
+ timestamp = timestamp.detach().clone().to(device)
+ meta_embed = meta_embed.detach().clone().to(device)
+ if self._append_meta_timestamps["fixed"] is None:
+ self._append_meta_timestamps["fixed"] = timestamp
+ else:
+ self._append_meta_timestamps["fixed"] = torch.cat(
+ (self._append_meta_timestamps["fixed"], timestamp), dim=0
+ )
+ if self._append_meta_embed["fixed"] is None:
+ self._append_meta_embed["fixed"] = meta_embed
+ else:
+ self._append_meta_embed["fixed"] = torch.cat(
+ (self._append_meta_embed["fixed"], meta_embed), dim=0
+ )
+
+ def gen_time_embed(self, timestamps):
+ # timestamps is a batch of timestamps
+ [B] = timestamps.shape
+ # batch, seq = timestamps.shape
+ timestamps = timestamps.view(-1, 1)
+ meta_timestamps, meta_embeds = self.meta_timestamps, self.super_meta_embed
+ timestamp_v_embed = meta_embeds.unsqueeze(dim=0)
+ timestamp_q_embed = self._tscalar_embed(timestamps)
+ timestamp_k_embed = self._tscalar_embed(meta_timestamps.view(1, -1))
+
+ # create the mask
+ mask = (
+ torch.unsqueeze(timestamps, dim=-1) <= meta_timestamps.view(1, 1, -1)
+ ) | (
+ torch.abs(
+ torch.unsqueeze(timestamps, dim=-1) - meta_timestamps.view(1, 1, -1)
+ )
+ > self._thresh
+ )
+ timestamp_embeds = self._trans_att(
+ timestamp_q_embed, timestamp_k_embed, timestamp_v_embed, mask
+ )
+ return timestamp_embeds[:, -1, :]
+
+ def gen_model(self, time_embeds):
+ B, _ = time_embeds.shape
+ # create joint embed
+ num_layer, _ = self._super_layer_embed.shape
+ # The shape of `joint_embed` is batch * num-layers * input-dim
+ joint_embeds = torch.cat(
+ (
+ time_embeds.view(B, 1, -1).expand(-1, num_layer, -1),
+ self._super_layer_embed.view(1, num_layer, -1).expand(B, -1, -1),
+ ),
+ dim=-1,
+ )
+ batch_weights = self._generator(joint_embeds)
+ batch_containers = []
+ for weights in torch.split(batch_weights, 1):
+ batch_containers.append(
+ self._shape_container.translate(torch.split(weights.squeeze(0), 1))
+ )
+ return batch_containers
+
+ def forward_raw(self, timestamps, time_embeds, tembed_only=False):
+ raise NotImplementedError
+
+ def forward_candidate(self, input):
+ raise NotImplementedError
+
+ def easy_adapt(self, timestamp, time_embed):
+ with torch.no_grad():
+ timestamp = torch.Tensor([timestamp]).to(self._meta_timestamps.device)
+ self.replace_append_learnt(None, None)
+ self.append_fixed(timestamp, time_embed)
+
+ def adapt(self, base_model, criterion, timestamp, x, y, lr, epochs, init_info):
+ distance = self.get_closest_meta_distance(timestamp)
+ if distance + self._interval * 1e-2 <= self._interval:
+ return False, None
+ x, y = x.to(self._meta_timestamps.device), y.to(self._meta_timestamps.device)
+ with torch.set_grad_enabled(True):
+ new_param = self.create_meta_embed()
+
+ optimizer = torch.optim.Adam(
+ [new_param], lr=lr, weight_decay=1e-5, amsgrad=True
+ )
+ timestamp = torch.Tensor([timestamp]).to(new_param.device)
+ self.replace_append_learnt(timestamp, new_param)
+ self.train()
+ base_model.train()
+ if init_info is not None:
+ best_loss = init_info["loss"]
+ new_param.data.copy_(init_info["param"].data)
+ else:
+ best_loss = 1e9
+ with torch.no_grad():
+ best_new_param = new_param.detach().clone()
+ for iepoch in range(epochs):
+ optimizer.zero_grad()
+ time_embed = self.gen_time_embed(timestamp.view(1))
+ match_loss = F.l1_loss(new_param, time_embed)
+
+ [container] = self.gen_model(new_param.view(1, -1))
+ y_hat = base_model.forward_with_container(x, container)
+ meta_loss = criterion(y_hat, y)
+ loss = meta_loss + match_loss
+ loss.backward()
+ optimizer.step()
+ if meta_loss.item() < best_loss:
+ with torch.no_grad():
+ best_loss = meta_loss.item()
+ best_new_param = new_param.detach().clone()
+ self.easy_adapt(timestamp, best_new_param)
+ return True, best_loss
+
+ def extra_repr(self) -> str:
+ return "(_super_layer_embed): {:}, (_super_meta_embed): {:}, (_meta_timestamps): {:}".format(
+ list(self._super_layer_embed.shape),
+ list(self._super_meta_embed.shape),
+ list(self._meta_timestamps.shape),
+ )
diff --git a/AutoDL-Projects/exps/experimental/GeMOSA/vis-synthetic.py b/AutoDL-Projects/exps/experimental/GeMOSA/vis-synthetic.py
new file mode 100644
index 0000000..a6f61fe
--- /dev/null
+++ b/AutoDL-Projects/exps/experimental/GeMOSA/vis-synthetic.py
@@ -0,0 +1,441 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.02 #
+############################################################################
+# python exps/GeMOSA/vis-synthetic.py --env_version v1 #
+# python exps/GeMOSA/vis-synthetic.py --env_version v2 #
+# python exps/GeMOSA/vis-synthetic.py --env_version v3 #
+# python exps/GeMOSA/vis-synthetic.py --env_version v4 #
+############################################################################
+import os, sys, copy, random
+import torch
+import numpy as np
+import argparse
+from collections import OrderedDict, defaultdict
+from pathlib import Path
+from tqdm import tqdm
+from pprint import pprint
+
+import matplotlib
+from matplotlib import cm
+
+matplotlib.use("agg")
+import matplotlib.pyplot as plt
+import matplotlib.ticker as ticker
+
+lib_dir = (Path(__file__).parent / ".." / "..").resolve()
+if str(lib_dir) not in sys.path:
+ sys.path.insert(0, str(lib_dir))
+
+from xautodl.models.xcore import get_model
+from xautodl.datasets.synthetic_core import get_synthetic_env
+from xautodl.procedures.metric_utils import MSEMetric
+
+
+def plot_scatter(cur_ax, xs, ys, color, alpha, linewidths, label=None):
+ cur_ax.scatter([-100], [-100], color=color, linewidths=linewidths[0], label=label)
+ cur_ax.scatter(
+ xs, ys, color=color, alpha=alpha, linewidths=linewidths[1], label=None
+ )
+
+
+def draw_multi_fig(save_dir, timestamp, scatter_list, wh, fig_title=None):
+ save_path = save_dir / "{:04d}".format(timestamp)
+ # print('Plot the figure at timestamp-{:} into {:}'.format(timestamp, save_path))
+ dpi, width, height = 40, wh[0], wh[1]
+ figsize = width / float(dpi), height / float(dpi)
+ LabelSize, LegendFontsize, font_gap = 80, 80, 5
+
+ fig = plt.figure(figsize=figsize)
+ if fig_title is not None:
+ fig.suptitle(
+ fig_title, fontsize=LegendFontsize, fontweight="bold", x=0.5, y=0.92
+ )
+
+ for idx, scatter_dict in enumerate(scatter_list):
+ cur_ax = fig.add_subplot(len(scatter_list), 1, idx + 1)
+ plot_scatter(
+ cur_ax,
+ scatter_dict["xaxis"],
+ scatter_dict["yaxis"],
+ scatter_dict["color"],
+ scatter_dict["alpha"],
+ scatter_dict["linewidths"],
+ scatter_dict["label"],
+ )
+ cur_ax.set_xlabel("X", fontsize=LabelSize)
+ cur_ax.set_ylabel("Y", rotation=0, fontsize=LabelSize)
+ cur_ax.set_xlim(scatter_dict["xlim"][0], scatter_dict["xlim"][1])
+ cur_ax.set_ylim(scatter_dict["ylim"][0], scatter_dict["ylim"][1])
+ for tick in cur_ax.xaxis.get_major_ticks():
+ tick.label.set_fontsize(LabelSize - font_gap)
+ tick.label.set_rotation(10)
+ for tick in cur_ax.yaxis.get_major_ticks():
+ tick.label.set_fontsize(LabelSize - font_gap)
+ cur_ax.legend(loc=1, fontsize=LegendFontsize)
+ fig.savefig(str(save_path) + ".pdf", dpi=dpi, bbox_inches="tight", format="pdf")
+ fig.savefig(str(save_path) + ".png", dpi=dpi, bbox_inches="tight", format="png")
+ plt.close("all")
+
+
+def find_min(cur, others):
+ if cur is None:
+ return float(others)
+ else:
+ return float(min(cur, others))
+
+
+def find_max(cur, others):
+ if cur is None:
+ return float(others.max())
+ else:
+ return float(max(cur, others))
+
+
+def compare_cl(save_dir):
+ save_dir = Path(str(save_dir))
+ save_dir.mkdir(parents=True, exist_ok=True)
+ dynamic_env, cl_function = create_example_v1(
+ # timestamp_config=dict(num=200, min_timestamp=-1, max_timestamp=1.0),
+ timestamp_config=dict(num=200),
+ num_per_task=1000,
+ )
+
+ models = dict()
+
+ cl_function.set_timestamp(0)
+ cl_xaxis_min = None
+ cl_xaxis_max = None
+
+ all_data = OrderedDict()
+
+ for idx, (timestamp, dataset) in enumerate(tqdm(dynamic_env, ncols=50)):
+ xaxis_all = dataset[0][:, 0].numpy()
+ yaxis_all = dataset[1][:, 0].numpy()
+ current_data = dict()
+ current_data["lfna_xaxis_all"] = xaxis_all
+ current_data["lfna_yaxis_all"] = yaxis_all
+
+ # compute cl-min
+ cl_xaxis_min = find_min(cl_xaxis_min, xaxis_all.mean() - xaxis_all.std())
+ cl_xaxis_max = find_max(cl_xaxis_max, xaxis_all.mean() + xaxis_all.std())
+ all_data[timestamp] = current_data
+
+ global_cl_xaxis_all = np.arange(cl_xaxis_min, cl_xaxis_max, step=0.1)
+ global_cl_yaxis_all = cl_function.noise_call(global_cl_xaxis_all)
+
+ for idx, (timestamp, xdata) in enumerate(tqdm(all_data.items(), ncols=50)):
+ scatter_list = []
+ scatter_list.append(
+ {
+ "xaxis": xdata["lfna_xaxis_all"],
+ "yaxis": xdata["lfna_yaxis_all"],
+ "color": "k",
+ "linewidths": 15,
+ "alpha": 0.99,
+ "xlim": (-6, 6),
+ "ylim": (-40, 40),
+ "label": "LFNA",
+ }
+ )
+
+ cur_cl_xaxis_min = cl_xaxis_min
+ cur_cl_xaxis_max = cl_xaxis_min + (cl_xaxis_max - cl_xaxis_min) * (
+ idx + 1
+ ) / len(all_data)
+ cl_xaxis_all = np.arange(cur_cl_xaxis_min, cur_cl_xaxis_max, step=0.01)
+ cl_yaxis_all = cl_function.noise_call(cl_xaxis_all, std=0.2)
+
+ scatter_list.append(
+ {
+ "xaxis": cl_xaxis_all,
+ "yaxis": cl_yaxis_all,
+ "color": "k",
+ "linewidths": 15,
+ "xlim": (round(cl_xaxis_min, 1), round(cl_xaxis_max, 1)),
+ "ylim": (-20, 6),
+ "alpha": 0.99,
+ "label": "Continual Learning",
+ }
+ )
+
+ draw_multi_fig(
+ save_dir,
+ idx,
+ scatter_list,
+ wh=(2200, 1800),
+ fig_title="Timestamp={:03d}".format(idx),
+ )
+ print("Save all figures into {:}".format(save_dir))
+ save_dir = save_dir.resolve()
+ base_cmd = (
+ "ffmpeg -y -i {xdir}/%04d.png -vf fps=1 -vf scale=2200:1800 -vb 5000k".format(
+ xdir=save_dir
+ )
+ )
+ video_cmd = "{:} -pix_fmt yuv420p {xdir}/compare-cl.mp4".format(
+ base_cmd, xdir=save_dir
+ )
+ print(video_cmd + "\n")
+ os.system(video_cmd)
+ os.system(
+ "{:} -pix_fmt yuv420p {xdir}/compare-cl.webm".format(base_cmd, xdir=save_dir)
+ )
+
+
+def visualize_env(save_dir, version):
+ save_dir = Path(str(save_dir))
+ for substr in ("pdf", "png"):
+ sub_save_dir = save_dir / "{:}-{:}".format(substr, version)
+ sub_save_dir.mkdir(parents=True, exist_ok=True)
+
+ dynamic_env = get_synthetic_env(version=version)
+ print("env: {:}".format(dynamic_env))
+ print("oracle_map: {:}".format(dynamic_env.oracle_map))
+ allxs, allys = [], []
+ for idx, (timestamp, (allx, ally)) in enumerate(tqdm(dynamic_env, ncols=50)):
+ allxs.append(allx)
+ allys.append(ally)
+ if dynamic_env.meta_info["task"] == "regression":
+ allxs, allys = torch.cat(allxs).view(-1), torch.cat(allys).view(-1)
+ print(
+ "x - min={:.3f}, max={:.3f}".format(allxs.min().item(), allxs.max().item())
+ )
+ print(
+ "y - min={:.3f}, max={:.3f}".format(allys.min().item(), allys.max().item())
+ )
+ elif dynamic_env.meta_info["task"] == "classification":
+ allxs = torch.cat(allxs)
+ print(
+ "x[0] - min={:.3f}, max={:.3f}".format(
+ allxs[:, 0].min().item(), allxs[:, 0].max().item()
+ )
+ )
+ print(
+ "x[1] - min={:.3f}, max={:.3f}".format(
+ allxs[:, 1].min().item(), allxs[:, 1].max().item()
+ )
+ )
+ else:
+ raise ValueError("Unknown task".format(dynamic_env.meta_info["task"]))
+
+ for idx, (timestamp, (allx, ally)) in enumerate(tqdm(dynamic_env, ncols=50)):
+ dpi, width, height = 30, 1800, 1400
+ figsize = width / float(dpi), height / float(dpi)
+ LabelSize, LegendFontsize, font_gap = 80, 80, 5
+ fig = plt.figure(figsize=figsize)
+
+ cur_ax = fig.add_subplot(1, 1, 1)
+ if dynamic_env.meta_info["task"] == "regression":
+ allx, ally = allx[:, 0].numpy(), ally[:, 0].numpy()
+ plot_scatter(
+ cur_ax, allx, ally, "k", 0.99, (15, 1.5), "timestamp={:05d}".format(idx)
+ )
+ cur_ax.set_xlim(round(allxs.min().item(), 1), round(allxs.max().item(), 1))
+ cur_ax.set_ylim(round(allys.min().item(), 1), round(allys.max().item(), 1))
+ elif dynamic_env.meta_info["task"] == "classification":
+ positive, negative = ally == 1, ally == 0
+ # plot_scatter(cur_ax, [1], [1], "k", 0.1, 1, "timestamp={:05d}".format(idx))
+ plot_scatter(
+ cur_ax,
+ allx[positive, 0],
+ allx[positive, 1],
+ "r",
+ 0.99,
+ (20, 10),
+ "positive",
+ )
+ plot_scatter(
+ cur_ax,
+ allx[negative, 0],
+ allx[negative, 1],
+ "g",
+ 0.99,
+ (20, 10),
+ "negative",
+ )
+ cur_ax.set_xlim(
+ round(allxs[:, 0].min().item(), 1), round(allxs[:, 0].max().item(), 1)
+ )
+ cur_ax.set_ylim(
+ round(allxs[:, 1].min().item(), 1), round(allxs[:, 1].max().item(), 1)
+ )
+ else:
+ raise ValueError("Unknown task".format(dynamic_env.meta_info["task"]))
+
+ cur_ax.set_xlabel("X", fontsize=LabelSize)
+ cur_ax.set_ylabel("Y", rotation=0, fontsize=LabelSize)
+ for tick in cur_ax.xaxis.get_major_ticks():
+ tick.label.set_fontsize(LabelSize - font_gap)
+ tick.label.set_rotation(10)
+ for tick in cur_ax.yaxis.get_major_ticks():
+ tick.label.set_fontsize(LabelSize - font_gap)
+ cur_ax.legend(loc=1, fontsize=LegendFontsize)
+ pdf_save_path = (
+ save_dir
+ / "pdf-{:}".format(version)
+ / "v{:}-{:05d}.pdf".format(version, idx)
+ )
+ fig.savefig(str(pdf_save_path), dpi=dpi, bbox_inches="tight", format="pdf")
+ png_save_path = (
+ save_dir
+ / "png-{:}".format(version)
+ / "v{:}-{:05d}.png".format(version, idx)
+ )
+ fig.savefig(str(png_save_path), dpi=dpi, bbox_inches="tight", format="png")
+ plt.close("all")
+ save_dir = save_dir.resolve()
+ base_cmd = "ffmpeg -y -i {xdir}/v{version}-%05d.png -vf scale=1800:1400 -pix_fmt yuv420p -vb 5000k".format(
+ xdir=save_dir / "png-{:}".format(version), version=version
+ )
+ print(base_cmd)
+ os.system("{:} {xdir}/env-{ver}.mp4".format(base_cmd, xdir=save_dir, ver=version))
+ os.system("{:} {xdir}/env-{ver}.webm".format(base_cmd, xdir=save_dir, ver=version))
+
+
+def compare_algs(save_dir, version, alg_dir="./outputs/GeMOSA-synthetic"):
+ save_dir = Path(str(save_dir))
+ for substr in ("pdf", "png"):
+ sub_save_dir = save_dir / substr
+ sub_save_dir.mkdir(parents=True, exist_ok=True)
+
+ dpi, width, height = 30, 3200, 2000
+ figsize = width / float(dpi), height / float(dpi)
+ LabelSize, LegendFontsize, font_gap = 80, 80, 5
+
+ dynamic_env = get_synthetic_env(mode=None, version=version)
+ allxs, allys = [], []
+ for idx, (timestamp, (allx, ally)) in enumerate(tqdm(dynamic_env, ncols=50)):
+ allxs.append(allx)
+ allys.append(ally)
+ allxs, allys = torch.cat(allxs).view(-1), torch.cat(allys).view(-1)
+
+ alg_name2dir = OrderedDict()
+ # alg_name2dir["Supervised Learning (History Data)"] = "use-all-past-data"
+ # alg_name2dir["MAML"] = "use-maml-s1"
+ # alg_name2dir["LFNA (fix init)"] = "lfna-fix-init"
+ if version == "v1":
+ # alg_name2dir["Optimal"] = "use-same-timestamp"
+ alg_name2dir[
+ "GMOA"
+ ] = "lfna-battle-bs128-d16_16_16-s16-lr0.002-wd1e-05-e10000-envv1"
+ else:
+ raise ValueError("Invalid version: {:}".format(version))
+ alg_name2all_containers = OrderedDict()
+ for idx_alg, (alg, xdir) in enumerate(alg_name2dir.items()):
+ ckp_path = Path(alg_dir) / str(xdir) / "final-ckp.pth"
+ xdata = torch.load(ckp_path, map_location="cpu")
+ alg_name2all_containers[alg] = xdata["w_containers"]
+ # load the basic model
+ model = get_model(
+ dict(model_type="norm_mlp"),
+ input_dim=1,
+ output_dim=1,
+ hidden_dims=[16] * 2,
+ act_cls="gelu",
+ norm_cls="layer_norm_1d",
+ )
+
+ alg2xs, alg2ys = defaultdict(list), defaultdict(list)
+ colors = ["r", "g", "b", "m", "y"]
+
+ linewidths, skip = 10, 5
+ for idx, (timestamp, (ori_allx, ori_ally)) in enumerate(
+ tqdm(dynamic_env, ncols=50)
+ ):
+ if idx <= skip:
+ continue
+ fig = plt.figure(figsize=figsize)
+ cur_ax = fig.add_subplot(2, 1, 1)
+
+ # the data
+ allx, ally = ori_allx[:, 0].numpy(), ori_ally[:, 0].numpy()
+ plot_scatter(cur_ax, allx, ally, "k", 0.99, linewidths, "Raw Data")
+
+ for idx_alg, (alg, xdir) in enumerate(alg_name2dir.items()):
+ with torch.no_grad():
+ predicts = model.forward_with_container(
+ ori_allx, alg_name2all_containers[alg][idx]
+ )
+ predicts = predicts.cpu()
+ # keep data
+ metric = MSEMetric()
+ metric(predicts, ori_ally)
+ predicts = predicts.view(-1).numpy()
+ alg2xs[alg].append(idx)
+ alg2ys[alg].append(metric.get_info()["mse"])
+ plot_scatter(cur_ax, allx, predicts, colors[idx_alg], 0.99, linewidths, alg)
+
+ cur_ax.set_xlabel("X", fontsize=LabelSize)
+ cur_ax.set_ylabel("Y", rotation=0, fontsize=LabelSize)
+ for tick in cur_ax.xaxis.get_major_ticks():
+ tick.label.set_fontsize(LabelSize - font_gap)
+ tick.label.set_rotation(10)
+ for tick in cur_ax.yaxis.get_major_ticks():
+ tick.label.set_fontsize(LabelSize - font_gap)
+ cur_ax.set_xlim(round(allxs.min().item(), 1), round(allxs.max().item(), 1))
+ cur_ax.set_ylim(round(allys.min().item(), 1), round(allys.max().item(), 1))
+ cur_ax.legend(loc=1, fontsize=LegendFontsize)
+
+ # the trajectory data
+ cur_ax = fig.add_subplot(2, 1, 2)
+ for idx_alg, (alg, xdir) in enumerate(alg_name2dir.items()):
+ # plot_scatter(cur_ax, alg2xs[alg], alg2ys[alg], olors[idx_alg], 0.99, linewidths, alg)
+ cur_ax.plot(
+ alg2xs[alg],
+ alg2ys[alg],
+ color=colors[idx_alg],
+ linestyle="-",
+ linewidth=5,
+ label=alg,
+ )
+ cur_ax.legend(loc=1, fontsize=LegendFontsize)
+
+ cur_ax.set_xlabel("Timestamp", fontsize=LabelSize)
+ cur_ax.set_ylabel("MSE", fontsize=LabelSize)
+ for tick in cur_ax.xaxis.get_major_ticks():
+ tick.label.set_fontsize(LabelSize - font_gap)
+ tick.label.set_rotation(10)
+ for tick in cur_ax.yaxis.get_major_ticks():
+ tick.label.set_fontsize(LabelSize - font_gap)
+ cur_ax.set_xlim(1, len(dynamic_env))
+ cur_ax.set_ylim(0, 10)
+ cur_ax.legend(loc=1, fontsize=LegendFontsize)
+
+ pdf_save_path = save_dir / "pdf" / "v{:}-{:05d}.pdf".format(version, idx - skip)
+ fig.savefig(str(pdf_save_path), dpi=dpi, bbox_inches="tight", format="pdf")
+ png_save_path = save_dir / "png" / "v{:}-{:05d}.png".format(version, idx - skip)
+ fig.savefig(str(png_save_path), dpi=dpi, bbox_inches="tight", format="png")
+ plt.close("all")
+ save_dir = save_dir.resolve()
+ base_cmd = "ffmpeg -y -i {xdir}/v{ver}-%05d.png -vf scale={w}:{h} -pix_fmt yuv420p -vb 5000k".format(
+ xdir=save_dir / "png", w=width, h=height, ver=version
+ )
+ os.system(
+ "{:} {xdir}/com-alg-{ver}.mp4".format(base_cmd, xdir=save_dir, ver=version)
+ )
+ os.system(
+ "{:} {xdir}/com-alg-{ver}.webm".format(base_cmd, xdir=save_dir, ver=version)
+ )
+
+
+if __name__ == "__main__":
+
+ parser = argparse.ArgumentParser("Visualize synthetic data.")
+ parser.add_argument(
+ "--save_dir",
+ type=str,
+ default="./outputs/vis-synthetic",
+ help="The save directory.",
+ )
+ parser.add_argument(
+ "--env_version",
+ type=str,
+ required=True,
+ help="The synthetic enviornment version.",
+ )
+ args = parser.parse_args()
+
+ visualize_env(os.path.join(args.save_dir, "vis-env"), args.env_version)
+ # visualize_env(os.path.join(args.save_dir, "vis-env"), "v2")
+ # compare_algs(os.path.join(args.save_dir, "compare-alg"), args.env_version)
+ # compare_cl(os.path.join(args.save_dir, "compare-cl"))
diff --git a/AutoDL-Projects/exps/experimental/example-nas-bench.py b/AutoDL-Projects/exps/experimental/example-nas-bench.py
new file mode 100644
index 0000000..aae09ab
--- /dev/null
+++ b/AutoDL-Projects/exps/experimental/example-nas-bench.py
@@ -0,0 +1,66 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.08 #
+###########################################################################################################################################################
+# Before run these commands, the files must be properly put.
+#
+# python exps/experimental/example-nas-bench.py --api_path $HOME/.torch/NAS-Bench-201-v1_1-096897.pth --archive_path $HOME/.torch/NAS-Bench-201-v1_1-archive
+###########################################################################################################################################################
+import os, gc, sys, math, argparse, psutil
+import numpy as np
+import torch
+from pathlib import Path
+from collections import OrderedDict
+import matplotlib
+import seaborn as sns
+
+matplotlib.use("agg")
+import matplotlib.pyplot as plt
+
+lib_dir = (Path(__file__).parent / ".." / ".." / "lib").resolve()
+if str(lib_dir) not in sys.path:
+ sys.path.insert(0, str(lib_dir))
+from nas_201_api import NASBench201API
+from log_utils import time_string
+from models import get_cell_based_tiny_net
+from utils import weight_watcher
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser("Analysis of NAS-Bench-201")
+ parser.add_argument(
+ "--api_path",
+ type=str,
+ default=None,
+ help="The path to the NAS-Bench-201 benchmark file and weight dir.",
+ )
+ parser.add_argument(
+ "--archive_path",
+ type=str,
+ default=None,
+ help="The path to the NAS-Bench-201 weight dir.",
+ )
+ args = parser.parse_args()
+
+ meta_file = Path(args.api_path)
+ weight_dir = Path(args.archive_path)
+ assert meta_file.exists(), "invalid path for api : {:}".format(meta_file)
+ assert (
+ weight_dir.exists() and weight_dir.is_dir()
+ ), "invalid path for weight dir : {:}".format(weight_dir)
+
+ api = NASBench201API(meta_file, verbose=True)
+
+ arch_index = 3 # query the 3-th architecture
+ api.reload(weight_dir, arch_index) # reload the data of 3-th from archive dir
+
+ data = "cifar10" # query the info from CIFAR-10
+ config = api.get_net_config(arch_index, data)
+ net = get_cell_based_tiny_net(config)
+ meta_info = api.query_meta_info_by_index(
+ arch_index, hp="200"
+ ) # all info about this architecture
+ params = meta_info.get_net_param(data, 888)
+
+ net.load_state_dict(params)
+ _, summary = weight_watcher.analyze(net, alphas=False)
+ print("The summary of {:}-th architecture:\n{:}".format(arch_index, summary))
diff --git a/AutoDL-Projects/exps/experimental/test-dks.py b/AutoDL-Projects/exps/experimental/test-dks.py
new file mode 100644
index 0000000..57436b7
--- /dev/null
+++ b/AutoDL-Projects/exps/experimental/test-dks.py
@@ -0,0 +1,57 @@
+from dks.base.activation_getter import (
+ get_activation_function as _get_numpy_activation_function,
+)
+from dks.base.activation_transform import _get_activations_params
+
+
+def subnet_max_func(x, r_fn):
+ depth = 7
+ res_x = r_fn(x)
+ x = r_fn(x)
+ for _ in range(depth):
+ x = r_fn(r_fn(x)) + x
+ return max(x, res_x)
+
+
+def subnet_max_func_v2(x, r_fn):
+ depth = 2
+ res_x = r_fn(x)
+
+ x = r_fn(x)
+ for _ in range(depth):
+ x = 0.8 * r_fn(r_fn(x)) + 0.2 * x
+
+ return max(x, res_x)
+
+
+def get_transformed_activations(
+ activation_names,
+ method="TAT",
+ dks_params=None,
+ tat_params=None,
+ max_slope_func=None,
+ max_curv_func=None,
+ subnet_max_func=None,
+ activation_getter=_get_numpy_activation_function,
+):
+ params = _get_activations_params(
+ activation_names,
+ method=method,
+ dks_params=dks_params,
+ tat_params=tat_params,
+ max_slope_func=max_slope_func,
+ max_curv_func=max_curv_func,
+ subnet_max_func=subnet_max_func,
+ )
+ return params
+
+
+params = get_transformed_activations(
+ ["swish"], method="TAT", subnet_max_func=subnet_max_func
+)
+print(params)
+
+params = get_transformed_activations(
+ ["leaky_relu"], method="TAT", subnet_max_func=subnet_max_func_v2
+)
+print(params)
diff --git a/AutoDL-Projects/exps/experimental/test-dynamic.py b/AutoDL-Projects/exps/experimental/test-dynamic.py
new file mode 100644
index 0000000..a1a1e28
--- /dev/null
+++ b/AutoDL-Projects/exps/experimental/test-dynamic.py
@@ -0,0 +1,21 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.08 #
+#####################################################
+# python test-dynamic.py
+#####################################################
+import sys
+from pathlib import Path
+
+lib_dir = (Path(__file__).parent / ".." / "..").resolve()
+print("LIB-DIR: {:}".format(lib_dir))
+if str(lib_dir) not in sys.path:
+ sys.path.insert(0, str(lib_dir))
+
+from xautodl.datasets.math_core import ConstantFunc
+from xautodl.datasets.math_core import GaussianDGenerator
+
+mean_generator = ConstantFunc(0)
+cov_generator = ConstantFunc(1)
+
+generator = GaussianDGenerator([mean_generator], [[cov_generator]], (-1, 1))
+generator(0, 10)
diff --git a/AutoDL-Projects/exps/experimental/test-flops.py b/AutoDL-Projects/exps/experimental/test-flops.py
new file mode 100644
index 0000000..a804cb3
--- /dev/null
+++ b/AutoDL-Projects/exps/experimental/test-flops.py
@@ -0,0 +1,28 @@
+import sys, time, random, argparse
+from copy import deepcopy
+import torchvision.models as models
+from pathlib import Path
+
+lib_dir = (Path(__file__).parent / ".." / ".." / "lib").resolve()
+if str(lib_dir) not in sys.path:
+ sys.path.insert(0, str(lib_dir))
+
+from utils import get_model_infos
+
+# from models.ImageNet_MobileNetV2 import MobileNetV2
+from torchvision.models.mobilenet import MobileNetV2
+
+
+def main(width_mult):
+ # model = MobileNetV2(1001, width_mult, 32, 1280, 'InvertedResidual', 0.2)
+ model = MobileNetV2(width_mult=width_mult)
+ print(model)
+ flops, params = get_model_infos(model, (2, 3, 224, 224))
+ print("FLOPs : {:}".format(flops))
+ print("Params : {:}".format(params))
+ print("-" * 50)
+
+
+if __name__ == "__main__":
+ main(1.0)
+ main(1.4)
diff --git a/AutoDL-Projects/exps/experimental/test-nas-plot.py b/AutoDL-Projects/exps/experimental/test-nas-plot.py
new file mode 100644
index 0000000..f46f186
--- /dev/null
+++ b/AutoDL-Projects/exps/experimental/test-nas-plot.py
@@ -0,0 +1,168 @@
+# python ./exps/vis/test.py
+import os, sys, random
+from pathlib import Path
+from copy import deepcopy
+import torch
+import numpy as np
+from collections import OrderedDict
+
+lib_dir = (Path(__file__).parent / ".." / ".." / "lib").resolve()
+if str(lib_dir) not in sys.path:
+ sys.path.insert(0, str(lib_dir))
+
+from nas_201_api import NASBench201API as API
+
+
+def test_nas_api():
+ from nas_201_api import ArchResults
+
+ xdata = torch.load(
+ "/home/dxy/FOR-RELEASE/NAS-Projects/output/NAS-BENCH-201-4/simplifies/architectures/000157-FULL.pth"
+ )
+ for key in ["full", "less"]:
+ print("\n------------------------- {:} -------------------------".format(key))
+ archRes = ArchResults.create_from_state_dict(xdata[key])
+ print(archRes)
+ print(archRes.arch_idx_str())
+ print(archRes.get_dataset_names())
+ print(archRes.get_comput_costs("cifar10-valid"))
+ # get the metrics
+ print(archRes.get_metrics("cifar10-valid", "x-valid", None, False))
+ print(archRes.get_metrics("cifar10-valid", "x-valid", None, True))
+ print(archRes.query("cifar10-valid", 777))
+
+
+OPS = ["skip-connect", "conv-1x1", "conv-3x3", "pool-3x3"]
+COLORS = ["chartreuse", "cyan", "navyblue", "chocolate1"]
+
+
+def plot(filename):
+ from graphviz import Digraph
+
+ g = Digraph(
+ format="png",
+ edge_attr=dict(fontsize="20", fontname="times"),
+ node_attr=dict(
+ style="filled",
+ shape="rect",
+ align="center",
+ fontsize="20",
+ height="0.5",
+ width="0.5",
+ penwidth="2",
+ fontname="times",
+ ),
+ engine="dot",
+ )
+ g.body.extend(["rankdir=LR"])
+
+ steps = 5
+ for i in range(0, steps):
+ if i == 0:
+ g.node(str(i), fillcolor="darkseagreen2")
+ elif i + 1 == steps:
+ g.node(str(i), fillcolor="palegoldenrod")
+ else:
+ g.node(str(i), fillcolor="lightblue")
+
+ for i in range(1, steps):
+ for xin in range(i):
+ op_i = random.randint(0, len(OPS) - 1)
+ # g.edge(str(xin), str(i), label=OPS[op_i], fillcolor=COLORS[op_i])
+ g.edge(
+ str(xin),
+ str(i),
+ label=OPS[op_i],
+ color=COLORS[op_i],
+ fillcolor=COLORS[op_i],
+ )
+ # import pdb; pdb.set_trace()
+ g.render(filename, cleanup=True, view=False)
+
+
+def test_auto_grad():
+ class Net(torch.nn.Module):
+ def __init__(self, iS):
+ super(Net, self).__init__()
+ self.layer = torch.nn.Linear(iS, 1)
+
+ def forward(self, inputs):
+ outputs = self.layer(inputs)
+ outputs = torch.exp(outputs)
+ return outputs.mean()
+
+ net = Net(10)
+ inputs = torch.rand(256, 10)
+ loss = net(inputs)
+ first_order_grads = torch.autograd.grad(
+ loss, net.parameters(), retain_graph=True, create_graph=True
+ )
+ first_order_grads = torch.cat([x.view(-1) for x in first_order_grads])
+ second_order_grads = []
+ for grads in first_order_grads:
+ s_grads = torch.autograd.grad(grads, net.parameters())
+ second_order_grads.append(s_grads)
+
+
+def test_one_shot_model(ckpath, use_train):
+ from models import get_cell_based_tiny_net, get_search_spaces
+ from datasets import get_datasets, SearchDataset
+ from config_utils import load_config, dict2config
+ from utils.nas_utils import evaluate_one_shot
+
+ use_train = int(use_train) > 0
+ # ckpath = 'output/search-cell-nas-bench-201/DARTS-V1-cifar10/checkpoint/seed-11416-basic.pth'
+ # ckpath = 'output/search-cell-nas-bench-201/DARTS-V1-cifar10/checkpoint/seed-28640-basic.pth'
+ print("ckpath : {:}".format(ckpath))
+ ckp = torch.load(ckpath)
+ xargs = ckp["args"]
+ train_data, valid_data, xshape, class_num = get_datasets(
+ xargs.dataset, xargs.data_path, -1
+ )
+ # config = load_config(xargs.config_path, {'class_num': class_num, 'xshape': xshape}, None)
+ config = load_config(
+ "./configs/nas-benchmark/algos/DARTS.config",
+ {"class_num": class_num, "xshape": xshape},
+ None,
+ )
+ if xargs.dataset == "cifar10":
+ cifar_split = load_config("configs/nas-benchmark/cifar-split.txt", None, None)
+ xvalid_data = deepcopy(train_data)
+ xvalid_data.transform = valid_data.transform
+ valid_loader = torch.utils.data.DataLoader(
+ xvalid_data,
+ batch_size=2048,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(cifar_split.valid),
+ num_workers=12,
+ pin_memory=True,
+ )
+ else:
+ raise ValueError("invalid dataset : {:}".format(xargs.dataseet))
+ search_space = get_search_spaces("cell", xargs.search_space_name)
+ model_config = dict2config(
+ {
+ "name": "SETN",
+ "C": xargs.channel,
+ "N": xargs.num_cells,
+ "max_nodes": xargs.max_nodes,
+ "num_classes": class_num,
+ "space": search_space,
+ "affine": False,
+ "track_running_stats": True,
+ },
+ None,
+ )
+ search_model = get_cell_based_tiny_net(model_config)
+ search_model.load_state_dict(ckp["search_model"])
+ search_model = search_model.cuda()
+ api = API("/home/dxy/.torch/NAS-Bench-201-v1_0-e61699.pth")
+ archs, probs, accuracies = evaluate_one_shot(
+ search_model, valid_loader, api, use_train
+ )
+
+
+if __name__ == "__main__":
+ # test_nas_api()
+ # for i in range(200): plot('{:04d}'.format(i))
+ # test_auto_grad()
+ test_one_shot_model(sys.argv[1], sys.argv[2])
diff --git a/AutoDL-Projects/exps/experimental/test-resnest.py b/AutoDL-Projects/exps/experimental/test-resnest.py
new file mode 100644
index 0000000..eeeef81
--- /dev/null
+++ b/AutoDL-Projects/exps/experimental/test-resnest.py
@@ -0,0 +1,31 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020.06 #
+#####################################################
+# python exps/experimental/test-resnest.py
+#####################################################
+import sys, time, torch, random, argparse
+from PIL import ImageFile
+
+ImageFile.LOAD_TRUNCATED_IMAGES = True
+from copy import deepcopy
+from pathlib import Path
+
+lib_dir = (Path(__file__).parent / ".." / ".." / "lib").resolve()
+if str(lib_dir) not in sys.path:
+ sys.path.insert(0, str(lib_dir))
+from utils import get_model_infos
+
+torch.hub.list("zhanghang1989/ResNeSt", force_reload=True)
+
+for model_name, xshape in [
+ ("resnest50", (1, 3, 224, 224)),
+ ("resnest101", (1, 3, 256, 256)),
+ ("resnest200", (1, 3, 320, 320)),
+ ("resnest269", (1, 3, 416, 416)),
+]:
+ # net = torch.hub.load('zhanghang1989/ResNeSt', model_name, pretrained=True)
+ net = torch.hub.load("zhanghang1989/ResNeSt", model_name, pretrained=False)
+ print("Model : {:}, input shape : {:}".format(model_name, xshape))
+ flops, param = get_model_infos(net, xshape)
+ print("flops : {:.3f}M".format(flops))
+ print("params : {:.3f}M".format(param))
diff --git a/AutoDL-Projects/exps/experimental/test-ww-bench.py b/AutoDL-Projects/exps/experimental/test-ww-bench.py
new file mode 100644
index 0000000..5f398b3
--- /dev/null
+++ b/AutoDL-Projects/exps/experimental/test-ww-bench.py
@@ -0,0 +1,198 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.08 #
+###########################################################################################################################################################
+# Before run these commands, the files must be properly put.
+#
+# CUDA_VISIBLE_DEVICES='' OMP_NUM_THREADS=4 python exps/experimental/test-ww-bench.py --search_space sss --base_path $HOME/.torch/NATS-tss-v1_0-3ffb9 --dataset cifar10
+# CUDA_VISIBLE_DEVICES='' OMP_NUM_THREADS=4 python exps/experimental/test-ww-bench.py --search_space sss --base_path $HOME/.torch/NATS-sss-v1_0-50262 --dataset cifar100
+# CUDA_VISIBLE_DEVICES='' OMP_NUM_THREADS=4 python exps/experimental/test-ww-bench.py --search_space sss --base_path $HOME/.torch/NATS-sss-v1_0-50262 --dataset ImageNet16-120
+# CUDA_VISIBLE_DEVICES='' OMP_NUM_THREADS=4 python exps/experimental/test-ww-bench.py --search_space tss --base_path $HOME/.torch/NATS-tss-v1_0-3ffb9 --dataset cifar10
+###########################################################################################################################################################
+import os, gc, sys, math, argparse, psutil
+import numpy as np
+import torch
+from pathlib import Path
+from collections import OrderedDict
+import matplotlib
+import seaborn as sns
+
+matplotlib.use("agg")
+import matplotlib.pyplot as plt
+
+lib_dir = (Path(__file__).parent / ".." / "..").resolve()
+print("LIB-DIR: {:}".format(lib_dir))
+if str(lib_dir) not in sys.path:
+ sys.path.insert(0, str(lib_dir))
+
+from log_utils import time_string
+from nats_bench import create
+from models import get_cell_based_tiny_net
+from utils import weight_watcher
+
+
+"""
+def get_cor(A, B):
+ return float(np.corrcoef(A, B)[0,1])
+
+
+def tostr(accdict, norms):
+ xstr = []
+ for key, accs in accdict.items():
+ cor = get_cor(accs, norms)
+ xstr.append('{:}: {:.3f}'.format(key, cor))
+ return ' '.join(xstr)
+"""
+
+
+def evaluate(api, weight_dir, data: str):
+ print("\nEvaluate dataset={:}".format(data))
+ process = psutil.Process(os.getpid())
+ norms, accuracies = [], []
+ ok, total = 0, 5000
+ for idx in range(total):
+ arch_index = api.random()
+ api.reload(weight_dir, arch_index)
+ # compute the weight watcher results
+ config = api.get_net_config(arch_index, data)
+ net = get_cell_based_tiny_net(config)
+ meta_info = api.query_meta_info_by_index(
+ arch_index, hp="200" if api.search_space_name == "topology" else "90"
+ )
+ params = meta_info.get_net_param(
+ data, 888 if api.search_space_name == "topology" else 777
+ )
+ with torch.no_grad():
+ net.load_state_dict(params)
+ _, summary = weight_watcher.analyze(net, alphas=False)
+ if "lognorm" not in summary:
+ api.clear_params(arch_index, None)
+ del net
+ continue
+ continue
+ cur_norm = -summary["lognorm"]
+ api.clear_params(arch_index, None)
+ if math.isnan(cur_norm):
+ del net, meta_info
+ continue
+ else:
+ ok += 1
+ norms.append(cur_norm)
+ # query the accuracy
+ info = meta_info.get_metrics(
+ data,
+ "ori-test",
+ iepoch=None,
+ is_random=888 if api.search_space_name == "topology" else 777,
+ )
+ accuracies.append(info["accuracy"])
+ del net, meta_info
+ # print the information
+ if idx % 20 == 0:
+ gc.collect()
+ print(
+ "{:} {:04d}_{:04d}/{:04d} ({:.2f} MB memory)".format(
+ time_string(), ok, idx, total, process.memory_info().rss / 1e6
+ )
+ )
+ return norms, accuracies
+
+
+def main(search_space, meta_file: str, weight_dir, save_dir, xdata):
+ save_dir.mkdir(parents=True, exist_ok=True)
+ api = create(meta_file, search_space, verbose=False)
+ datasets = ["cifar10-valid", "cifar10", "cifar100", "ImageNet16-120"]
+ print(time_string() + " " + "=" * 50)
+ for data in datasets:
+ hps = api.avaliable_hps
+ for hp in hps:
+ nums = api.statistics(data, hp=hp)
+ total = sum([k * v for k, v in nums.items()])
+ print(
+ "Using {:3s} epochs, trained on {:20s} : {:} trials in total ({:}).".format(
+ hp, data, total, nums
+ )
+ )
+ print(time_string() + " " + "=" * 50)
+
+ norms, accuracies = evaluate(api, weight_dir, xdata)
+
+ indexes = list(range(len(norms)))
+ norm_indexes = sorted(indexes, key=lambda i: norms[i])
+ accy_indexes = sorted(indexes, key=lambda i: accuracies[i])
+ labels = []
+ for index in norm_indexes:
+ labels.append(accy_indexes.index(index))
+
+ dpi, width, height = 200, 1400, 800
+ figsize = width / float(dpi), height / float(dpi)
+ LabelSize, LegendFontsize = 18, 12
+ resnet_scale, resnet_alpha = 120, 0.5
+
+ fig = plt.figure(figsize=figsize)
+ ax = fig.add_subplot(111)
+ plt.xlim(min(indexes), max(indexes))
+ plt.ylim(min(indexes), max(indexes))
+ # plt.ylabel('y').set_rotation(30)
+ plt.yticks(
+ np.arange(min(indexes), max(indexes), max(indexes) // 3),
+ fontsize=LegendFontsize,
+ rotation="vertical",
+ )
+ plt.xticks(
+ np.arange(min(indexes), max(indexes), max(indexes) // 5),
+ fontsize=LegendFontsize,
+ )
+ ax.scatter(indexes, labels, marker="*", s=0.5, c="tab:red", alpha=0.8)
+ ax.scatter(indexes, indexes, marker="o", s=0.5, c="tab:blue", alpha=0.8)
+ ax.scatter([-1], [-1], marker="o", s=100, c="tab:blue", label="Test accuracy")
+ ax.scatter([-1], [-1], marker="*", s=100, c="tab:red", label="Weight watcher")
+ plt.grid(zorder=0)
+ ax.set_axisbelow(True)
+ plt.legend(loc=0, fontsize=LegendFontsize)
+ ax.set_xlabel(
+ "architecture ranking sorted by the test accuracy ", fontsize=LabelSize
+ )
+ ax.set_ylabel("architecture ranking computed by weight watcher", fontsize=LabelSize)
+ save_path = (save_dir / "{:}-{:}-test-ww.pdf".format(search_space, xdata)).resolve()
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="pdf")
+ save_path = (save_dir / "{:}-{:}-test-ww.png".format(search_space, xdata)).resolve()
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="png")
+ print("{:} save into {:}".format(time_string(), save_path))
+
+ print("{:} finish this test.".format(time_string()))
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser("Analysis of NAS-Bench-201")
+ parser.add_argument(
+ "--save_dir",
+ type=str,
+ default="./output/vis-nas-bench/",
+ help="The base-name of folder to save checkpoints and log.",
+ )
+ parser.add_argument(
+ "--search_space",
+ type=str,
+ default=None,
+ choices=["tss", "sss"],
+ help="The search space.",
+ )
+ parser.add_argument(
+ "--base_path",
+ type=str,
+ default=None,
+ help="The path to the NAS-Bench-201 benchmark file and weight dir.",
+ )
+ parser.add_argument("--dataset", type=str, default=None, help=".")
+ args = parser.parse_args()
+
+ save_dir = Path(args.save_dir)
+ save_dir.mkdir(parents=True, exist_ok=True)
+ meta_file = Path(args.base_path + ".pth")
+ weight_dir = Path(args.base_path + "-full")
+ assert meta_file.exists(), "invalid path for api : {:}".format(meta_file)
+ assert (
+ weight_dir.exists() and weight_dir.is_dir()
+ ), "invalid path for weight dir : {:}".format(weight_dir)
+
+ main(args.search_space, str(meta_file), weight_dir, save_dir, args.dataset)
diff --git a/AutoDL-Projects/exps/experimental/test-ww.py b/AutoDL-Projects/exps/experimental/test-ww.py
new file mode 100644
index 0000000..97597ca
--- /dev/null
+++ b/AutoDL-Projects/exps/experimental/test-ww.py
@@ -0,0 +1,30 @@
+import sys, time, random, argparse
+from copy import deepcopy
+import torchvision.models as models
+from pathlib import Path
+
+from xautodl.utils import weight_watcher
+
+
+def main():
+ # model = models.vgg19_bn(pretrained=True)
+ # _, summary = weight_watcher.analyze(model, alphas=False)
+ # for key, value in summary.items():
+ # print('{:10s} : {:}'.format(key, value))
+
+ _, summary = weight_watcher.analyze(models.vgg13(pretrained=True), alphas=False)
+ print("vgg-13 : {:}".format(summary["lognorm"]))
+ _, summary = weight_watcher.analyze(models.vgg13_bn(pretrained=True), alphas=False)
+ print("vgg-13-BN : {:}".format(summary["lognorm"]))
+ _, summary = weight_watcher.analyze(models.vgg16(pretrained=True), alphas=False)
+ print("vgg-16 : {:}".format(summary["lognorm"]))
+ _, summary = weight_watcher.analyze(models.vgg16_bn(pretrained=True), alphas=False)
+ print("vgg-16-BN : {:}".format(summary["lognorm"]))
+ _, summary = weight_watcher.analyze(models.vgg19(pretrained=True), alphas=False)
+ print("vgg-19 : {:}".format(summary["lognorm"]))
+ _, summary = weight_watcher.analyze(models.vgg19_bn(pretrained=True), alphas=False)
+ print("vgg-19-BN : {:}".format(summary["lognorm"]))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/AutoDL-Projects/exps/experimental/vis-nats-bench-algos.py b/AutoDL-Projects/exps/experimental/vis-nats-bench-algos.py
new file mode 100644
index 0000000..2d9ea17
--- /dev/null
+++ b/AutoDL-Projects/exps/experimental/vis-nats-bench-algos.py
@@ -0,0 +1,178 @@
+###############################################################
+# NAS-Bench-201, ICLR 2020 (https://arxiv.org/abs/2001.00326) #
+###############################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020.06 #
+###############################################################
+# Usage: python exps/experimental/vis-nats-bench-algos.py --search_space tss
+# Usage: python exps/experimental/vis-nats-bench-algos.py --search_space sss
+###############################################################
+import os, gc, sys, time, torch, argparse
+import numpy as np
+from typing import List, Text, Dict, Any
+from shutil import copyfile
+from collections import defaultdict, OrderedDict
+from copy import deepcopy
+from pathlib import Path
+import matplotlib
+import seaborn as sns
+
+matplotlib.use("agg")
+import matplotlib.pyplot as plt
+import matplotlib.ticker as ticker
+
+lib_dir = (Path(__file__).parent / ".." / ".." / "lib").resolve()
+if str(lib_dir) not in sys.path:
+ sys.path.insert(0, str(lib_dir))
+from config_utils import dict2config, load_config
+from nats_bench import create
+from log_utils import time_string
+
+
+def fetch_data(root_dir="./output/search", search_space="tss", dataset=None):
+ ss_dir = "{:}-{:}".format(root_dir, search_space)
+ alg2name, alg2path = OrderedDict(), OrderedDict()
+ alg2name["REA"] = "R-EA-SS3"
+ alg2name["REINFORCE"] = "REINFORCE-0.01"
+ alg2name["RANDOM"] = "RANDOM"
+ alg2name["BOHB"] = "BOHB"
+ for alg, name in alg2name.items():
+ alg2path[alg] = os.path.join(ss_dir, dataset, name, "results.pth")
+ assert os.path.isfile(alg2path[alg]), "invalid path : {:}".format(alg2path[alg])
+ alg2data = OrderedDict()
+ for alg, path in alg2path.items():
+ data = torch.load(path)
+ for index, info in data.items():
+ info["time_w_arch"] = [
+ (x, y) for x, y in zip(info["all_total_times"], info["all_archs"])
+ ]
+ for j, arch in enumerate(info["all_archs"]):
+ assert arch != -1, "invalid arch from {:} {:} {:} ({:}, {:})".format(
+ alg, search_space, dataset, index, j
+ )
+ alg2data[alg] = data
+ return alg2data
+
+
+def query_performance(api, data, dataset, ticket):
+ results, is_size_space = [], api.search_space_name == "size"
+ for i, info in data.items():
+ time_w_arch = sorted(info["time_w_arch"], key=lambda x: abs(x[0] - ticket))
+ time_a, arch_a = time_w_arch[0]
+ time_b, arch_b = time_w_arch[1]
+ info_a = api.get_more_info(
+ arch_a, dataset=dataset, hp=90 if is_size_space else 200, is_random=False
+ )
+ info_b = api.get_more_info(
+ arch_b, dataset=dataset, hp=90 if is_size_space else 200, is_random=False
+ )
+ accuracy_a, accuracy_b = info_a["test-accuracy"], info_b["test-accuracy"]
+ interplate = (time_b - ticket) / (time_b - time_a) * accuracy_a + (
+ ticket - time_a
+ ) / (time_b - time_a) * accuracy_b
+ results.append(interplate)
+ return sum(results) / len(results)
+
+
+y_min_s = {
+ ("cifar10", "tss"): 90,
+ ("cifar10", "sss"): 92,
+ ("cifar100", "tss"): 65,
+ ("cifar100", "sss"): 65,
+ ("ImageNet16-120", "tss"): 36,
+ ("ImageNet16-120", "sss"): 40,
+}
+
+y_max_s = {
+ ("cifar10", "tss"): 94.5,
+ ("cifar10", "sss"): 93.3,
+ ("cifar100", "tss"): 72,
+ ("cifar100", "sss"): 70,
+ ("ImageNet16-120", "tss"): 44,
+ ("ImageNet16-120", "sss"): 46,
+}
+
+name2label = {
+ "cifar10": "CIFAR-10",
+ "cifar100": "CIFAR-100",
+ "ImageNet16-120": "ImageNet-16-120",
+}
+
+
+def visualize_curve(api, vis_save_dir, search_space, max_time):
+ vis_save_dir = vis_save_dir.resolve()
+ vis_save_dir.mkdir(parents=True, exist_ok=True)
+
+ dpi, width, height = 250, 5200, 1400
+ figsize = width / float(dpi), height / float(dpi)
+ LabelSize, LegendFontsize = 16, 16
+
+ def sub_plot_fn(ax, dataset):
+ alg2data = fetch_data(search_space=search_space, dataset=dataset)
+ alg2accuracies = OrderedDict()
+ total_tickets = 150
+ time_tickets = [
+ float(i) / total_tickets * max_time for i in range(total_tickets)
+ ]
+ colors = ["b", "g", "c", "m", "y"]
+ ax.set_xlim(0, 200)
+ ax.set_ylim(y_min_s[(dataset, search_space)], y_max_s[(dataset, search_space)])
+ for idx, (alg, data) in enumerate(alg2data.items()):
+ print("plot alg : {:}".format(alg))
+ accuracies = []
+ for ticket in time_tickets:
+ accuracy = query_performance(api, data, dataset, ticket)
+ accuracies.append(accuracy)
+ alg2accuracies[alg] = accuracies
+ ax.plot(
+ [x / 100 for x in time_tickets],
+ accuracies,
+ c=colors[idx],
+ label="{:}".format(alg),
+ )
+ ax.set_xlabel("Estimated wall-clock time (1e2 seconds)", fontsize=LabelSize)
+ ax.set_ylabel(
+ "Test accuracy on {:}".format(name2label[dataset]), fontsize=LabelSize
+ )
+ ax.set_title(
+ "Searching results on {:}".format(name2label[dataset]),
+ fontsize=LabelSize + 4,
+ )
+ ax.legend(loc=4, fontsize=LegendFontsize)
+
+ fig, axs = plt.subplots(1, 3, figsize=figsize)
+ datasets = ["cifar10", "cifar100", "ImageNet16-120"]
+ for dataset, ax in zip(datasets, axs):
+ sub_plot_fn(ax, dataset)
+ print("sub-plot {:} on {:} done.".format(dataset, search_space))
+ save_path = (vis_save_dir / "{:}-curve.png".format(search_space)).resolve()
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="png")
+ print("{:} save into {:}".format(time_string(), save_path))
+ plt.close("all")
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(
+ description="NAS-Bench-X",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ )
+ parser.add_argument(
+ "--save_dir",
+ type=str,
+ default="output/vis-nas-bench/nas-algos",
+ help="Folder to save checkpoints and log.",
+ )
+ parser.add_argument(
+ "--search_space",
+ type=str,
+ choices=["tss", "sss"],
+ help="Choose the search space.",
+ )
+ parser.add_argument(
+ "--max_time", type=float, default=20000, help="The maximum time budget."
+ )
+ args = parser.parse_args()
+
+ save_dir = Path(args.save_dir)
+
+ api = create(None, args.search_space, verbose=False)
+ visualize_curve(api, save_dir, args.search_space, args.max_time)
diff --git a/AutoDL-Projects/exps/experimental/vis-nats-bench-ws.py b/AutoDL-Projects/exps/experimental/vis-nats-bench-ws.py
new file mode 100644
index 0000000..47500e1
--- /dev/null
+++ b/AutoDL-Projects/exps/experimental/vis-nats-bench-ws.py
@@ -0,0 +1,185 @@
+###############################################################
+# NAS-Bench-201, ICLR 2020 (https://arxiv.org/abs/2001.00326) #
+###############################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020.06 #
+###############################################################
+# Usage: python exps/experimental/vis-nats-bench-ws.py --search_space tss
+# Usage: python exps/experimental/vis-nats-bench-ws.py --search_space sss
+###############################################################
+import os, gc, sys, time, torch, argparse
+import numpy as np
+from typing import List, Text, Dict, Any
+from shutil import copyfile
+from collections import defaultdict, OrderedDict
+from copy import deepcopy
+from pathlib import Path
+import matplotlib
+import seaborn as sns
+
+matplotlib.use("agg")
+import matplotlib.pyplot as plt
+import matplotlib.ticker as ticker
+
+lib_dir = (Path(__file__).parent / ".." / ".." / "lib").resolve()
+if str(lib_dir) not in sys.path:
+ sys.path.insert(0, str(lib_dir))
+from config_utils import dict2config, load_config
+from nats_bench import create
+from log_utils import time_string
+
+
+# def fetch_data(root_dir='./output/search', search_space='tss', dataset=None, suffix='-WARMNone'):
+def fetch_data(
+ root_dir="./output/search", search_space="tss", dataset=None, suffix="-WARM0.3"
+):
+ ss_dir = "{:}-{:}".format(root_dir, search_space)
+ alg2name, alg2path = OrderedDict(), OrderedDict()
+ seeds = [777, 888, 999]
+ print("\n[fetch data] from {:} on {:}".format(search_space, dataset))
+ if search_space == "tss":
+ alg2name["GDAS"] = "gdas-affine0_BN0-None"
+ alg2name["RSPS"] = "random-affine0_BN0-None"
+ alg2name["DARTS (1st)"] = "darts-v1-affine0_BN0-None"
+ alg2name["DARTS (2nd)"] = "darts-v2-affine0_BN0-None"
+ alg2name["ENAS"] = "enas-affine0_BN0-None"
+ alg2name["SETN"] = "setn-affine0_BN0-None"
+ else:
+ # alg2name['TAS'] = 'tas-affine0_BN0{:}'.format(suffix)
+ # alg2name['FBNetV2'] = 'fbv2-affine0_BN0{:}'.format(suffix)
+ # alg2name['TuNAS'] = 'tunas-affine0_BN0{:}'.format(suffix)
+ alg2name["channel-wise interpolation"] = "tas-affine0_BN0-AWD0.001{:}".format(
+ suffix
+ )
+ alg2name[
+ "masking + Gumbel-Softmax"
+ ] = "mask_gumbel-affine0_BN0-AWD0.001{:}".format(suffix)
+ alg2name["masking + sampling"] = "mask_rl-affine0_BN0-AWD0.0{:}".format(suffix)
+ for alg, name in alg2name.items():
+ alg2path[alg] = os.path.join(ss_dir, dataset, name, "seed-{:}-last-info.pth")
+ alg2data = OrderedDict()
+ for alg, path in alg2path.items():
+ alg2data[alg], ok_num = [], 0
+ for seed in seeds:
+ xpath = path.format(seed)
+ if os.path.isfile(xpath):
+ ok_num += 1
+ else:
+ print("This is an invalid path : {:}".format(xpath))
+ continue
+ data = torch.load(xpath, map_location=torch.device("cpu"))
+ data = torch.load(data["last_checkpoint"], map_location=torch.device("cpu"))
+ alg2data[alg].append(data["genotypes"])
+ print("This algorithm : {:} has {:} valid ckps.".format(alg, ok_num))
+ assert ok_num > 0, "Must have at least 1 valid ckps."
+ return alg2data
+
+
+y_min_s = {
+ ("cifar10", "tss"): 90,
+ ("cifar10", "sss"): 92,
+ ("cifar100", "tss"): 65,
+ ("cifar100", "sss"): 65,
+ ("ImageNet16-120", "tss"): 36,
+ ("ImageNet16-120", "sss"): 40,
+}
+
+y_max_s = {
+ ("cifar10", "tss"): 94.5,
+ ("cifar10", "sss"): 93.3,
+ ("cifar100", "tss"): 72,
+ ("cifar100", "sss"): 70,
+ ("ImageNet16-120", "tss"): 44,
+ ("ImageNet16-120", "sss"): 46,
+}
+
+name2label = {
+ "cifar10": "CIFAR-10",
+ "cifar100": "CIFAR-100",
+ "ImageNet16-120": "ImageNet-16-120",
+}
+
+
+def visualize_curve(api, vis_save_dir, search_space):
+ vis_save_dir = vis_save_dir.resolve()
+ vis_save_dir.mkdir(parents=True, exist_ok=True)
+
+ dpi, width, height = 250, 5200, 1400
+ figsize = width / float(dpi), height / float(dpi)
+ LabelSize, LegendFontsize = 16, 16
+
+ def sub_plot_fn(ax, dataset):
+ alg2data = fetch_data(search_space=search_space, dataset=dataset)
+ alg2accuracies = OrderedDict()
+ epochs = 100
+ colors = ["b", "g", "c", "m", "y", "r"]
+ ax.set_xlim(0, epochs)
+ # ax.set_ylim(y_min_s[(dataset, search_space)], y_max_s[(dataset, search_space)])
+ for idx, (alg, data) in enumerate(alg2data.items()):
+ print("plot alg : {:}".format(alg))
+ xs, accuracies = [], []
+ for iepoch in range(epochs + 1):
+ try:
+ structures, accs = [_[iepoch - 1] for _ in data], []
+ except:
+ raise ValueError(
+ "This alg {:} on {:} has invalid checkpoints.".format(
+ alg, dataset
+ )
+ )
+ for structure in structures:
+ info = api.get_more_info(
+ structure,
+ dataset=dataset,
+ hp=90 if api.search_space_name == "size" else 200,
+ is_random=False,
+ )
+ accs.append(info["test-accuracy"])
+ accuracies.append(sum(accs) / len(accs))
+ xs.append(iepoch)
+ alg2accuracies[alg] = accuracies
+ ax.plot(xs, accuracies, c=colors[idx], label="{:}".format(alg))
+ ax.set_xlabel("The searching epoch", fontsize=LabelSize)
+ ax.set_ylabel(
+ "Test accuracy on {:}".format(name2label[dataset]), fontsize=LabelSize
+ )
+ ax.set_title(
+ "Searching results on {:}".format(name2label[dataset]),
+ fontsize=LabelSize + 4,
+ )
+ ax.legend(loc=4, fontsize=LegendFontsize)
+
+ fig, axs = plt.subplots(1, 3, figsize=figsize)
+ datasets = ["cifar10", "cifar100", "ImageNet16-120"]
+ for dataset, ax in zip(datasets, axs):
+ sub_plot_fn(ax, dataset)
+ print("sub-plot {:} on {:} done.".format(dataset, search_space))
+ save_path = (vis_save_dir / "{:}-ws-curve.png".format(search_space)).resolve()
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="png")
+ print("{:} save into {:}".format(time_string(), save_path))
+ plt.close("all")
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(
+ description="NAS-Bench-X",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ )
+ parser.add_argument(
+ "--save_dir",
+ type=str,
+ default="output/vis-nas-bench/nas-algos",
+ help="Folder to save checkpoints and log.",
+ )
+ parser.add_argument(
+ "--search_space",
+ type=str,
+ default="tss",
+ choices=["tss", "sss"],
+ help="Choose the search space.",
+ )
+ args = parser.parse_args()
+
+ save_dir = Path(args.save_dir)
+
+ api = create(None, args.search_space, fast_mode=True, verbose=False)
+ visualize_curve(api, save_dir, args.search_space)
diff --git a/AutoDL-Projects/exps/experimental/visualize-nas-bench-x.py b/AutoDL-Projects/exps/experimental/visualize-nas-bench-x.py
new file mode 100644
index 0000000..505e2bb
--- /dev/null
+++ b/AutoDL-Projects/exps/experimental/visualize-nas-bench-x.py
@@ -0,0 +1,657 @@
+###############################################################
+# NAS-Bench-201, ICLR 2020 (https://arxiv.org/abs/2001.00326) #
+###############################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020.06 #
+###############################################################
+# Usage: python exps/experimental/visualize-nas-bench-x.py
+###############################################################
+import os, sys, time, torch, argparse
+import numpy as np
+from typing import List, Text, Dict, Any
+from shutil import copyfile
+from collections import defaultdict
+from copy import deepcopy
+from pathlib import Path
+import matplotlib
+import seaborn as sns
+
+matplotlib.use("agg")
+import matplotlib.pyplot as plt
+import matplotlib.ticker as ticker
+
+lib_dir = (Path(__file__).parent / ".." / ".." / "lib").resolve()
+if str(lib_dir) not in sys.path:
+ sys.path.insert(0, str(lib_dir))
+from config_utils import dict2config, load_config
+from log_utils import time_string
+from models import get_cell_based_tiny_net
+from nats_bench import create
+
+
+def visualize_info(api, vis_save_dir, indicator):
+ vis_save_dir = vis_save_dir.resolve()
+ # print ('{:} start to visualize {:} information'.format(time_string(), api))
+ vis_save_dir.mkdir(parents=True, exist_ok=True)
+
+ cifar010_cache_path = vis_save_dir / "{:}-cache-{:}-info.pth".format(
+ "cifar10", indicator
+ )
+ cifar100_cache_path = vis_save_dir / "{:}-cache-{:}-info.pth".format(
+ "cifar100", indicator
+ )
+ imagenet_cache_path = vis_save_dir / "{:}-cache-{:}-info.pth".format(
+ "ImageNet16-120", indicator
+ )
+ cifar010_info = torch.load(cifar010_cache_path)
+ cifar100_info = torch.load(cifar100_cache_path)
+ imagenet_info = torch.load(imagenet_cache_path)
+ indexes = list(range(len(cifar010_info["params"])))
+
+ print("{:} start to visualize relative ranking".format(time_string()))
+
+ cifar010_ord_indexes = sorted(indexes, key=lambda i: cifar010_info["test_accs"][i])
+ cifar100_ord_indexes = sorted(indexes, key=lambda i: cifar100_info["test_accs"][i])
+ imagenet_ord_indexes = sorted(indexes, key=lambda i: imagenet_info["test_accs"][i])
+
+ cifar100_labels, imagenet_labels = [], []
+ for idx in cifar010_ord_indexes:
+ cifar100_labels.append(cifar100_ord_indexes.index(idx))
+ imagenet_labels.append(imagenet_ord_indexes.index(idx))
+ print("{:} prepare data done.".format(time_string()))
+
+ dpi, width, height = 200, 1400, 800
+ figsize = width / float(dpi), height / float(dpi)
+ LabelSize, LegendFontsize = 18, 12
+ resnet_scale, resnet_alpha = 120, 0.5
+
+ fig = plt.figure(figsize=figsize)
+ ax = fig.add_subplot(111)
+ plt.xlim(min(indexes), max(indexes))
+ plt.ylim(min(indexes), max(indexes))
+ # plt.ylabel('y').set_rotation(30)
+ plt.yticks(
+ np.arange(min(indexes), max(indexes), max(indexes) // 3),
+ fontsize=LegendFontsize,
+ rotation="vertical",
+ )
+ plt.xticks(
+ np.arange(min(indexes), max(indexes), max(indexes) // 5),
+ fontsize=LegendFontsize,
+ )
+ ax.scatter(indexes, cifar100_labels, marker="^", s=0.5, c="tab:green", alpha=0.8)
+ ax.scatter(indexes, imagenet_labels, marker="*", s=0.5, c="tab:red", alpha=0.8)
+ ax.scatter(indexes, indexes, marker="o", s=0.5, c="tab:blue", alpha=0.8)
+ ax.scatter([-1], [-1], marker="o", s=100, c="tab:blue", label="CIFAR-10")
+ ax.scatter([-1], [-1], marker="^", s=100, c="tab:green", label="CIFAR-100")
+ ax.scatter([-1], [-1], marker="*", s=100, c="tab:red", label="ImageNet-16-120")
+ plt.grid(zorder=0)
+ ax.set_axisbelow(True)
+ plt.legend(loc=0, fontsize=LegendFontsize)
+ ax.set_xlabel("architecture ranking in CIFAR-10", fontsize=LabelSize)
+ ax.set_ylabel("architecture ranking", fontsize=LabelSize)
+ save_path = (vis_save_dir / "{:}-relative-rank.pdf".format(indicator)).resolve()
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="pdf")
+ save_path = (vis_save_dir / "{:}-relative-rank.png".format(indicator)).resolve()
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="png")
+ print("{:} save into {:}".format(time_string(), save_path))
+
+
+def visualize_sss_info(api, dataset, vis_save_dir):
+ vis_save_dir = vis_save_dir.resolve()
+ print("{:} start to visualize {:} information".format(time_string(), dataset))
+ vis_save_dir.mkdir(parents=True, exist_ok=True)
+ cache_file_path = vis_save_dir / "{:}-cache-sss-info.pth".format(dataset)
+ if not cache_file_path.exists():
+ print("Do not find cache file : {:}".format(cache_file_path))
+ params, flops, train_accs, valid_accs, test_accs = [], [], [], [], []
+ for index in range(len(api)):
+ cost_info = api.get_cost_info(index, dataset, hp="90")
+ params.append(cost_info["params"])
+ flops.append(cost_info["flops"])
+ # accuracy
+ info = api.get_more_info(index, dataset, hp="90", is_random=False)
+ train_accs.append(info["train-accuracy"])
+ test_accs.append(info["test-accuracy"])
+ if dataset == "cifar10":
+ info = api.get_more_info(
+ index, "cifar10-valid", hp="90", is_random=False
+ )
+ valid_accs.append(info["valid-accuracy"])
+ else:
+ valid_accs.append(info["valid-accuracy"])
+ info = {
+ "params": params,
+ "flops": flops,
+ "train_accs": train_accs,
+ "valid_accs": valid_accs,
+ "test_accs": test_accs,
+ }
+ torch.save(info, cache_file_path)
+ else:
+ print("Find cache file : {:}".format(cache_file_path))
+ info = torch.load(cache_file_path)
+ params, flops, train_accs, valid_accs, test_accs = (
+ info["params"],
+ info["flops"],
+ info["train_accs"],
+ info["valid_accs"],
+ info["test_accs"],
+ )
+ print("{:} collect data done.".format(time_string()))
+
+ pyramid = [
+ "8:16:32:48:64",
+ "8:8:16:32:48",
+ "8:8:16:16:32",
+ "8:8:16:16:48",
+ "8:8:16:16:64",
+ "16:16:32:32:64",
+ "32:32:64:64:64",
+ ]
+ pyramid_indexes = [api.query_index_by_arch(x) for x in pyramid]
+ largest_indexes = [api.query_index_by_arch("64:64:64:64:64")]
+
+ indexes = list(range(len(params)))
+ dpi, width, height = 250, 8500, 1300
+ figsize = width / float(dpi), height / float(dpi)
+ LabelSize, LegendFontsize = 24, 24
+ # resnet_scale, resnet_alpha = 120, 0.5
+ xscale, xalpha = 120, 0.8
+
+ fig, axs = plt.subplots(1, 4, figsize=figsize)
+ # ax1, ax2, ax3, ax4, ax5 = axs
+ for ax in axs:
+ for tick in ax.xaxis.get_major_ticks():
+ tick.label.set_fontsize(LabelSize)
+ ax.yaxis.set_major_formatter(ticker.FormatStrFormatter("%.0f"))
+ for tick in ax.yaxis.get_major_ticks():
+ tick.label.set_fontsize(LabelSize)
+ ax2, ax3, ax4, ax5 = axs
+ # ax1.xaxis.set_ticks(np.arange(0, max(indexes), max(indexes)//5))
+ # ax1.scatter(indexes, test_accs, marker='o', s=0.5, c='tab:blue')
+ # ax1.set_xlabel('architecture ID', fontsize=LabelSize)
+ # ax1.set_ylabel('test accuracy (%)', fontsize=LabelSize)
+
+ ax2.scatter(params, train_accs, marker="o", s=0.5, c="tab:blue")
+ ax2.scatter(
+ [params[x] for x in pyramid_indexes],
+ [train_accs[x] for x in pyramid_indexes],
+ marker="*",
+ s=xscale,
+ c="tab:orange",
+ label="Pyramid Structure",
+ alpha=xalpha,
+ )
+ ax2.scatter(
+ [params[x] for x in largest_indexes],
+ [train_accs[x] for x in largest_indexes],
+ marker="x",
+ s=xscale,
+ c="tab:green",
+ label="Largest Candidate",
+ alpha=xalpha,
+ )
+ ax2.set_xlabel("#parameters (MB)", fontsize=LabelSize)
+ ax2.set_ylabel("train accuracy (%)", fontsize=LabelSize)
+ ax2.legend(loc=4, fontsize=LegendFontsize)
+
+ ax3.scatter(params, test_accs, marker="o", s=0.5, c="tab:blue")
+ ax3.scatter(
+ [params[x] for x in pyramid_indexes],
+ [test_accs[x] for x in pyramid_indexes],
+ marker="*",
+ s=xscale,
+ c="tab:orange",
+ label="Pyramid Structure",
+ alpha=xalpha,
+ )
+ ax3.scatter(
+ [params[x] for x in largest_indexes],
+ [test_accs[x] for x in largest_indexes],
+ marker="x",
+ s=xscale,
+ c="tab:green",
+ label="Largest Candidate",
+ alpha=xalpha,
+ )
+ ax3.set_xlabel("#parameters (MB)", fontsize=LabelSize)
+ ax3.set_ylabel("test accuracy (%)", fontsize=LabelSize)
+ ax3.legend(loc=4, fontsize=LegendFontsize)
+
+ ax4.scatter(flops, train_accs, marker="o", s=0.5, c="tab:blue")
+ ax4.scatter(
+ [flops[x] for x in pyramid_indexes],
+ [train_accs[x] for x in pyramid_indexes],
+ marker="*",
+ s=xscale,
+ c="tab:orange",
+ label="Pyramid Structure",
+ alpha=xalpha,
+ )
+ ax4.scatter(
+ [flops[x] for x in largest_indexes],
+ [train_accs[x] for x in largest_indexes],
+ marker="x",
+ s=xscale,
+ c="tab:green",
+ label="Largest Candidate",
+ alpha=xalpha,
+ )
+ ax4.set_xlabel("#FLOPs (M)", fontsize=LabelSize)
+ ax4.set_ylabel("train accuracy (%)", fontsize=LabelSize)
+ ax4.legend(loc=4, fontsize=LegendFontsize)
+
+ ax5.scatter(flops, test_accs, marker="o", s=0.5, c="tab:blue")
+ ax5.scatter(
+ [flops[x] for x in pyramid_indexes],
+ [test_accs[x] for x in pyramid_indexes],
+ marker="*",
+ s=xscale,
+ c="tab:orange",
+ label="Pyramid Structure",
+ alpha=xalpha,
+ )
+ ax5.scatter(
+ [flops[x] for x in largest_indexes],
+ [test_accs[x] for x in largest_indexes],
+ marker="x",
+ s=xscale,
+ c="tab:green",
+ label="Largest Candidate",
+ alpha=xalpha,
+ )
+ ax5.set_xlabel("#FLOPs (M)", fontsize=LabelSize)
+ ax5.set_ylabel("test accuracy (%)", fontsize=LabelSize)
+ ax5.legend(loc=4, fontsize=LegendFontsize)
+
+ save_path = vis_save_dir / "sss-{:}.png".format(dataset)
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="png")
+ print("{:} save into {:}".format(time_string(), save_path))
+ plt.close("all")
+
+
+def visualize_tss_info(api, dataset, vis_save_dir):
+ vis_save_dir = vis_save_dir.resolve()
+ print("{:} start to visualize {:} information".format(time_string(), dataset))
+ vis_save_dir.mkdir(parents=True, exist_ok=True)
+ cache_file_path = vis_save_dir / "{:}-cache-tss-info.pth".format(dataset)
+ if not cache_file_path.exists():
+ print("Do not find cache file : {:}".format(cache_file_path))
+ params, flops, train_accs, valid_accs, test_accs = [], [], [], [], []
+ for index in range(len(api)):
+ cost_info = api.get_cost_info(index, dataset, hp="12")
+ params.append(cost_info["params"])
+ flops.append(cost_info["flops"])
+ # accuracy
+ info = api.get_more_info(index, dataset, hp="200", is_random=False)
+ train_accs.append(info["train-accuracy"])
+ test_accs.append(info["test-accuracy"])
+ if dataset == "cifar10":
+ info = api.get_more_info(
+ index, "cifar10-valid", hp="200", is_random=False
+ )
+ valid_accs.append(info["valid-accuracy"])
+ else:
+ valid_accs.append(info["valid-accuracy"])
+ print("")
+ info = {
+ "params": params,
+ "flops": flops,
+ "train_accs": train_accs,
+ "valid_accs": valid_accs,
+ "test_accs": test_accs,
+ }
+ torch.save(info, cache_file_path)
+ else:
+ print("Find cache file : {:}".format(cache_file_path))
+ info = torch.load(cache_file_path)
+ params, flops, train_accs, valid_accs, test_accs = (
+ info["params"],
+ info["flops"],
+ info["train_accs"],
+ info["valid_accs"],
+ info["test_accs"],
+ )
+ print("{:} collect data done.".format(time_string()))
+
+ resnet = [
+ "|nor_conv_3x3~0|+|none~0|nor_conv_3x3~1|+|skip_connect~0|none~1|skip_connect~2|"
+ ]
+ resnet_indexes = [api.query_index_by_arch(x) for x in resnet]
+ largest_indexes = [
+ api.query_index_by_arch(
+ "|nor_conv_3x3~0|+|nor_conv_3x3~0|nor_conv_3x3~1|+|nor_conv_3x3~0|nor_conv_3x3~1|nor_conv_3x3~2|"
+ )
+ ]
+
+ indexes = list(range(len(params)))
+ dpi, width, height = 250, 8500, 1300
+ figsize = width / float(dpi), height / float(dpi)
+ LabelSize, LegendFontsize = 24, 24
+ # resnet_scale, resnet_alpha = 120, 0.5
+ xscale, xalpha = 120, 0.8
+
+ fig, axs = plt.subplots(1, 4, figsize=figsize)
+ # ax1, ax2, ax3, ax4, ax5 = axs
+ for ax in axs:
+ for tick in ax.xaxis.get_major_ticks():
+ tick.label.set_fontsize(LabelSize)
+ ax.yaxis.set_major_formatter(ticker.FormatStrFormatter("%.0f"))
+ for tick in ax.yaxis.get_major_ticks():
+ tick.label.set_fontsize(LabelSize)
+ ax2, ax3, ax4, ax5 = axs
+ # ax1.xaxis.set_ticks(np.arange(0, max(indexes), max(indexes)//5))
+ # ax1.scatter(indexes, test_accs, marker='o', s=0.5, c='tab:blue')
+ # ax1.set_xlabel('architecture ID', fontsize=LabelSize)
+ # ax1.set_ylabel('test accuracy (%)', fontsize=LabelSize)
+
+ ax2.scatter(params, train_accs, marker="o", s=0.5, c="tab:blue")
+ ax2.scatter(
+ [params[x] for x in resnet_indexes],
+ [train_accs[x] for x in resnet_indexes],
+ marker="*",
+ s=xscale,
+ c="tab:orange",
+ label="ResNet",
+ alpha=xalpha,
+ )
+ ax2.scatter(
+ [params[x] for x in largest_indexes],
+ [train_accs[x] for x in largest_indexes],
+ marker="x",
+ s=xscale,
+ c="tab:green",
+ label="Largest Candidate",
+ alpha=xalpha,
+ )
+ ax2.set_xlabel("#parameters (MB)", fontsize=LabelSize)
+ ax2.set_ylabel("train accuracy (%)", fontsize=LabelSize)
+ ax2.legend(loc=4, fontsize=LegendFontsize)
+
+ ax3.scatter(params, test_accs, marker="o", s=0.5, c="tab:blue")
+ ax3.scatter(
+ [params[x] for x in resnet_indexes],
+ [test_accs[x] for x in resnet_indexes],
+ marker="*",
+ s=xscale,
+ c="tab:orange",
+ label="ResNet",
+ alpha=xalpha,
+ )
+ ax3.scatter(
+ [params[x] for x in largest_indexes],
+ [test_accs[x] for x in largest_indexes],
+ marker="x",
+ s=xscale,
+ c="tab:green",
+ label="Largest Candidate",
+ alpha=xalpha,
+ )
+ ax3.set_xlabel("#parameters (MB)", fontsize=LabelSize)
+ ax3.set_ylabel("test accuracy (%)", fontsize=LabelSize)
+ ax3.legend(loc=4, fontsize=LegendFontsize)
+
+ ax4.scatter(flops, train_accs, marker="o", s=0.5, c="tab:blue")
+ ax4.scatter(
+ [flops[x] for x in resnet_indexes],
+ [train_accs[x] for x in resnet_indexes],
+ marker="*",
+ s=xscale,
+ c="tab:orange",
+ label="ResNet",
+ alpha=xalpha,
+ )
+ ax4.scatter(
+ [flops[x] for x in largest_indexes],
+ [train_accs[x] for x in largest_indexes],
+ marker="x",
+ s=xscale,
+ c="tab:green",
+ label="Largest Candidate",
+ alpha=xalpha,
+ )
+ ax4.set_xlabel("#FLOPs (M)", fontsize=LabelSize)
+ ax4.set_ylabel("train accuracy (%)", fontsize=LabelSize)
+ ax4.legend(loc=4, fontsize=LegendFontsize)
+
+ ax5.scatter(flops, test_accs, marker="o", s=0.5, c="tab:blue")
+ ax5.scatter(
+ [flops[x] for x in resnet_indexes],
+ [test_accs[x] for x in resnet_indexes],
+ marker="*",
+ s=xscale,
+ c="tab:orange",
+ label="ResNet",
+ alpha=xalpha,
+ )
+ ax5.scatter(
+ [flops[x] for x in largest_indexes],
+ [test_accs[x] for x in largest_indexes],
+ marker="x",
+ s=xscale,
+ c="tab:green",
+ label="Largest Candidate",
+ alpha=xalpha,
+ )
+ ax5.set_xlabel("#FLOPs (M)", fontsize=LabelSize)
+ ax5.set_ylabel("test accuracy (%)", fontsize=LabelSize)
+ ax5.legend(loc=4, fontsize=LegendFontsize)
+
+ save_path = vis_save_dir / "tss-{:}.png".format(dataset)
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="png")
+ print("{:} save into {:}".format(time_string(), save_path))
+ plt.close("all")
+
+
+def visualize_rank_info(api, vis_save_dir, indicator):
+ vis_save_dir = vis_save_dir.resolve()
+ # print ('{:} start to visualize {:} information'.format(time_string(), api))
+ vis_save_dir.mkdir(parents=True, exist_ok=True)
+
+ cifar010_cache_path = vis_save_dir / "{:}-cache-{:}-info.pth".format(
+ "cifar10", indicator
+ )
+ cifar100_cache_path = vis_save_dir / "{:}-cache-{:}-info.pth".format(
+ "cifar100", indicator
+ )
+ imagenet_cache_path = vis_save_dir / "{:}-cache-{:}-info.pth".format(
+ "ImageNet16-120", indicator
+ )
+ cifar010_info = torch.load(cifar010_cache_path)
+ cifar100_info = torch.load(cifar100_cache_path)
+ imagenet_info = torch.load(imagenet_cache_path)
+ indexes = list(range(len(cifar010_info["params"])))
+
+ print("{:} start to visualize relative ranking".format(time_string()))
+
+ dpi, width, height = 250, 3800, 1200
+ figsize = width / float(dpi), height / float(dpi)
+ LabelSize, LegendFontsize = 14, 14
+
+ fig, axs = plt.subplots(1, 3, figsize=figsize)
+ ax1, ax2, ax3 = axs
+
+ def get_labels(info):
+ ord_test_indexes = sorted(indexes, key=lambda i: info["test_accs"][i])
+ ord_valid_indexes = sorted(indexes, key=lambda i: info["valid_accs"][i])
+ labels = []
+ for idx in ord_test_indexes:
+ labels.append(ord_valid_indexes.index(idx))
+ return labels
+
+ def plot_ax(labels, ax, name):
+ for tick in ax.xaxis.get_major_ticks():
+ tick.label.set_fontsize(LabelSize)
+ for tick in ax.yaxis.get_major_ticks():
+ tick.label.set_fontsize(LabelSize)
+ tick.label.set_rotation(90)
+ ax.set_xlim(min(indexes), max(indexes))
+ ax.set_ylim(min(indexes), max(indexes))
+ ax.yaxis.set_ticks(np.arange(min(indexes), max(indexes), max(indexes) // 3))
+ ax.xaxis.set_ticks(np.arange(min(indexes), max(indexes), max(indexes) // 5))
+ ax.scatter(indexes, labels, marker="^", s=0.5, c="tab:green", alpha=0.8)
+ ax.scatter(indexes, indexes, marker="o", s=0.5, c="tab:blue", alpha=0.8)
+ ax.scatter(
+ [-1], [-1], marker="^", s=100, c="tab:green", label="{:} test".format(name)
+ )
+ ax.scatter(
+ [-1],
+ [-1],
+ marker="o",
+ s=100,
+ c="tab:blue",
+ label="{:} validation".format(name),
+ )
+ ax.legend(loc=4, fontsize=LegendFontsize)
+ ax.set_xlabel("ranking on the {:} validation".format(name), fontsize=LabelSize)
+ ax.set_ylabel("architecture ranking", fontsize=LabelSize)
+
+ labels = get_labels(cifar010_info)
+ plot_ax(labels, ax1, "CIFAR-10")
+ labels = get_labels(cifar100_info)
+ plot_ax(labels, ax2, "CIFAR-100")
+ labels = get_labels(imagenet_info)
+ plot_ax(labels, ax3, "ImageNet-16-120")
+
+ save_path = (
+ vis_save_dir / "{:}-same-relative-rank.pdf".format(indicator)
+ ).resolve()
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="pdf")
+ save_path = (
+ vis_save_dir / "{:}-same-relative-rank.png".format(indicator)
+ ).resolve()
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="png")
+ print("{:} save into {:}".format(time_string(), save_path))
+ plt.close("all")
+
+
+def calculate_correlation(*vectors):
+ matrix = []
+ for i, vectori in enumerate(vectors):
+ x = []
+ for j, vectorj in enumerate(vectors):
+ x.append(np.corrcoef(vectori, vectorj)[0, 1])
+ matrix.append(x)
+ return np.array(matrix)
+
+
+def visualize_all_rank_info(api, vis_save_dir, indicator):
+ vis_save_dir = vis_save_dir.resolve()
+ # print ('{:} start to visualize {:} information'.format(time_string(), api))
+ vis_save_dir.mkdir(parents=True, exist_ok=True)
+
+ cifar010_cache_path = vis_save_dir / "{:}-cache-{:}-info.pth".format(
+ "cifar10", indicator
+ )
+ cifar100_cache_path = vis_save_dir / "{:}-cache-{:}-info.pth".format(
+ "cifar100", indicator
+ )
+ imagenet_cache_path = vis_save_dir / "{:}-cache-{:}-info.pth".format(
+ "ImageNet16-120", indicator
+ )
+ cifar010_info = torch.load(cifar010_cache_path)
+ cifar100_info = torch.load(cifar100_cache_path)
+ imagenet_info = torch.load(imagenet_cache_path)
+ indexes = list(range(len(cifar010_info["params"])))
+
+ print("{:} start to visualize relative ranking".format(time_string()))
+
+ dpi, width, height = 250, 3200, 1400
+ figsize = width / float(dpi), height / float(dpi)
+ LabelSize, LegendFontsize = 14, 14
+
+ fig, axs = plt.subplots(1, 2, figsize=figsize)
+ ax1, ax2 = axs
+
+ sns_size = 15
+ CoRelMatrix = calculate_correlation(
+ cifar010_info["valid_accs"],
+ cifar010_info["test_accs"],
+ cifar100_info["valid_accs"],
+ cifar100_info["test_accs"],
+ imagenet_info["valid_accs"],
+ imagenet_info["test_accs"],
+ )
+
+ sns.heatmap(
+ CoRelMatrix,
+ annot=True,
+ annot_kws={"size": sns_size},
+ fmt=".3f",
+ linewidths=0.5,
+ ax=ax1,
+ xticklabels=["C10-V", "C10-T", "C100-V", "C100-T", "I120-V", "I120-T"],
+ yticklabels=["C10-V", "C10-T", "C100-V", "C100-T", "I120-V", "I120-T"],
+ )
+
+ selected_indexes, acc_bar = [], 92
+ for i, acc in enumerate(cifar010_info["test_accs"]):
+ if acc > acc_bar:
+ selected_indexes.append(i)
+ cifar010_valid_accs = np.array(cifar010_info["valid_accs"])[selected_indexes]
+ cifar010_test_accs = np.array(cifar010_info["test_accs"])[selected_indexes]
+ cifar100_valid_accs = np.array(cifar100_info["valid_accs"])[selected_indexes]
+ cifar100_test_accs = np.array(cifar100_info["test_accs"])[selected_indexes]
+ imagenet_valid_accs = np.array(imagenet_info["valid_accs"])[selected_indexes]
+ imagenet_test_accs = np.array(imagenet_info["test_accs"])[selected_indexes]
+ CoRelMatrix = calculate_correlation(
+ cifar010_valid_accs,
+ cifar010_test_accs,
+ cifar100_valid_accs,
+ cifar100_test_accs,
+ imagenet_valid_accs,
+ imagenet_test_accs,
+ )
+
+ sns.heatmap(
+ CoRelMatrix,
+ annot=True,
+ annot_kws={"size": sns_size},
+ fmt=".3f",
+ linewidths=0.5,
+ ax=ax2,
+ xticklabels=["C10-V", "C10-T", "C100-V", "C100-T", "I120-V", "I120-T"],
+ yticklabels=["C10-V", "C10-T", "C100-V", "C100-T", "I120-V", "I120-T"],
+ )
+ ax1.set_title("Correlation coefficient over ALL candidates")
+ ax2.set_title(
+ "Correlation coefficient over candidates with accuracy > {:}%".format(acc_bar)
+ )
+ save_path = (vis_save_dir / "{:}-all-relative-rank.png".format(indicator)).resolve()
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight", format="png")
+ print("{:} save into {:}".format(time_string(), save_path))
+ plt.close("all")
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(
+ description="NAS-Bench-X",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ )
+ parser.add_argument(
+ "--save_dir",
+ type=str,
+ default="output/vis-nas-bench",
+ help="Folder to save checkpoints and log.",
+ )
+ # use for train the model
+ args = parser.parse_args()
+
+ to_save_dir = Path(args.save_dir)
+
+ datasets = ["cifar10", "cifar100", "ImageNet16-120"]
+ api201 = create(None, "tss", verbose=True)
+ for xdata in datasets:
+ visualize_tss_info(api201, xdata, to_save_dir)
+
+ api_sss = create(None, "size", verbose=True)
+ for xdata in datasets:
+ visualize_sss_info(api_sss, xdata, to_save_dir)
+
+ visualize_info(None, to_save_dir, "tss")
+ visualize_info(None, to_save_dir, "sss")
+ visualize_rank_info(None, to_save_dir, "tss")
+ visualize_rank_info(None, to_save_dir, "sss")
+
+ visualize_all_rank_info(None, to_save_dir, "tss")
+ visualize_all_rank_info(None, to_save_dir, "sss")
diff --git a/AutoDL-Projects/exps/trading/baselines.py b/AutoDL-Projects/exps/trading/baselines.py
new file mode 100644
index 0000000..5576b8f
--- /dev/null
+++ b/AutoDL-Projects/exps/trading/baselines.py
@@ -0,0 +1,261 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.02 #
+#####################################################
+# python exps/trading/baselines.py --alg MLP #
+# python exps/trading/baselines.py --alg GRU #
+# python exps/trading/baselines.py --alg LSTM #
+# python exps/trading/baselines.py --alg ALSTM #
+# python exps/trading/baselines.py --alg NAIVE-V1 #
+# python exps/trading/baselines.py --alg NAIVE-V2 #
+# #
+# python exps/trading/baselines.py --alg SFM #
+# python exps/trading/baselines.py --alg XGBoost #
+# python exps/trading/baselines.py --alg LightGBM #
+# python exps/trading/baselines.py --alg DoubleE #
+# python exps/trading/baselines.py --alg TabNet #
+# #############################
+# python exps/trading/baselines.py --alg Transformer
+# python exps/trading/baselines.py --alg TSF
+# python exps/trading/baselines.py --alg TSF-2x24-drop0_0 --market csi300
+# python exps/trading/baselines.py --alg TSF-6x32-drop0_0 --market csi300
+#################################################################################
+import sys
+import copy
+from datetime import datetime
+import argparse
+from collections import OrderedDict
+from pprint import pprint
+import ruamel.yaml as yaml
+
+from xautodl.config_utils import arg_str2bool
+from xautodl.procedures.q_exps import update_gpu
+from xautodl.procedures.q_exps import update_market
+from xautodl.procedures.q_exps import run_exp
+
+import qlib
+from qlib.utils import init_instance_by_config
+from qlib.workflow import R
+from qlib.utils import flatten_dict
+
+
+def to_drop(config, pos_drop, other_drop):
+ config = copy.deepcopy(config)
+ net = config["task"]["model"]["kwargs"]["net_config"]
+ net["pos_drop"] = pos_drop
+ net["other_drop"] = other_drop
+ return config
+
+
+def to_layer(config, embed_dim, depth):
+ config = copy.deepcopy(config)
+ net = config["task"]["model"]["kwargs"]["net_config"]
+ net["embed_dim"] = embed_dim
+ net["num_heads"] = [4] * depth
+ net["mlp_hidden_multipliers"] = [4] * depth
+ return config
+
+
+def extend_transformer_settings(alg2configs, name):
+ config = copy.deepcopy(alg2configs[name])
+ for i in range(1, 9):
+ for j in (6, 12, 24, 32, 48, 64):
+ for k1 in (0, 0.05, 0.1, 0.2, 0.3):
+ for k2 in (0, 0.1):
+ alg2configs[
+ name + "-{:}x{:}-drop{:}_{:}".format(i, j, k1, k2)
+ ] = to_layer(to_drop(config, k1, k2), j, i)
+ return alg2configs
+
+
+def replace_start_time(config, start_time):
+ config = copy.deepcopy(config)
+ xtime = datetime.strptime(start_time, "%Y-%m-%d")
+ config["data_handler_config"]["start_time"] = xtime.date()
+ config["data_handler_config"]["fit_start_time"] = xtime.date()
+ config["task"]["dataset"]["kwargs"]["segments"]["train"][0] = xtime.date()
+ return config
+
+
+def extend_train_data(alg2configs, name):
+ config = copy.deepcopy(alg2configs[name])
+ start_times = (
+ "2008-01-01",
+ "2008-07-01",
+ "2009-01-01",
+ "2009-07-01",
+ "2010-01-01",
+ "2011-01-01",
+ "2012-01-01",
+ "2013-01-01",
+ )
+ for start_time in start_times:
+ config = replace_start_time(config, start_time)
+ alg2configs[name + "s{:}".format(start_time)] = config
+ return alg2configs
+
+
+def refresh_record(alg2configs):
+ alg2configs = copy.deepcopy(alg2configs)
+ for key, config in alg2configs.items():
+ xlist = config["task"]["record"]
+ new_list = []
+ for x in xlist:
+ # remove PortAnaRecord and SignalMseRecord
+ if x["class"] != "PortAnaRecord" and x["class"] != "SignalMseRecord":
+ new_list.append(x)
+ ## add MultiSegRecord
+ new_list.append(
+ {
+ "class": "MultiSegRecord",
+ "module_path": "qlib.contrib.workflow",
+ "generate_kwargs": {
+ "segments": {"train": "train", "valid": "valid", "test": "test"},
+ "save": True,
+ },
+ }
+ )
+ config["task"]["record"] = new_list
+ return alg2configs
+
+
+def retrieve_configs():
+ # https://github.com/microsoft/qlib/blob/main/examples/benchmarks/
+ config_dir = (lib_dir / ".." / "configs" / "qlib").resolve()
+ # algorithm to file names
+ alg2names = OrderedDict()
+ alg2names["GRU"] = "workflow_config_gru_Alpha360.yaml"
+ alg2names["LSTM"] = "workflow_config_lstm_Alpha360.yaml"
+ alg2names["MLP"] = "workflow_config_mlp_Alpha360.yaml"
+ # A dual-stage attention-based recurrent neural network for time series prediction, IJCAI-2017
+ alg2names["ALSTM"] = "workflow_config_alstm_Alpha360.yaml"
+ # XGBoost: A Scalable Tree Boosting System, KDD-2016
+ alg2names["XGBoost"] = "workflow_config_xgboost_Alpha360.yaml"
+ # LightGBM: A Highly Efficient Gradient Boosting Decision Tree, NeurIPS-2017
+ alg2names["LightGBM"] = "workflow_config_lightgbm_Alpha360.yaml"
+ # State Frequency Memory (SFM): Stock Price Prediction via Discovering Multi-Frequency Trading Patterns, KDD-2017
+ alg2names["SFM"] = "workflow_config_sfm_Alpha360.yaml"
+ # DoubleEnsemble: A New Ensemble Method Based on Sample Reweighting and Feature Selection for Financial Data Analysis, https://arxiv.org/pdf/2010.01265.pdf
+ alg2names["DoubleE"] = "workflow_config_doubleensemble_Alpha360.yaml"
+ alg2names["TabNet"] = "workflow_config_TabNet_Alpha360.yaml"
+ alg2names["NAIVE-V1"] = "workflow_config_naive_v1_Alpha360.yaml"
+ alg2names["NAIVE-V2"] = "workflow_config_naive_v2_Alpha360.yaml"
+ alg2names["Transformer"] = "workflow_config_transformer_Alpha360.yaml"
+ alg2names["TSF"] = "workflow_config_transformer_basic_Alpha360.yaml"
+
+ # find the yaml paths
+ alg2configs = OrderedDict()
+ print("Start retrieving the algorithm configurations")
+ for idx, (alg, name) in enumerate(alg2names.items()):
+ path = config_dir / name
+ assert path.exists(), "{:} does not exist.".format(path)
+ with open(path) as fp:
+ alg2configs[alg] = yaml.safe_load(fp)
+ print(
+ "The {:02d}/{:02d}-th baseline algorithm is {:9s} ({:}).".format(
+ idx, len(alg2configs), alg, path
+ )
+ )
+ alg2configs = extend_transformer_settings(alg2configs, "TSF")
+ alg2configs = refresh_record(alg2configs)
+ # extend the algorithms by different train-data
+ for name in ("TSF-2x24-drop0_0", "TSF-6x32-drop0_0"):
+ alg2configs = extend_train_data(alg2configs, name)
+ print(
+ "There are {:} algorithms : {:}".format(
+ len(alg2configs), list(alg2configs.keys())
+ )
+ )
+ return alg2configs
+
+
+def main(alg_name, market, config, times, save_dir, gpu):
+
+ pprint("Run {:}".format(alg_name))
+ config = update_market(config, market)
+ config = update_gpu(config, gpu)
+
+ qlib.init(**config.get("qlib_init"))
+ dataset_config = config.get("task").get("dataset")
+ dataset = init_instance_by_config(dataset_config)
+ pprint(dataset_config)
+ pprint(dataset)
+
+ for irun in range(times):
+ run_exp(
+ config.get("task"),
+ dataset,
+ alg_name,
+ "recorder-{:02d}-{:02d}".format(irun, times),
+ "{:}-{:}".format(save_dir, market),
+ )
+
+
+if __name__ == "__main__":
+
+ alg2configs = retrieve_configs()
+
+ parser = argparse.ArgumentParser("Baselines")
+ parser.add_argument(
+ "--save_dir",
+ type=str,
+ default="./outputs/qlib-baselines",
+ help="The checkpoint directory.",
+ )
+ parser.add_argument(
+ "--market",
+ type=str,
+ default="all",
+ choices=["csi100", "csi300", "all"],
+ help="The market indicator.",
+ )
+ parser.add_argument("--times", type=int, default=5, help="The repeated run times.")
+ parser.add_argument(
+ "--shared_dataset",
+ type=arg_str2bool,
+ default=False,
+ help="Whether to share the dataset for all algorithms?",
+ )
+ parser.add_argument(
+ "--gpu", type=int, default=0, help="The GPU ID used for train / test."
+ )
+ parser.add_argument(
+ "--alg",
+ type=str,
+ choices=list(alg2configs.keys()),
+ nargs="+",
+ required=True,
+ help="The algorithm name(s).",
+ )
+ args = parser.parse_args()
+
+ if len(args.alg) == 1:
+ main(
+ args.alg[0],
+ args.market,
+ alg2configs[args.alg[0]],
+ args.times,
+ args.save_dir,
+ args.gpu,
+ )
+ elif len(args.alg) > 1:
+ assert args.shared_dataset, "Must allow share dataset"
+ pprint(args)
+ configs = [
+ update_gpu(update_market(alg2configs[name], args.market), args.gpu)
+ for name in args.alg
+ ]
+ qlib.init(**configs[0].get("qlib_init"))
+ dataset_config = configs[0].get("task").get("dataset")
+ dataset = init_instance_by_config(dataset_config)
+ pprint(dataset_config)
+ pprint(dataset)
+ for alg_name, config in zip(args.alg, configs):
+ print("Run {:} over {:}".format(alg_name, args.alg))
+ for irun in range(args.times):
+ run_exp(
+ config.get("task"),
+ dataset,
+ alg_name,
+ "recorder-{:02d}-{:02d}".format(irun, args.times),
+ "{:}-{:}".format(args.save_dir, args.market),
+ )
diff --git a/AutoDL-Projects/exps/trading/organize_results.py b/AutoDL-Projects/exps/trading/organize_results.py
new file mode 100644
index 0000000..4f70da7
--- /dev/null
+++ b/AutoDL-Projects/exps/trading/organize_results.py
@@ -0,0 +1,175 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.02 #
+#####################################################
+# python exps/trading/organize_results.py --save_dir outputs/qlib-baselines-all
+#####################################################
+import os, re, sys, argparse
+import numpy as np
+from typing import List, Text
+from collections import defaultdict, OrderedDict
+from pprint import pprint
+from pathlib import Path
+import ruamel.yaml as yaml
+
+lib_dir = (Path(__file__).parent / ".." / "..").resolve()
+print("LIB-DIR: {:}".format(lib_dir))
+if str(lib_dir) not in sys.path:
+ sys.path.insert(0, str(lib_dir))
+
+from xautodl.config_utils import arg_str2bool
+from xautodl.utils.qlib_utils import QResult
+
+import qlib
+from qlib.config import REG_CN
+from qlib.workflow import R
+
+
+def compare_results(
+ heads, values, names, space=10, separate="& ", verbose=True, sort_key=False
+):
+ for idx, x in enumerate(heads):
+ assert x == heads[0], "[{:}] \n{:}\nvs\n{:}".format(idx, x, heads[0])
+ new_head = QResult.full_str("Name", space) + separate + heads[0]
+ info_str_dict = dict(head=new_head, lines=[])
+ for name, value in zip(names, values):
+ xline = QResult.full_str(name, space) + separate + value
+ info_str_dict["lines"].append(xline)
+ if verbose:
+ print("\nThere are {:} algorithms.".format(len(values)))
+ print(info_str_dict["head"])
+ if sort_key:
+ lines = sorted(
+ list(zip(values, info_str_dict["lines"])),
+ key=lambda x: float(x[0].split(" ")[0]),
+ )
+ lines = [x[1] for x in lines]
+ else:
+ lines = info_str_dict["lines"]
+ for xline in lines:
+ print(xline + "\\\\")
+ return info_str_dict
+
+
+def filter_finished(recorders):
+ returned_recorders = dict()
+ not_finished = 0
+ for key, recorder in recorders.items():
+ if recorder.status == "FINISHED":
+ returned_recorders[key] = recorder
+ else:
+ not_finished += 1
+ return returned_recorders, not_finished
+
+
+def query_info(save_dir, verbose, name_filter, key_map):
+ R.set_uri(save_dir)
+ experiments = R.list_experiments()
+
+ if verbose:
+ print("There are {:} experiments.".format(len(experiments)))
+ qresults = []
+ for idx, (key, experiment) in enumerate(experiments.items()):
+ if experiment.id == "0":
+ continue
+ if (
+ name_filter is not None
+ and re.fullmatch(name_filter, experiment.name) is None
+ ):
+ continue
+ recorders = experiment.list_recorders()
+ recorders, not_finished = filter_finished(recorders)
+ if verbose:
+ print(
+ "====>>>> {:02d}/{:02d}-th experiment {:9s} has {:02d}/{:02d} finished recorders.".format(
+ idx + 1,
+ len(experiments),
+ experiment.name,
+ len(recorders),
+ len(recorders) + not_finished,
+ )
+ )
+ result = QResult(experiment.name)
+ for recorder_id, recorder in recorders.items():
+ result.update(recorder.list_metrics(), key_map)
+ result.append_path(
+ os.path.join(recorder.uri, recorder.experiment_id, recorder.id)
+ )
+ if not len(result):
+ print("There are no valid recorders for {:}".format(experiment))
+ continue
+ else:
+ print(
+ "There are {:} valid recorders for {:}".format(
+ len(recorders), experiment.name
+ )
+ )
+ qresults.append(result)
+ return qresults
+
+
+if __name__ == "__main__":
+
+ parser = argparse.ArgumentParser("Show Results")
+
+ parser.add_argument(
+ "--save_dir",
+ type=str,
+ nargs="+",
+ default=[],
+ help="The checkpoint directory.",
+ )
+ parser.add_argument(
+ "--verbose",
+ type=arg_str2bool,
+ default=False,
+ help="Print detailed log information or not.",
+ )
+ parser.add_argument(
+ "--name_filter", type=str, default=".*", help="Filter experiment names."
+ )
+ args = parser.parse_args()
+
+ print("Show results of {:}".format(args.save_dir))
+ if not args.save_dir:
+ raise ValueError("Receive no input directory for [args.save_dir]")
+
+ provider_uri = "~/.qlib/qlib_data/cn_data"
+ qlib.init(provider_uri=provider_uri, region=REG_CN)
+
+ """
+ key_map = {
+ # "RMSE": "RMSE",
+ "IC": "IC",
+ "ICIR": "ICIR",
+ "Rank IC": "Rank_IC",
+ "Rank ICIR": "Rank_ICIR",
+ # "excess_return_with_cost.annualized_return": "Annualized_Return",
+ # "excess_return_with_cost.information_ratio": "Information_Ratio",
+ # "excess_return_with_cost.max_drawdown": "Max_Drawdown",
+ }
+ """
+ key_map = dict()
+ for xset in ("train", "valid", "test"):
+ key_map["{:}-mean-IC".format(xset)] = "IC ({:})".format(xset)
+ # key_map["{:}-mean-ICIR".format(xset)] = "ICIR ({:})".format(xset)
+ key_map["{:}-mean-Rank-IC".format(xset)] = "Rank IC ({:})".format(xset)
+ # key_map["{:}-mean-Rank-ICIR".format(xset)] = "Rank ICIR ({:})".format(xset)
+
+ all_qresults = []
+ for save_dir in args.save_dir:
+ qresults = query_info(save_dir, args.verbose, args.name_filter, key_map)
+ all_qresults.extend(qresults)
+ names, head_strs, value_strs = [], [], []
+ for result in all_qresults:
+ head_str, value_str = result.info(list(key_map.values()), verbose=args.verbose)
+ head_strs.append(head_str)
+ value_strs.append(value_str)
+ names.append(result.name)
+ compare_results(
+ head_strs,
+ value_strs,
+ names,
+ space=18,
+ verbose=True,
+ sort_key=True,
+ )
diff --git a/AutoDL-Projects/exps/trading/workflow_tt.py b/AutoDL-Projects/exps/trading/workflow_tt.py
new file mode 100644
index 0000000..d372614
--- /dev/null
+++ b/AutoDL-Projects/exps/trading/workflow_tt.py
@@ -0,0 +1,206 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.02 #
+#####################################################
+# Refer to:
+# - https://github.com/microsoft/qlib/blob/main/examples/workflow_by_code.ipynb
+# - https://github.com/microsoft/qlib/blob/main/examples/workflow_by_code.py
+# python exps/trading/workflow_tt.py --gpu 1 --market csi300
+#####################################################
+import yaml
+import argparse
+
+from xautodl.procedures.q_exps import update_gpu
+from xautodl.procedures.q_exps import update_market
+from xautodl.procedures.q_exps import run_exp
+
+import qlib
+from qlib.config import C
+from qlib.config import REG_CN
+from qlib.utils import init_instance_by_config
+from qlib.workflow import R
+
+
+def main(xargs):
+ dataset_config = {
+ "class": "DatasetH",
+ "module_path": "qlib.data.dataset",
+ "kwargs": {
+ "handler": {
+ "class": "Alpha360",
+ "module_path": "qlib.contrib.data.handler",
+ "kwargs": {
+ "start_time": "2008-01-01",
+ "end_time": "2020-08-01",
+ "fit_start_time": "2008-01-01",
+ "fit_end_time": "2014-12-31",
+ "instruments": xargs.market,
+ "infer_processors": [
+ {
+ "class": "RobustZScoreNorm",
+ "kwargs": {"fields_group": "feature", "clip_outlier": True},
+ },
+ {"class": "Fillna", "kwargs": {"fields_group": "feature"}},
+ ],
+ "learn_processors": [
+ {"class": "DropnaLabel"},
+ {"class": "CSRankNorm", "kwargs": {"fields_group": "label"}},
+ ],
+ "label": ["Ref($close, -2) / Ref($close, -1) - 1"],
+ },
+ },
+ "segments": {
+ "train": ("2008-01-01", "2014-12-31"),
+ "valid": ("2015-01-01", "2016-12-31"),
+ "test": ("2017-01-01", "2020-08-01"),
+ },
+ },
+ }
+
+ model_config = {
+ "class": "QuantTransformer",
+ "module_path": "xautodl.trade_models.quant_transformer",
+ "kwargs": {
+ "net_config": None,
+ "opt_config": None,
+ "GPU": "0",
+ "metric": "loss",
+ },
+ }
+
+ port_analysis_config = {
+ "strategy": {
+ "class": "TopkDropoutStrategy",
+ "module_path": "qlib.contrib.strategy.strategy",
+ "kwargs": {
+ "topk": 50,
+ "n_drop": 5,
+ },
+ },
+ "backtest": {
+ "verbose": False,
+ "limit_threshold": 0.095,
+ "account": 100000000,
+ "benchmark": "SH000300",
+ "deal_price": "close",
+ "open_cost": 0.0005,
+ "close_cost": 0.0015,
+ "min_cost": 5,
+ },
+ }
+
+ record_config = [
+ {
+ "class": "SignalRecord",
+ "module_path": "qlib.workflow.record_temp",
+ "kwargs": dict(),
+ },
+ {
+ "class": "SigAnaRecord",
+ "module_path": "qlib.workflow.record_temp",
+ "kwargs": dict(ana_long_short=False, ann_scaler=252),
+ },
+ {
+ "class": "PortAnaRecord",
+ "module_path": "qlib.workflow.record_temp",
+ "kwargs": dict(config=port_analysis_config),
+ },
+ ]
+
+ provider_uri = "~/.qlib/qlib_data/cn_data"
+ qlib.init(provider_uri=provider_uri, region=REG_CN)
+
+ from qlib.utils import init_instance_by_config
+
+ xconfig = """
+model:
+ class: SFM
+ module_path: qlib.contrib.model.pytorch_sfm
+ kwargs:
+ d_feat: 6
+ hidden_size: 64
+ output_dim: 32
+ freq_dim: 25
+ dropout_W: 0.5
+ dropout_U: 0.5
+ n_epochs: 20
+ lr: 1e-3
+ batch_size: 1600
+ early_stop: 20
+ eval_steps: 5
+ loss: mse
+ optimizer: adam
+ GPU: 0
+"""
+ xconfig = """
+model:
+ class: TabnetModel
+ module_path: qlib.contrib.model.pytorch_tabnet
+ kwargs:
+ d_feat: 360
+ pretrain: True
+"""
+ xconfig = """
+model:
+ class: GRU
+ module_path: qlib.contrib.model.pytorch_gru
+ kwargs:
+ d_feat: 6
+ hidden_size: 64
+ num_layers: 4
+ dropout: 0.0
+ n_epochs: 200
+ lr: 0.001
+ early_stop: 20
+ batch_size: 800
+ metric: loss
+ loss: mse
+ GPU: 0
+"""
+ xconfig = yaml.safe_load(xconfig)
+ model = init_instance_by_config(xconfig["model"])
+ from xautodl.utils.flop_benchmark import count_parameters_in_MB
+
+ # print(count_parameters_in_MB(model.tabnet_model))
+ import pdb
+
+ pdb.set_trace()
+
+ save_dir = "{:}-{:}".format(xargs.save_dir, xargs.market)
+ dataset = init_instance_by_config(dataset_config)
+ for irun in range(xargs.times):
+ xmodel_config = model_config.copy()
+ xmodel_config = update_gpu(xmodel_config, xargs.gpu)
+ task_config = dict(
+ model=xmodel_config, dataset=dataset_config, record=record_config
+ )
+
+ run_exp(
+ task_config,
+ dataset,
+ xargs.name,
+ "recorder-{:02d}-{:02d}".format(irun, xargs.times),
+ save_dir,
+ )
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser("Vanilla Transformable Transformer")
+ parser.add_argument(
+ "--save_dir",
+ type=str,
+ default="./outputs/vtt-runs",
+ help="The checkpoint directory.",
+ )
+ parser.add_argument(
+ "--name", type=str, default="Transformer", help="The experiment name."
+ )
+ parser.add_argument("--times", type=int, default=10, help="The repeated run times.")
+ parser.add_argument(
+ "--gpu", type=int, default=0, help="The GPU ID used for train / test."
+ )
+ parser.add_argument(
+ "--market", type=str, default="all", help="The market indicator."
+ )
+ args = parser.parse_args()
+
+ main(args)
diff --git a/AutoDL-Projects/notebooks/NATS-Bench/BayesOpt.ipynb b/AutoDL-Projects/notebooks/NATS-Bench/BayesOpt.ipynb
new file mode 100644
index 0000000..c5eb12f
--- /dev/null
+++ b/AutoDL-Projects/notebooks/NATS-Bench/BayesOpt.ipynb
@@ -0,0 +1,118 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "german-madonna",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Implementation for \"A Tutorial on Bayesian Optimization\"\n",
+ "import numpy as np\n",
+ "\n",
+ "def get_data():\n",
+ " return np.random.random(2) * 10\n",
+ "\n",
+ "def f(x):\n",
+ " return float(np.power((x[0] * 3 - x[1]), 3) - np.exp(x[1]) + np.power(x[0], 2))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "id": "broke-citizenship",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Kernels typically have the property that points closer in the input space are more strongly correlated\n",
+ "# i.e., if |x1 - x2| < |x1 - x3|, then sigma(x1, x2) > sigma(x1, x3).\n",
+ "# the commonly used and simple kernel is the power exponential or Gaussian kernel:\n",
+ "def sigma0(x1, x2, alpha0=1, alpha=[1,1]):\n",
+ " \"\"\"alpha could be a vector\"\"\"\n",
+ " power = np.array(alpha, dtype=np.float32) * np.power(np.array(x1)-np.array(x2), 2)\n",
+ " return alpha0 * np.exp( -np.sum(power) )\n",
+ "\n",
+ "# the most common choice for the mean function is a constant value\n",
+ "def mu0(x, mu):\n",
+ " return mu"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "id": "aerial-carnival",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "K = 5\n",
+ "X = np.array([get_data() for i in range(K)])\n",
+ "mu = np.mean(X, axis=0)\n",
+ "mu0_over_K = [mu0(x, mu) for x in X]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "id": "polished-discussion",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "sigma0_over_KK = []\n",
+ "for i in range(K):\n",
+ " sigma0_over_KK.append(np.array([sigma0(X[i], X[j]) for j in range(K)]))\n",
+ "sigma0_over_KK = np.array(sigma0_over_KK)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "id": "comic-jesus",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "(20, 20)\n",
+ "1.1038803861344952e-06\n",
+ "1.1038803861344952e-06\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(sigma0_over_KK.shape)\n",
+ "print(sigma0_over_KK[1][2])\n",
+ "print(sigma0_over_KK[2][1])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "statistical-wrist",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "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.8.8"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/AutoDL-Projects/notebooks/NATS-Bench/find-largest.ipynb b/AutoDL-Projects/notebooks/NATS-Bench/find-largest.ipynb
new file mode 100644
index 0000000..b207371
--- /dev/null
+++ b/AutoDL-Projects/notebooks/NATS-Bench/find-largest.ipynb
@@ -0,0 +1,88 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[2021-03-27 06:46:38] Try to use the default NATS-Bench (topology) path from fast_mode=True and path=None.\n"
+ ]
+ }
+ ],
+ "source": [
+ "from nats_bench import create\n",
+ "from pprint import pprint\n",
+ "# Create the API for tologoy search space\n",
+ "api = create(None, 'tss', fast_mode=True, verbose=False)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "{'test-accuracy': 22.39999992879232,\n",
+ " 'test-all-time': 7.7054752962929856,\n",
+ " 'test-loss': 3.1626377182006835,\n",
+ " 'test-per-time': 0.6421229413577488,\n",
+ " 'train-accuracy': 21.68885959195242,\n",
+ " 'train-all-time': 1260.0195466594694,\n",
+ " 'train-loss': 3.1863493608815463,\n",
+ " 'train-per-time': 105.00162888828912,\n",
+ " 'valid-accuracy': 23.266666631062826,\n",
+ " 'valid-all-time': 7.7054752962929856,\n",
+ " 'valid-loss': 3.1219845104217527,\n",
+ " 'valid-per-time': 0.6421229413577488,\n",
+ " 'valtest-accuracy': 22.833333323160808,\n",
+ " 'valtest-all-time': 15.410950592585971,\n",
+ " 'valtest-loss': 3.142311067581177,\n",
+ " 'valtest-per-time': 1.2842458827154977}\n"
+ ]
+ }
+ ],
+ "source": [
+ "largest_candidate_tss = '|nor_conv_3x3~0|+|nor_conv_3x3~0|nor_conv_3x3~1|+|nor_conv_3x3~0|nor_conv_3x3~1|nor_conv_3x3~2|'\n",
+ "\n",
+ "arch_index = api.query_index_by_arch(largest_candidate_tss)\n",
+ "info = api.get_more_info(arch_index, 'ImageNet16-120', hp='12', is_random=False)\n",
+ "pprint(info)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "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.8.8"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/AutoDL-Projects/notebooks/NATS-Bench/issue-96.ipynb b/AutoDL-Projects/notebooks/NATS-Bench/issue-96.ipynb
new file mode 100644
index 0000000..70ff0e6
--- /dev/null
+++ b/AutoDL-Projects/notebooks/NATS-Bench/issue-96.ipynb
@@ -0,0 +1,91 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[2021-03-01 12:28:12] Try to use the default NATS-Bench (topology) path from fast_mode=True and path=None.\n"
+ ]
+ }
+ ],
+ "source": [
+ "from nats_bench import create\n",
+ "import numpy as np\n",
+ "\n",
+ "def get_correlation(A, B):\n",
+ " return float(np.corrcoef(A, B)[0,1])\n",
+ "\n",
+ "# Create the API for tologoy search space\n",
+ "api = create(None, 'tss', fast_mode=True, verbose=False)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "There are 15625 architectures on the topology search space\n"
+ ]
+ }
+ ],
+ "source": [
+ "print('There are {:} architectures on the topology search space'.format(len(api)))\n",
+ "accuracies_12, accuracies_200 = [], []\n",
+ "for i, arch in enumerate(api):\n",
+ " info_a = api.get_more_info(i, dataset='cifar10-valid', hp='12', is_random=False)\n",
+ " accuracies_12.append(info_a['valid-accuracy'])\n",
+ "\n",
+ " info_b = api.get_more_info(i, dataset='cifar10-valid', hp='200', is_random=False)\n",
+ " accuracies_200.append(info_b['test-accuracy'])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[CIFAR-10] The correlation between 12-epoch validation accuracy and 200-epoch test accuracy is: 91.18%\n"
+ ]
+ }
+ ],
+ "source": [
+ "correlation = get_correlation(accuracies_12, accuracies_200)\n",
+ "print('[CIFAR-10] The correlation between 12-epoch validation accuracy and 200-epoch test accuracy is: {:.2f}%'.format(correlation * 100))"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "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.8.3"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/AutoDL-Projects/notebooks/NATS-Bench/issue-97.ipynb b/AutoDL-Projects/notebooks/NATS-Bench/issue-97.ipynb
new file mode 100644
index 0000000..2186588
--- /dev/null
+++ b/AutoDL-Projects/notebooks/NATS-Bench/issue-97.ipynb
@@ -0,0 +1,86 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[2021-03-09 08:44:19] Try to use the default NATS-Bench (size) path from fast_mode=True and path=None.\n"
+ ]
+ }
+ ],
+ "source": [
+ "from nats_bench import create\n",
+ "import numpy as np\n",
+ "\n",
+ "# Create the API for size search space\n",
+ "api = create(None, 'sss', fast_mode=True, verbose=False)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "There are 32768 architectures on the size search space\n"
+ ]
+ }
+ ],
+ "source": [
+ "print('There are {:} architectures on the size search space'.format(len(api)))\n",
+ "\n",
+ "c2acc = dict()\n",
+ "for index in range(len(api)):\n",
+ " info = api.get_more_info(index, 'cifar10', hp='90')\n",
+ " config = api.get_net_config(index, 'cifar10')\n",
+ " c2acc[config['channels']] = info['test-accuracy']"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "91.08546417236329\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(np.mean(list(c2acc.values())))"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "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.8.3"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/AutoDL-Projects/notebooks/Q/qlib-data-play.ipynb b/AutoDL-Projects/notebooks/Q/qlib-data-play.ipynb
new file mode 100644
index 0000000..59778ae
--- /dev/null
+++ b/AutoDL-Projects/notebooks/Q/qlib-data-play.ipynb
@@ -0,0 +1,274 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "[82189:MainThread](2021-03-02 21:02:54,241) INFO - qlib.Initialization - [config.py:276] - default_conf: client.\n",
+ "[82189:MainThread](2021-03-02 21:02:54,255) WARNING - qlib.Initialization - [config.py:291] - redis connection failed(host=127.0.0.1 port=6379), cache will not be used!\n",
+ "[82189:MainThread](2021-03-02 21:02:54,828) INFO - qlib.Initialization - [__init__.py:46] - qlib successfully initialized based on client settings.\n",
+ "[82189:MainThread](2021-03-02 21:02:54,829) INFO - qlib.Initialization - [__init__.py:47] - data_path=/Users/xuanyidong/.qlib/qlib_data/cn_data\n"
+ ]
+ }
+ ],
+ "source": [
+ "import os\n",
+ "import sys\n",
+ "import qlib\n",
+ "import pprint\n",
+ "import numpy as np\n",
+ "import pandas as pd\n",
+ "qlib.init(provider_uri='~/.qlib/qlib_data/cn_data')\n",
+ "\n",
+ "from qlib.config import C\n",
+ "from qlib.data import D\n",
+ "from qlib.data.data import DatasetD, ExpressionD, Inst, Cal, FeatureD\n",
+ "from qlib.data.cache import H\n",
+ "from qlib.data.filter import NameDFilter\n",
+ "from qlib.utils import code_to_fname, read_bin"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n"
+ ]
+ }
+ ],
+ "source": [
+ "nameDFilter = NameDFilter(name_rule_re='SH[0-9]{4}55')\n",
+ "instruments_config = D.instruments(market='csi300', filter_pipe=[nameDFilter])\n",
+ "instruments = D.list_instruments(instruments=instruments_config,\n",
+ " start_time='2015-01-01',\n",
+ " end_time='2016-02-15',\n",
+ " as_list=True)\n",
+ "\n",
+ "fields = ['$close', '$volume', 'Ref($close, 1)', 'Mean($close, 3)', '$high-$low']\n",
+ "features = D.features(instruments_config, fields, start_time='2010-01-01', end_time='2017-12-31', freq='day')\n",
+ "print(type(features))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ " $close $volume Ref($close, 1) Mean($close, 3) \\\n",
+ "instrument datetime \n",
+ "SH600655 2010-01-04 8.934296 47799352.0 8.667867 8.691138 \n",
+ " 2010-01-05 8.889880 29791234.0 8.934296 8.830681 \n",
+ " 2010-01-06 8.845468 29002874.0 8.889880 8.889881 \n",
+ " 2010-01-07 8.553690 38189440.0 8.845468 8.763013 \n",
+ " 2010-01-08 8.645658 23417642.0 8.553690 8.681605 \n",
+ "... ... ... ... ... \n",
+ "SH601555 2017-12-25 1.393481 80615584.0 1.406559 1.408012 \n",
+ " 2017-12-26 1.406559 64259856.0 1.393481 1.402200 \n",
+ " 2017-12-27 1.400747 58551256.0 1.406559 1.400262 \n",
+ " 2017-12-28 1.412371 96204872.0 1.400747 1.406559 \n",
+ " 2017-12-29 1.412371 52801024.0 1.412371 1.408496 \n",
+ "\n",
+ " $high-$low \n",
+ "instrument datetime \n",
+ "SH600655 2010-01-04 0.412291 \n",
+ " 2010-01-05 0.203006 \n",
+ " 2010-01-06 0.250560 \n",
+ " 2010-01-07 0.412291 \n",
+ " 2010-01-08 0.275964 \n",
+ "... ... \n",
+ "SH601555 2017-12-25 0.020343 \n",
+ " 2017-12-26 0.018890 \n",
+ " 2017-12-27 0.017437 \n",
+ " 2017-12-28 0.045045 \n",
+ " 2017-12-29 0.013078 \n",
+ "\n",
+ "[2867 rows x 5 columns]\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(features)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "\n",
+ "LocalProvider\n",
+ "Wrapper(provider=)\n",
+ "Wrapper(provider=)\n",
+ "\n",
+ "LocalDatasetProvider\n",
+ "--\n",
+ "Wrapper(provider=)\n",
+ "\n",
+ "default_disk_cache: 1\n",
+ "ExpressionD: Wrapper(provider=)\n",
+ "FeatureD : \n"
+ ]
+ }
+ ],
+ "source": [
+ "# Provider:\n",
+ "print(type(D._provider))\n",
+ "print(type(C))\n",
+ "print(C.provider)\n",
+ "print(D)\n",
+ "\n",
+ "# DatasetD Provider\n",
+ "print(DatasetD)\n",
+ "print(DatasetD._provider)\n",
+ "print(C.dataset_provider)\n",
+ "\n",
+ "print('--')\n",
+ "print(Inst)\n",
+ "print(Inst._provider)\n",
+ "\n",
+ "# Default Disk Cache\n",
+ "print('default_disk_cache: {:}'.format(C.default_disk_cache))\n",
+ "print('ExpressionD: {:}'.format(ExpressionD))\n",
+ "print('FeatureD : {:}'.format(FeatureD._provider))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "NameError",
+ "evalue": "name 'pprint' is not defined",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
+ "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mpprint\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minstruments_config\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0minstruments_d\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mDatasetD\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_provider\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_instruments_d\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minstruments_config\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfreq\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'day'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mpprint\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mpprint\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minstruments_d\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;31mNameError\u001b[0m: name 'pprint' is not defined"
+ ]
+ }
+ ],
+ "source": [
+ "pprint.pprint(instruments_config)\n",
+ "instruments_d = DatasetD._provider.get_instruments_d(instruments_config, freq='day')\n",
+ "pprint.pprint(instruments_d)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "2012-12-31 00:00:00 -> 2019-01-18 00:00:00\n",
+ "\n",
+ "[1.1059314, 1.0935822, 1.1059314, 1.0922102, 1.0839773, 1.0839773, 1.0181155,\n",
+ " 1.0730004, 1.0867218, 1.068884,\n",
+ " ...\n",
+ " 1.1163876, 1.1208236, 1.1119517, 1.0986437, 1.1075157, 1.0971651, 1.1149089,\n",
+ " 1.083857, 1.083857, 1.0956864]\n",
+ "Length: 1439, dtype: float32\n"
+ ]
+ }
+ ],
+ "source": [
+ "instrument, field, freq = 'SH601555', '$close', 'day'\n",
+ "all_dates = D.calendar(start_time='2011-12-31', end_time='2019-02-10', freq=freq)\n",
+ "start_time, end_time = all_dates[0], all_dates[-11]\n",
+ "print(str(start_time) + ' -> ' + str(end_time))\n",
+ "obj = ExpressionD.expression(instrument, field, start_time, end_time, freq)\n",
+ "print(obj.array)\n",
+ "\n",
+ "# expression = ExpressionD.get_expression_instance(field)\n",
+ "# start_time = pd.Timestamp(start_time)\n",
+ "# end_time = pd.Timestamp(end_time)\n",
+ "# _, _, start_index, end_index = Cal.locate_index(start_time, end_time, freq='day', future=False)\n",
+ "# print(start_index)\n",
+ "# print(end_index)\n",
+ "\n",
+ "# fname = code_to_fname(instrument)\n",
+ "# uri_data = FeatureD._uri_data.format(instrument.lower(), field[1:], freq)\n",
+ "# print(uri_data)\n",
+ "# # series = read_bin(uri_data, start_index, end_index)\n",
+ "# series = read_bin(uri_data, 2850, 2870)\n",
+ "# print(series)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Wrapper(provider=)\n",
+ "Wrapper(provider=)\n",
+ "Wrapper(provider=)\n"
+ ]
+ }
+ ],
+ "source": [
+ "from qlib.data import D\n",
+ "from qlib.data.data import ExpressionD, Inst\n",
+ "print(D)\n",
+ "print(Inst)\n",
+ "print(ExpressionD)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "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.8.3"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/AutoDL-Projects/notebooks/Q/workflow-test.ipynb b/AutoDL-Projects/notebooks/Q/workflow-test.ipynb
new file mode 100644
index 0000000..9b9e093
--- /dev/null
+++ b/AutoDL-Projects/notebooks/Q/workflow-test.ipynb
@@ -0,0 +1,162 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "library path: /Users/xuanyidong/Desktop/XAutoDL/lib\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "[61704:MainThread](2021-03-22 13:56:38,104) INFO - qlib.Initialization - [config.py:276] - default_conf: client.\n",
+ "[61704:MainThread](2021-03-22 13:56:38,106) WARNING - qlib.Initialization - [config.py:291] - redis connection failed(host=127.0.0.1 port=6379), cache will not be used!\n",
+ "[61704:MainThread](2021-03-22 13:56:38,680) INFO - qlib.Initialization - [__init__.py:46] - qlib successfully initialized based on client settings.\n",
+ "[61704:MainThread](2021-03-22 13:56:38,681) INFO - qlib.Initialization - [__init__.py:47] - data_path=/Users/xuanyidong/.qlib/qlib_data/cn_data\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "{'class': 'DatasetH',\n",
+ " 'kwargs': {'handler': {'class': 'Alpha158',\n",
+ " 'kwargs': {'end_time': '2020-08-01',\n",
+ " 'fit_end_time': '2014-12-31',\n",
+ " 'fit_start_time': '2008-01-01',\n",
+ " 'instruments': 'csi100',\n",
+ " 'start_time': '2008-01-01'},\n",
+ " 'module_path': 'qlib.contrib.data.handler'},\n",
+ " 'segments': {'test': ('2017-01-01', '2020-08-01'),\n",
+ " 'train': ('2008-01-01', '2014-12-31'),\n",
+ " 'valid': ('2015-01-01', '2016-12-31')}},\n",
+ " 'module_path': 'qlib.data.dataset'}\n"
+ ]
+ }
+ ],
+ "source": [
+ "import os\n",
+ "import sys\n",
+ "import qlib\n",
+ "import pprint\n",
+ "import numpy as np\n",
+ "import pandas as pd\n",
+ "\n",
+ "from pathlib import Path\n",
+ "\n",
+ "__file__ = os.path.dirname(os.path.realpath(\"__file__\"))\n",
+ "\n",
+ "lib_dir = (Path(__file__).parent / \"..\" / \"lib\").resolve()\n",
+ "print(\"library path: {:}\".format(lib_dir))\n",
+ "assert lib_dir.exists(), \"{:} does not exist\".format(lib_dir)\n",
+ "if str(lib_dir) not in sys.path:\n",
+ " sys.path.insert(0, str(lib_dir))\n",
+ "\n",
+ "from qlib import config as qconfig\n",
+ "from qlib.utils import init_instance_by_config\n",
+ "\n",
+ "qlib.init(provider_uri='~/.qlib/qlib_data/cn_data', region=qconfig.REG_CN)\n",
+ "\n",
+ "dataset_config = {\n",
+ " \"class\": \"DatasetH\",\n",
+ " \"module_path\": \"qlib.data.dataset\",\n",
+ " \"kwargs\": {\n",
+ " \"handler\": {\n",
+ " \"class\": \"Alpha158\",\n",
+ " \"module_path\": \"qlib.contrib.data.handler\",\n",
+ " \"kwargs\": {\n",
+ " \"start_time\": \"2008-01-01\",\n",
+ " \"end_time\": \"2020-08-01\",\n",
+ " \"fit_start_time\": \"2008-01-01\",\n",
+ " \"fit_end_time\": \"2014-12-31\",\n",
+ " \"instruments\": \"csi100\",\n",
+ " },\n",
+ " },\n",
+ " \"segments\": {\n",
+ " \"train\": (\"2008-01-01\", \"2014-12-31\"),\n",
+ " \"valid\": (\"2015-01-01\", \"2016-12-31\"),\n",
+ " \"test\": (\"2017-01-01\", \"2020-08-01\"),\n",
+ " },\n",
+ " },\n",
+ " }\n",
+ "pprint.pprint(dataset_config)\n",
+ "dataset = init_instance_by_config(dataset_config)\n",
+ "\n",
+ "df_train, df_valid, df_test = dataset.prepare(\n",
+ " [\"train\", \"valid\", \"test\"],\n",
+ " col_set=[\"feature\", \"label\"],\n",
+ " data_key=DataHandlerLP.DK_L,\n",
+ " )"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "{'class': 'DatasetH',\n",
+ " 'kwargs': {'handler': {'class': 'Alpha158',\n",
+ " 'kwargs': {'end_time': '2020-08-01',\n",
+ " 'fit_end_time': '2014-12-31',\n",
+ " 'fit_start_time': '2008-01-01',\n",
+ " 'instruments': 'csi300',\n",
+ " 'start_time': '2008-01-01'},\n",
+ " 'module_path': 'qlib.contrib.data.handler'},\n",
+ " 'segments': {'test': ('2017-01-01', '2020-08-01'),\n",
+ " 'train': ('2008-01-01', '2014-12-31'),\n",
+ " 'valid': ('2015-01-01', '2016-12-31')}},\n",
+ " 'module_path': 'qlib.data.dataset'}\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "[95290:MainThread](2021-03-03 12:18:43,481) INFO - qlib.timer - [log.py:81] - Time cost: 237.911s | Loading data Done\n",
+ "[95290:MainThread](2021-03-03 12:18:45,080) INFO - qlib.timer - [log.py:81] - Time cost: 0.465s | DropnaLabel Done\n",
+ "[95290:MainThread](2021-03-03 12:18:51,572) INFO - qlib.timer - [log.py:81] - Time cost: 6.491s | CSZScoreNorm Done\n",
+ "[95290:MainThread](2021-03-03 12:18:51,573) INFO - qlib.timer - [log.py:81] - Time cost: 8.090s | fit & process data Done\n",
+ "[95290:MainThread](2021-03-03 12:18:51,573) INFO - qlib.timer - [log.py:81] - Time cost: 246.003s | Init data Done\n"
+ ]
+ }
+ ],
+ "source": [
+ "from trade_models.transformations import get_transformer\n",
+ "\n",
+ "model = get_transformer(None)"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "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.8.8"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/AutoDL-Projects/notebooks/TOT/ES-Model-DC.ipynb b/AutoDL-Projects/notebooks/TOT/ES-Model-DC.ipynb
new file mode 100644
index 0000000..2a5a5bd
--- /dev/null
+++ b/AutoDL-Projects/notebooks/TOT/ES-Model-DC.ipynb
@@ -0,0 +1,311 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "afraid-minutes",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "The root path: /Users/xuanyidong/Desktop/AutoDL-Projects\n",
+ "The library path: /Users/xuanyidong/Desktop/AutoDL-Projects/lib\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "[70148:MainThread](2021-04-12 13:23:30,262) INFO - qlib.Initialization - [config.py:276] - default_conf: client.\n",
+ "[70148:MainThread](2021-04-12 13:23:30,266) WARNING - qlib.Initialization - [config.py:291] - redis connection failed(host=127.0.0.1 port=6379), cache will not be used!\n",
+ "[70148:MainThread](2021-04-12 13:23:30,269) INFO - qlib.Initialization - [__init__.py:46] - qlib successfully initialized based on client settings.\n",
+ "[70148:MainThread](2021-04-12 13:23:30,271) INFO - qlib.Initialization - [__init__.py:47] - data_path=/Users/xuanyidong/.qlib/qlib_data/cn_data\n"
+ ]
+ }
+ ],
+ "source": [
+ "#\n",
+ "# Exhaustive Search Results\n",
+ "#\n",
+ "import os\n",
+ "import re\n",
+ "import sys\n",
+ "import qlib\n",
+ "import pprint\n",
+ "import numpy as np\n",
+ "import pandas as pd\n",
+ "\n",
+ "from pathlib import Path\n",
+ "\n",
+ "__file__ = os.path.dirname(os.path.realpath(\"__file__\"))\n",
+ "root_dir = (Path(__file__).parent / \"..\").resolve()\n",
+ "lib_dir = (root_dir / \"lib\").resolve()\n",
+ "print(\"The root path: {:}\".format(root_dir))\n",
+ "print(\"The library path: {:}\".format(lib_dir))\n",
+ "assert lib_dir.exists(), \"{:} does not exist\".format(lib_dir)\n",
+ "if str(lib_dir) not in sys.path:\n",
+ " sys.path.insert(0, str(lib_dir))\n",
+ "\n",
+ "import qlib\n",
+ "from qlib import config as qconfig\n",
+ "from qlib.workflow import R\n",
+ "qlib.init(provider_uri='~/.qlib/qlib_data/cn_data', region=qconfig.REG_CN)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "hidden-exemption",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from utils.qlib_utils import QResult"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "continental-drain",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def filter_finished(recorders):\n",
+ " returned_recorders = dict()\n",
+ " not_finished = 0\n",
+ " for key, recorder in recorders.items():\n",
+ " if recorder.status == \"FINISHED\":\n",
+ " returned_recorders[key] = recorder\n",
+ " else:\n",
+ " not_finished += 1\n",
+ " return returned_recorders, not_finished\n",
+ "\n",
+ "def query_info(save_dir, verbose, name_filter, key_map):\n",
+ " if isinstance(save_dir, list):\n",
+ " results = []\n",
+ " for x in save_dir:\n",
+ " x = query_info(x, verbose, name_filter, key_map)\n",
+ " results.extend(x)\n",
+ " return results\n",
+ " # Here, the save_dir must be a string\n",
+ " R.set_uri(str(save_dir))\n",
+ " experiments = R.list_experiments()\n",
+ "\n",
+ " if verbose:\n",
+ " print(\"There are {:} experiments.\".format(len(experiments)))\n",
+ " qresults = []\n",
+ " for idx, (key, experiment) in enumerate(experiments.items()):\n",
+ " if experiment.id == \"0\":\n",
+ " continue\n",
+ " if name_filter is not None and re.fullmatch(name_filter, experiment.name) is None:\n",
+ " continue\n",
+ " recorders = experiment.list_recorders()\n",
+ " recorders, not_finished = filter_finished(recorders)\n",
+ " if verbose:\n",
+ " print(\n",
+ " \"====>>>> {:02d}/{:02d}-th experiment {:9s} has {:02d}/{:02d} finished recorders.\".format(\n",
+ " idx + 1,\n",
+ " len(experiments),\n",
+ " experiment.name,\n",
+ " len(recorders),\n",
+ " len(recorders) + not_finished,\n",
+ " )\n",
+ " )\n",
+ " result = QResult(experiment.name)\n",
+ " for recorder_id, recorder in recorders.items():\n",
+ " result.update(recorder.list_metrics(), key_map)\n",
+ " result.append_path(\n",
+ " os.path.join(recorder.uri, recorder.experiment_id, recorder.id)\n",
+ " )\n",
+ " if not len(result):\n",
+ " print(\"There are no valid recorders for {:}\".format(experiment))\n",
+ " continue\n",
+ " else:\n",
+ " if verbose:\n",
+ " print(\n",
+ " \"There are {:} valid recorders for {:}\".format(\n",
+ " len(recorders), experiment.name\n",
+ " )\n",
+ " )\n",
+ " qresults.append(result)\n",
+ " return qresults"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "filled-multiple",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "[70148:MainThread](2021-04-12 13:23:31,137) INFO - qlib.workflow - [expm.py:290] - \n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[PosixPath('/Users/xuanyidong/Desktop/AutoDL-Projects/outputs/qlib-baselines-csi300')]\n"
+ ]
+ }
+ ],
+ "source": [
+ "paths = [root_dir / 'outputs' / 'qlib-baselines-csi300']\n",
+ "paths = [path.resolve() for path in paths]\n",
+ "print(paths)\n",
+ "\n",
+ "key_map = dict()\n",
+ "for xset in (\"train\", \"valid\", \"test\"):\n",
+ " key_map[\"{:}-mean-IC\".format(xset)] = \"IC ({:})\".format(xset)\n",
+ " key_map[\"{:}-mean-ICIR\".format(xset)] = \"ICIR ({:})\".format(xset)\n",
+ "qresults = query_info(paths, False, 'TSF-.*-drop0_0', key_map)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "intimate-approval",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import matplotlib\n",
+ "from matplotlib import cm\n",
+ "matplotlib.use(\"agg\")\n",
+ "import matplotlib.pyplot as plt\n",
+ "import matplotlib.ticker as ticker"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "supreme-basis",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def vis_depth_channel(qresults, save_path):\n",
+ " save_dir = (save_path / '..').resolve()\n",
+ " save_dir.mkdir(parents=True, exist_ok=True)\n",
+ " print('There are {:} qlib-results'.format(len(qresults)))\n",
+ " \n",
+ " dpi, width, height = 200, 4000, 2000\n",
+ " figsize = width / float(dpi), height / float(dpi)\n",
+ " LabelSize, LegendFontsize = 22, 12\n",
+ " font_gap = 5\n",
+ " \n",
+ " fig = plt.figure(figsize=figsize)\n",
+ " # fig, axs = plt.subplots(1, 2, figsize=figsize, projection='3d')\n",
+ " \n",
+ " def plot_ax(cur_ax, train_or_test):\n",
+ " depths, channels = [], []\n",
+ " ic_values, xmaps = [], dict()\n",
+ " for qresult in qresults:\n",
+ " name = qresult.name.split('-')[1]\n",
+ " depths.append(float(name.split('x')[0]))\n",
+ " channels.append(float(name.split('x')[1]))\n",
+ " if train_or_test:\n",
+ " ic_values.append(qresult['IC (train)'])\n",
+ " else:\n",
+ " ic_values.append(qresult['IC (valid)'])\n",
+ " xmaps[(depths[-1], channels[-1])] = ic_values[-1]\n",
+ " # cur_ax.scatter(depths, channels, ic_values, marker='o', c=\"tab:orange\")\n",
+ " raw_depths = np.arange(1, 9, dtype=np.int32)\n",
+ " raw_channels = np.array([6, 12, 24, 32, 48, 64], dtype=np.int32)\n",
+ " depths, channels = np.meshgrid(raw_depths, raw_channels)\n",
+ " ic_values = np.sin(depths) # initialize\n",
+ " # print(ic_values.shape)\n",
+ " num_x, num_y = ic_values.shape\n",
+ " for i in range(num_x):\n",
+ " for j in range(num_y):\n",
+ " xkey = (int(depths[i][j]), int(channels[i][j]))\n",
+ " if xkey not in xmaps:\n",
+ " raise ValueError(\"Did not find {:}\".format(xkey))\n",
+ " ic_values[i][j] = xmaps[xkey]\n",
+ " #print(sorted(list(xmaps.keys())))\n",
+ " #surf = cur_ax.plot_surface(\n",
+ " # np.array(depths), np.array(channels), np.array(ic_values),\n",
+ " # cmap=cm.coolwarm, linewidth=0, antialiased=False)\n",
+ " surf = cur_ax.plot_surface(\n",
+ " depths, channels, ic_values,\n",
+ " cmap=cm.Spectral, linewidth=0.2, antialiased=True)\n",
+ " cur_ax.set_xticks(raw_depths)\n",
+ " cur_ax.set_yticks(raw_channels)\n",
+ " cur_ax.set_zticks(np.arange(4, 11, 2))\n",
+ " cur_ax.set_xlabel(\"#depth\", fontsize=LabelSize)\n",
+ " cur_ax.set_ylabel(\"#channels\", fontsize=LabelSize)\n",
+ " cur_ax.set_zlabel(\"{:} IC (%)\".format('training' if train_or_test else 'validation'), fontsize=LabelSize)\n",
+ " for tick in cur_ax.xaxis.get_major_ticks():\n",
+ " tick.label.set_fontsize(LabelSize - font_gap)\n",
+ " for tick in cur_ax.yaxis.get_major_ticks():\n",
+ " tick.label.set_fontsize(LabelSize - font_gap)\n",
+ " for tick in cur_ax.zaxis.get_major_ticks():\n",
+ " tick.label.set_fontsize(LabelSize - font_gap)\n",
+ " # Add a color bar which maps values to colors.\n",
+ "# cax = fig.add_axes([cur_ax.get_position().x1 + 0.01,\n",
+ "# cur_ax.get_position().y0,\n",
+ "# 0.01,\n",
+ "# cur_ax.get_position().height * 0.9])\n",
+ " # fig.colorbar(surf, cax=cax)\n",
+ " # fig.colorbar(surf, shrink=0.5, aspect=5)\n",
+ " # import pdb; pdb.set_trace()\n",
+ " # ax1.legend(loc=4, fontsize=LegendFontsize)\n",
+ " ax = fig.add_subplot(1, 2, 1, projection='3d')\n",
+ " plot_ax(ax, True)\n",
+ " ax = fig.add_subplot(1, 2, 2, projection='3d')\n",
+ " plot_ax(ax, False)\n",
+ " # fig.tight_layout()\n",
+ " plt.subplots_adjust(wspace=0.05)#, hspace=0.4)\n",
+ " fig.savefig(save_path, dpi=dpi, bbox_inches=\"tight\", format=\"pdf\")\n",
+ " plt.close(\"all\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "shared-envelope",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "The Desktop is at: /Users/xuanyidong/Desktop\n",
+ "There are 48 qlib-results\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Visualization\n",
+ "home_dir = Path.home()\n",
+ "desktop_dir = home_dir / 'Desktop'\n",
+ "print('The Desktop is at: {:}'.format(desktop_dir))\n",
+ "\n",
+ "vis_depth_channel(qresults, desktop_dir / 'es_csi300_d_vs_c.pdf')"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "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.8.8"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/AutoDL-Projects/notebooks/TOT/ES-Model-Drop.ipynb b/AutoDL-Projects/notebooks/TOT/ES-Model-Drop.ipynb
new file mode 100644
index 0000000..0544b0d
--- /dev/null
+++ b/AutoDL-Projects/notebooks/TOT/ES-Model-Drop.ipynb
@@ -0,0 +1,312 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "afraid-minutes",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "The root path: /Users/xuanyidong/Desktop/AutoDL-Projects\n",
+ "The library path: /Users/xuanyidong/Desktop/AutoDL-Projects/lib\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "[70363:MainThread](2021-04-12 13:25:01,065) INFO - qlib.Initialization - [config.py:276] - default_conf: client.\n",
+ "[70363:MainThread](2021-04-12 13:25:01,069) WARNING - qlib.Initialization - [config.py:291] - redis connection failed(host=127.0.0.1 port=6379), cache will not be used!\n",
+ "[70363:MainThread](2021-04-12 13:25:01,085) INFO - qlib.Initialization - [__init__.py:46] - qlib successfully initialized based on client settings.\n",
+ "[70363:MainThread](2021-04-12 13:25:01,092) INFO - qlib.Initialization - [__init__.py:47] - data_path=/Users/xuanyidong/.qlib/qlib_data/cn_data\n"
+ ]
+ }
+ ],
+ "source": [
+ "#\n",
+ "# Exhaustive Search Results\n",
+ "#\n",
+ "import os\n",
+ "import re\n",
+ "import sys\n",
+ "import qlib\n",
+ "import pprint\n",
+ "import numpy as np\n",
+ "import pandas as pd\n",
+ "\n",
+ "from pathlib import Path\n",
+ "\n",
+ "__file__ = os.path.dirname(os.path.realpath(\"__file__\"))\n",
+ "root_dir = (Path(__file__).parent / \"..\").resolve()\n",
+ "lib_dir = (root_dir / \"lib\").resolve()\n",
+ "print(\"The root path: {:}\".format(root_dir))\n",
+ "print(\"The library path: {:}\".format(lib_dir))\n",
+ "assert lib_dir.exists(), \"{:} does not exist\".format(lib_dir)\n",
+ "if str(lib_dir) not in sys.path:\n",
+ " sys.path.insert(0, str(lib_dir))\n",
+ "\n",
+ "import qlib\n",
+ "from qlib import config as qconfig\n",
+ "from qlib.workflow import R\n",
+ "qlib.init(provider_uri='~/.qlib/qlib_data/cn_data', region=qconfig.REG_CN)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "hidden-exemption",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from utils.qlib_utils import QResult"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "continental-drain",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def filter_finished(recorders):\n",
+ " returned_recorders = dict()\n",
+ " not_finished = 0\n",
+ " for key, recorder in recorders.items():\n",
+ " if recorder.status == \"FINISHED\":\n",
+ " returned_recorders[key] = recorder\n",
+ " else:\n",
+ " not_finished += 1\n",
+ " return returned_recorders, not_finished\n",
+ "\n",
+ "def query_info(save_dir, verbose, name_filter, key_map):\n",
+ " if isinstance(save_dir, list):\n",
+ " results = []\n",
+ " for x in save_dir:\n",
+ " x = query_info(x, verbose, name_filter, key_map)\n",
+ " results.extend(x)\n",
+ " return results\n",
+ " # Here, the save_dir must be a string\n",
+ " R.set_uri(str(save_dir))\n",
+ " experiments = R.list_experiments()\n",
+ "\n",
+ " if verbose:\n",
+ " print(\"There are {:} experiments.\".format(len(experiments)))\n",
+ " qresults = []\n",
+ " for idx, (key, experiment) in enumerate(experiments.items()):\n",
+ " if experiment.id == \"0\":\n",
+ " continue\n",
+ " if name_filter is not None and re.fullmatch(name_filter, experiment.name) is None:\n",
+ " continue\n",
+ " recorders = experiment.list_recorders()\n",
+ " recorders, not_finished = filter_finished(recorders)\n",
+ " if verbose:\n",
+ " print(\n",
+ " \"====>>>> {:02d}/{:02d}-th experiment {:9s} has {:02d}/{:02d} finished recorders.\".format(\n",
+ " idx + 1,\n",
+ " len(experiments),\n",
+ " experiment.name,\n",
+ " len(recorders),\n",
+ " len(recorders) + not_finished,\n",
+ " )\n",
+ " )\n",
+ " result = QResult(experiment.name)\n",
+ " for recorder_id, recorder in recorders.items():\n",
+ " result.update(recorder.list_metrics(), key_map)\n",
+ " result.append_path(\n",
+ " os.path.join(recorder.uri, recorder.experiment_id, recorder.id)\n",
+ " )\n",
+ " if not len(result):\n",
+ " print(\"There are no valid recorders for {:}\".format(experiment))\n",
+ " continue\n",
+ " else:\n",
+ " if verbose:\n",
+ " print(\n",
+ " \"There are {:} valid recorders for {:}\".format(\n",
+ " len(recorders), experiment.name\n",
+ " )\n",
+ " )\n",
+ " qresults.append(result)\n",
+ " return qresults"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "filled-multiple",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "[70363:MainThread](2021-04-12 13:25:01,647) INFO - qlib.workflow - [expm.py:290] - \n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[PosixPath('/Users/xuanyidong/Desktop/AutoDL-Projects/outputs/qlib-baselines-csi300')]\n"
+ ]
+ }
+ ],
+ "source": [
+ "paths = [root_dir / 'outputs' / 'qlib-baselines-csi300']\n",
+ "paths = [path.resolve() for path in paths]\n",
+ "print(paths)\n",
+ "\n",
+ "key_map = dict()\n",
+ "for xset in (\"train\", \"valid\", \"test\"):\n",
+ " key_map[\"{:}-mean-IC\".format(xset)] = \"IC ({:})\".format(xset)\n",
+ " key_map[\"{:}-mean-ICIR\".format(xset)] = \"ICIR ({:})\".format(xset)\n",
+ "\n",
+ "qresults = query_info(paths, False, 'TSF-.*', key_map)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "intimate-approval",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import matplotlib\n",
+ "from matplotlib import cm\n",
+ "matplotlib.use(\"agg\")\n",
+ "import matplotlib.pyplot as plt\n",
+ "import matplotlib.ticker as ticker"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "supreme-basis",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def vis_dropouts(qresults, basenames, name2suffix, save_path):\n",
+ " save_dir = (save_path / '..').resolve()\n",
+ " save_dir.mkdir(parents=True, exist_ok=True)\n",
+ " print('There are {:} qlib-results'.format(len(qresults)))\n",
+ " \n",
+ " name2qresult = dict()\n",
+ " for qresult in qresults:\n",
+ " name2qresult[qresult.name] = qresult\n",
+ " # sort architectures\n",
+ " accuracies = []\n",
+ " for basename in basenames:\n",
+ " qresult = name2qresult[basename + '-drop0_0']\n",
+ " accuracies.append(qresult['ICIR (train)'])\n",
+ " sorted_basenames = sorted(basenames, key=lambda x: accuracies[basenames.index(x)])\n",
+ " \n",
+ " dpi, width, height = 200, 4000, 2000\n",
+ " figsize = width / float(dpi), height / float(dpi)\n",
+ " LabelSize, LegendFontsize = 22, 22\n",
+ " font_gap = 5\n",
+ " colors = ['k', 'r']\n",
+ " markers = ['*', 'o']\n",
+ " \n",
+ " fig = plt.figure(figsize=figsize)\n",
+ " \n",
+ " def plot_ax(cur_ax, train_or_test):\n",
+ " for idx, (legend, suffix) in enumerate(name2suffix.items()):\n",
+ " x_values = list(range(len(sorted_basenames)))\n",
+ " y_values = []\n",
+ " for i, name in enumerate(sorted_basenames):\n",
+ " name = '{:}{:}'.format(name, suffix)\n",
+ " qresult = name2qresult[name]\n",
+ " if train_or_test:\n",
+ " value = qresult['IC (train)']\n",
+ " else:\n",
+ " value = qresult['IC (valid)']\n",
+ " y_values.append(value)\n",
+ " cur_ax.plot(x_values, y_values, c=colors[idx])\n",
+ " cur_ax.scatter(x_values, y_values,\n",
+ " marker=markers[idx], s=3, c=colors[idx], alpha=0.9,\n",
+ " label=legend)\n",
+ " cur_ax.set_yticks(np.arange(4, 11, 2))\n",
+ " cur_ax.set_xlabel(\"sorted architectures\", fontsize=LabelSize)\n",
+ " cur_ax.set_ylabel(\"{:} IC (%)\".format('training' if train_or_test else 'validation'), fontsize=LabelSize)\n",
+ " for tick in cur_ax.xaxis.get_major_ticks():\n",
+ " tick.label.set_fontsize(LabelSize - font_gap)\n",
+ " for tick in cur_ax.yaxis.get_major_ticks():\n",
+ " tick.label.set_fontsize(LabelSize - font_gap)\n",
+ " cur_ax.legend(loc=4, fontsize=LegendFontsize)\n",
+ " ax = fig.add_subplot(1, 2, 1)\n",
+ " plot_ax(ax, True)\n",
+ " ax = fig.add_subplot(1, 2, 2)\n",
+ " plot_ax(ax, False)\n",
+ " # fig.tight_layout()\n",
+ " # plt.subplots_adjust(wspace=0.05)#, hspace=0.4)\n",
+ " fig.savefig(save_path, dpi=dpi, bbox_inches=\"tight\", format=\"pdf\")\n",
+ " plt.close(\"all\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "id": "shared-envelope",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "{'TSF-3x48', 'TSF-2x64', 'TSF-2x12', 'TSF-8x48', 'TSF-6x32', 'TSF-4x48', 'TSF-8x6', 'TSF-4x6', 'TSF-2x32', 'TSF-5x12', 'TSF-5x64', 'TSF-1x64', 'TSF-2x24', 'TSF-8x24', 'TSF-4x12', 'TSF-6x12', 'TSF-1x32', 'TSF-5x32', 'TSF-3x24', 'TSF-8x12', 'TSF-5x48', 'TSF-6x64', 'TSF-7x64', 'TSF-7x48', 'TSF-1x6', 'TSF-2x48', 'TSF-7x24', 'TSF-3x32', 'TSF-1x24', 'TSF-4x64', 'TSF-3x12', 'TSF-8x64', 'TSF-4x32', 'TSF-5x6', 'TSF-7x6', 'TSF-7x12', 'TSF-3x6', 'TSF-4x24', 'TSF-6x48', 'TSF-6x6', 'TSF-1x48', 'TSF-1x12', 'TSF-7x32', 'TSF-5x24', 'TSF-2x6', 'TSF-6x24', 'TSF-3x64', 'TSF-8x32'}\n",
+ "The Desktop is at: /Users/xuanyidong/Desktop\n",
+ "There are 104 qlib-results\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Visualization\n",
+ "names = [qresult.name for qresult in qresults]\n",
+ "base_names = set()\n",
+ "for name in names:\n",
+ " base_name = name.split('-drop')[0]\n",
+ " base_names.add(base_name)\n",
+ "print(base_names)\n",
+ "# filter\n",
+ "filtered_base_names = set()\n",
+ "for base_name in base_names:\n",
+ " if (base_name + '-drop0_0') in names and (base_name + '-drop0.1_0') in names:\n",
+ " filtered_base_names.add(base_name)\n",
+ " else:\n",
+ " print('Cannot find all names for {:}'.format(base_name))\n",
+ "# print(filtered_base_names)\n",
+ "home_dir = Path.home()\n",
+ "desktop_dir = home_dir / 'Desktop'\n",
+ "print('The Desktop is at: {:}'.format(desktop_dir))\n",
+ "\n",
+ "vis_dropouts(qresults, list(filtered_base_names),\n",
+ " {'No-dropout': '-drop0_0',\n",
+ " 'Ratio=0.1' : '-drop0.1_0'},\n",
+ " desktop_dir / 'es_csi300_drop.pdf')"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "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.8.8"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/AutoDL-Projects/notebooks/TOT/Time-Curve.ipynb b/AutoDL-Projects/notebooks/TOT/Time-Curve.ipynb
new file mode 100644
index 0000000..fa8911f
--- /dev/null
+++ b/AutoDL-Projects/notebooks/TOT/Time-Curve.ipynb
@@ -0,0 +1,208 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "afraid-minutes",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "The root path: /Users/xuanyidong/Desktop/AutoDL-Projects\n",
+ "The library path: /Users/xuanyidong/Desktop/AutoDL-Projects/lib\n"
+ ]
+ }
+ ],
+ "source": [
+ "import os\n",
+ "import re\n",
+ "import sys\n",
+ "import torch\n",
+ "import pprint\n",
+ "import numpy as np\n",
+ "import pandas as pd\n",
+ "from pathlib import Path\n",
+ "from scipy.interpolate import make_interp_spline\n",
+ "\n",
+ "__file__ = os.path.dirname(os.path.realpath(\"__file__\"))\n",
+ "root_dir = (Path(__file__).parent / \"..\").resolve()\n",
+ "lib_dir = (root_dir / \"lib\").resolve()\n",
+ "print(\"The root path: {:}\".format(root_dir))\n",
+ "print(\"The library path: {:}\".format(lib_dir))\n",
+ "assert lib_dir.exists(), \"{:} does not exist\".format(lib_dir)\n",
+ "if str(lib_dir) not in sys.path:\n",
+ " sys.path.insert(0, str(lib_dir))\n",
+ "from utils.qlib_utils import QResult"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "continental-drain",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "TSF-2x24-drop0_0s2013-01-01\n",
+ "TSF-2x24-drop0_0s2012-01-01\n",
+ "TSF-2x24-drop0_0s2008-01-01\n",
+ "TSF-2x24-drop0_0s2009-01-01\n",
+ "TSF-2x24-drop0_0s2010-01-01\n",
+ "TSF-2x24-drop0_0s2011-01-01\n",
+ "TSF-2x24-drop0_0s2008-07-01\n",
+ "TSF-2x24-drop0_0s2009-07-01\n",
+ "There are 3011 dates\n",
+ "Dates: 2008-01-02 2008-01-03\n"
+ ]
+ }
+ ],
+ "source": [
+ "qresults = torch.load(os.path.join(root_dir, 'notebooks', 'TOT', 'temp-time-x.pth'))\n",
+ "for qresult in qresults:\n",
+ " print(qresult.name)\n",
+ "all_dates = set()\n",
+ "for qresult in qresults:\n",
+ " dates = qresult.find_all_dates()\n",
+ " for date in dates:\n",
+ " all_dates.add(date)\n",
+ "all_dates = sorted(list(all_dates))\n",
+ "print('There are {:} dates'.format(len(all_dates)))\n",
+ "print('Dates: {:} {:}'.format(all_dates[0], all_dates[1]))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "intimate-approval",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import matplotlib\n",
+ "from matplotlib import cm\n",
+ "matplotlib.use(\"agg\")\n",
+ "import matplotlib.pyplot as plt\n",
+ "import matplotlib.ticker as ticker"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "supreme-basis",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def vis_time_curve(qresults, dates, use_original, save_path):\n",
+ " save_dir = (save_path / '..').resolve()\n",
+ " save_dir.mkdir(parents=True, exist_ok=True)\n",
+ " print('There are {:} qlib-results'.format(len(qresults)))\n",
+ " \n",
+ " dpi, width, height = 200, 5000, 2000\n",
+ " figsize = width / float(dpi), height / float(dpi)\n",
+ " LabelSize, LegendFontsize = 22, 12\n",
+ " font_gap = 5\n",
+ " linestyles = ['-', '--']\n",
+ " colors = ['k', 'r']\n",
+ " \n",
+ " fig = plt.figure(figsize=figsize)\n",
+ " cur_ax = fig.add_subplot(1, 1, 1)\n",
+ " for idx, qresult in enumerate(qresults):\n",
+ " print('Visualize [{:}] -- {:}'.format(idx, qresult.name))\n",
+ " x_axis, y_axis = [], []\n",
+ " for idate, date in enumerate(dates):\n",
+ " if date in qresult._date2ICs[-1]:\n",
+ " mean, std = qresult.get_IC_by_date(date, 100)\n",
+ " if not np.isnan(mean):\n",
+ " x_axis.append(idate)\n",
+ " y_axis.append(mean)\n",
+ " x_axis, y_axis = np.array(x_axis), np.array(y_axis)\n",
+ " if use_original:\n",
+ " cur_ax.plot(x_axis, y_axis, linewidth=1, color=colors[idx], linestyle=linestyles[idx])\n",
+ " else:\n",
+ " xnew = np.linspace(x_axis.min(), x_axis.max(), 200)\n",
+ " spl = make_interp_spline(x_axis, y_axis, k=5)\n",
+ " ynew = spl(xnew)\n",
+ " cur_ax.plot(xnew, ynew, linewidth=2, color=colors[idx], linestyle=linestyles[idx])\n",
+ " \n",
+ " for tick in cur_ax.xaxis.get_major_ticks():\n",
+ " tick.label.set_fontsize(LabelSize - font_gap)\n",
+ " for tick in cur_ax.yaxis.get_major_ticks():\n",
+ " tick.label.set_fontsize(LabelSize - font_gap)\n",
+ " cur_ax.set_ylabel(\"IC (%)\", fontsize=LabelSize)\n",
+ " fig.savefig(save_path, dpi=dpi, bbox_inches=\"tight\", format=\"pdf\")\n",
+ " plt.close(\"all\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "shared-envelope",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "The Desktop is at: /Users/xuanyidong/Desktop\n",
+ "There are 2 qlib-results\n",
+ "Visualize [0] -- TSF-2x24-drop0_0s2008-01-01\n",
+ "Visualize [1] -- TSF-2x24-drop0_0s2009-07-01\n",
+ "There are 2 qlib-results\n",
+ "Visualize [0] -- TSF-2x24-drop0_0s2008-01-01\n",
+ "Visualize [1] -- TSF-2x24-drop0_0s2009-07-01\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Visualization\n",
+ "home_dir = Path.home()\n",
+ "desktop_dir = home_dir / 'Desktop'\n",
+ "print('The Desktop is at: {:}'.format(desktop_dir))\n",
+ "\n",
+ "vis_time_curve(\n",
+ " (qresults[2], qresults[-1]),\n",
+ " all_dates,\n",
+ " True,\n",
+ " desktop_dir / 'es_csi300_time_curve.pdf')\n",
+ "\n",
+ "vis_time_curve(\n",
+ " (qresults[2], qresults[-1]),\n",
+ " all_dates,\n",
+ " False,\n",
+ " desktop_dir / 'es_csi300_time_curve-inter.pdf')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "exempt-stable",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "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.8.8"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/AutoDL-Projects/notebooks/TOT/time-curve.py b/AutoDL-Projects/notebooks/TOT/time-curve.py
new file mode 100644
index 0000000..9109338
--- /dev/null
+++ b/AutoDL-Projects/notebooks/TOT/time-curve.py
@@ -0,0 +1,129 @@
+import os
+import re
+import sys
+import torch
+import qlib
+import pprint
+from collections import OrderedDict
+import numpy as np
+import pandas as pd
+
+from pathlib import Path
+
+# __file__ = os.path.dirname(os.path.realpath("__file__"))
+note_dir = Path(__file__).parent.resolve()
+root_dir = (Path(__file__).parent / ".." / "..").resolve()
+lib_dir = (root_dir / "lib").resolve()
+print("The root path: {:}".format(root_dir))
+print("The library path: {:}".format(lib_dir))
+assert lib_dir.exists(), "{:} does not exist".format(lib_dir)
+if str(lib_dir) not in sys.path:
+ sys.path.insert(0, str(lib_dir))
+
+import qlib
+from qlib import config as qconfig
+from qlib.workflow import R
+
+qlib.init(provider_uri="~/.qlib/qlib_data/cn_data", region=qconfig.REG_CN)
+
+from utils.qlib_utils import QResult
+
+
+def filter_finished(recorders):
+ returned_recorders = dict()
+ not_finished = 0
+ for key, recorder in recorders.items():
+ if recorder.status == "FINISHED":
+ returned_recorders[key] = recorder
+ else:
+ not_finished += 1
+ return returned_recorders, not_finished
+
+
+def add_to_dict(xdict, timestamp, value):
+ date = timestamp.date().strftime("%Y-%m-%d")
+ if date in xdict:
+ raise ValueError("This date [{:}] is already in the dict".format(date))
+ xdict[date] = value
+
+
+def query_info(save_dir, verbose, name_filter, key_map):
+ if isinstance(save_dir, list):
+ results = []
+ for x in save_dir:
+ x = query_info(x, verbose, name_filter, key_map)
+ results.extend(x)
+ return results
+ # Here, the save_dir must be a string
+ R.set_uri(str(save_dir))
+ experiments = R.list_experiments()
+
+ if verbose:
+ print("There are {:} experiments.".format(len(experiments)))
+ qresults = []
+ for idx, (key, experiment) in enumerate(experiments.items()):
+ if experiment.id == "0":
+ continue
+ if (
+ name_filter is not None
+ and re.fullmatch(name_filter, experiment.name) is None
+ ):
+ continue
+ recorders = experiment.list_recorders()
+ recorders, not_finished = filter_finished(recorders)
+ if verbose:
+ print(
+ "====>>>> {:02d}/{:02d}-th experiment {:9s} has {:02d}/{:02d} finished recorders.".format(
+ idx + 1,
+ len(experiments),
+ experiment.name,
+ len(recorders),
+ len(recorders) + not_finished,
+ )
+ )
+ result = QResult(experiment.name)
+ for recorder_id, recorder in recorders.items():
+ file_names = ["results-train.pkl", "results-valid.pkl", "results-test.pkl"]
+ date2IC = OrderedDict()
+ for file_name in file_names:
+ xtemp = recorder.load_object(file_name)["all-IC"]
+ timestamps, values = xtemp.index.tolist(), xtemp.tolist()
+ for timestamp, value in zip(timestamps, values):
+ add_to_dict(date2IC, timestamp, value)
+ result.update(recorder.list_metrics(), key_map)
+ result.append_path(
+ os.path.join(recorder.uri, recorder.experiment_id, recorder.id)
+ )
+ result.append_date2ICs(date2IC)
+ if not len(result):
+ print("There are no valid recorders for {:}".format(experiment))
+ continue
+ else:
+ if verbose:
+ print(
+ "There are {:} valid recorders for {:}".format(
+ len(recorders), experiment.name
+ )
+ )
+ qresults.append(result)
+ return qresults
+
+
+##
+paths = [root_dir / "outputs" / "qlib-baselines-csi300"]
+paths = [path.resolve() for path in paths]
+print(paths)
+
+key_map = dict()
+for xset in ("train", "valid", "test"):
+ key_map["{:}-mean-IC".format(xset)] = "IC ({:})".format(xset)
+ key_map["{:}-mean-ICIR".format(xset)] = "ICIR ({:})".format(xset)
+qresults = query_info(paths, False, "TSF-2x24-drop0_0s.*-.*-01", key_map)
+print("Find {:} results".format(len(qresults)))
+times = []
+for qresult in qresults:
+ times.append(qresult.name.split("0_0s")[-1])
+print(times)
+save_path = os.path.join(note_dir, "temp-time-x.pth")
+torch.save(qresults, save_path)
+print(save_path)
diff --git a/AutoDL-Projects/notebooks/spaces-xmisc/random-search-transformer.ipynb b/AutoDL-Projects/notebooks/spaces-xmisc/random-search-transformer.ipynb
new file mode 100644
index 0000000..688b4f3
--- /dev/null
+++ b/AutoDL-Projects/notebooks/spaces-xmisc/random-search-transformer.ipynb
@@ -0,0 +1,102 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "library path: /Users/xuanyidong/Desktop/XAutoDL/lib\n"
+ ]
+ }
+ ],
+ "source": [
+ "#####################################################\n",
+ "# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.03 #\n",
+ "#####################################################\n",
+ "import abc, os, sys\n",
+ "from pathlib import Path\n",
+ "\n",
+ "__file__ = os.path.dirname(os.path.realpath(\"__file__\"))\n",
+ "\n",
+ "lib_dir = (Path(__file__).parent / \"..\" / \"lib\").resolve()\n",
+ "print(\"library path: {:}\".format(lib_dir))\n",
+ "assert lib_dir.exists(), \"{:} does not exist\".format(lib_dir)\n",
+ "if str(lib_dir) not in sys.path:\n",
+ " sys.path.insert(0, str(lib_dir))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1.7.0\n",
+ "True\n",
+ "OrderedDict()\n",
+ "OrderedDict()\n",
+ "set()\n",
+ "OrderedDict()\n",
+ "OrderedDict()\n",
+ "OrderedDict()\n",
+ "OrderedDict()\n",
+ "OrderedDict()\n",
+ "OrderedDict()\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/Users/xuanyidong/anaconda3/lib/python3.8/site-packages/torch/nn/modules/container.py:551: UserWarning: Setting attributes on ParameterDict is not supported.\n",
+ " warnings.warn(\"Setting attributes on ParameterDict is not supported.\")\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Test the Linear layer\n",
+ "import spaces\n",
+ "import torch\n",
+ "from xlayers import super_core\n",
+ "\n",
+ "print(torch.__version__)\n",
+ "mlp = super_core.SuperMLPv2(10, 12, 32)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "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.8.3"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/AutoDL-Projects/notebooks/spaces-xmisc/scheduler.ipynb b/AutoDL-Projects/notebooks/spaces-xmisc/scheduler.ipynb
new file mode 100644
index 0000000..4ecc3c3
--- /dev/null
+++ b/AutoDL-Projects/notebooks/spaces-xmisc/scheduler.ipynb
@@ -0,0 +1,119 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "The config dir path: /Users/xuanyidong/Desktop/AutoDL-Projects/configs\n"
+ ]
+ }
+ ],
+ "source": [
+ "#####################################################\n",
+ "# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.06 #\n",
+ "#####################################################\n",
+ "import os, sys, math\n",
+ "import numpy as np\n",
+ "from pathlib import Path\n",
+ "\n",
+ "import matplotlib.pyplot as plt\n",
+ "\n",
+ "import torch\n",
+ "from xautodl.xmisc.scheduler_utils import CosineParamScheduler, MultiStepParamScheduler\n",
+ "from xautodl.xmisc.scheduler_utils import LRMultiplier, WarmupParamScheduler\n",
+ "\n",
+ "__file__ = os.path.dirname(os.path.realpath(\"__file__\"))\n",
+ "\n",
+ "config_dir = (Path(__file__).parent / \"..\" / \"configs\").resolve()\n",
+ "print(\"The config dir path: {:}\".format(config_dir))\n",
+ "\n",
+ "def draw(steps, lrs):\n",
+ " plt.close()\n",
+ " dpi, width, height = 200, 1400, 800\n",
+ " figsize = width / float(dpi), height / float(dpi)\n",
+ " fig = plt.figure(figsize=figsize)\n",
+ " ax = fig.add_subplot(111)\n",
+ "\n",
+ " plt.plot(steps, lrs)\n",
+ " plt.title(\"Plot Cosine Decayed LR with Warmup\")\n",
+ " plt.xlabel(\"steps\")\n",
+ " plt.ylabel(\"learning rate\")\n",
+ " plt.show()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "p = torch.nn.Parameter(torch.zeros(0))\n",
+ "opt = torch.optim.SGD([p], lr=5)\n",
+ "multiplier = WarmupParamScheduler(\n",
+ " CosineParamScheduler(0.1, 0.0001),\n",
+ " warmup_factor = 0.001,\n",
+ " warmup_length = 0.05,\n",
+ " warmup_method = 'linear'\n",
+ ")\n",
+ "total = 100\n",
+ "scheduler = LRMultiplier(opt, multiplier, total)\n",
+ "steps, lrs = [], []\n",
+ "\n",
+ "for _iter in range(total * 2):\n",
+ " p.sum().backward()\n",
+ " opt.step()\n",
+ " lrs.append(opt.param_groups[0][\"lr\"])\n",
+ " steps.append(_iter)\n",
+ "\n",
+ " scheduler.step()\n",
+ "draw(steps, lrs)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "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.8.8"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/AutoDL-Projects/notebooks/spaces-xmisc/synthetic-data.ipynb b/AutoDL-Projects/notebooks/spaces-xmisc/synthetic-data.ipynb
new file mode 100644
index 0000000..9b13971
--- /dev/null
+++ b/AutoDL-Projects/notebooks/spaces-xmisc/synthetic-data.ipynb
@@ -0,0 +1,110 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "filled-multiple",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "The root path: /Users/xuanyidong/Desktop/AutoDL-Projects\n",
+ "The library path: /Users/xuanyidong/Desktop/AutoDL-Projects/lib\n"
+ ]
+ }
+ ],
+ "source": [
+ "import os, sys\n",
+ "import torch\n",
+ "from pathlib import Path\n",
+ "import numpy as np\n",
+ "import matplotlib\n",
+ "import matplotlib.pyplot as plt\n",
+ "\n",
+ "\n",
+ "__file__ = os.path.dirname(os.path.realpath(\"__file__\"))\n",
+ "root_dir = (Path(__file__).parent / \"..\").resolve()\n",
+ "lib_dir = (root_dir / \"lib\").resolve()\n",
+ "print(\"The root path: {:}\".format(root_dir))\n",
+ "print(\"The library path: {:}\".format(lib_dir))\n",
+ "assert lib_dir.exists(), \"{:} does not exist\".format(lib_dir)\n",
+ "if str(lib_dir) not in sys.path:\n",
+ " sys.path.insert(0, str(lib_dir))\n",
+ "\n",
+ "from datasets import ComposedSinFunc"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "consistent-transition",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "ComposedSinFunc(QuadraticFunc(-12.00009536743164 * x^2 + 12.000093460083008 * x + 0.9998981952667236) * sin(QuarticFunc(6.998945236206055 * x^4 + -14.143538475036621 * x^3 + -16.54721450805664 * x^2 + 52.29801940917969 * x + 52.29801940917969)))\n"
+ ]
+ },
+ {
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "def visualize_q_func():\n",
+ "\n",
+ " dpi, width, height = 10, 200, 80\n",
+ " figsize = width / float(dpi), height / float(dpi)\n",
+ " LabelSize, LegendFontsize, font_gap = 40, 40, 5\n",
+ " \n",
+ " fig = plt.figure(figsize=figsize)\n",
+ " \n",
+ " func = ComposedSinFunc()\n",
+ " print(func)\n",
+ " xaxis, yaxis = [], []\n",
+ " timestamps = np.arange(0, 1.0, 0.01)\n",
+ " for idx, position in enumerate(timestamps):\n",
+ " xaxis.append(position)\n",
+ " yaxis.append(func(position))\n",
+ "\n",
+ " cur_ax = fig.add_subplot(1, 1, 1)\n",
+ " cur_ax.plot(xaxis, yaxis, color=\"k\", linestyle=\"-\", alpha=0.6, label=None)\n",
+ "\n",
+ "visualize_q_func()"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "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.8.8"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/AutoDL-Projects/notebooks/spaces-xmisc/synthetic-env.ipynb b/AutoDL-Projects/notebooks/spaces-xmisc/synthetic-env.ipynb
new file mode 100644
index 0000000..9345fb3
--- /dev/null
+++ b/AutoDL-Projects/notebooks/spaces-xmisc/synthetic-env.ipynb
@@ -0,0 +1,129 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "filled-multiple",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "The root path: /Users/xuanyidong/Desktop/AutoDL-Projects\n",
+ "The library path: /Users/xuanyidong/Desktop/AutoDL-Projects/lib\n"
+ ]
+ }
+ ],
+ "source": [
+ "import os, sys\n",
+ "import torch\n",
+ "from pathlib import Path\n",
+ "import numpy as np\n",
+ "import matplotlib\n",
+ "import matplotlib.pyplot as plt\n",
+ "\n",
+ "\n",
+ "__file__ = os.path.dirname(os.path.realpath(\"__file__\"))\n",
+ "root_dir = (Path(__file__).parent / \"..\").resolve()\n",
+ "lib_dir = (root_dir / \"lib\").resolve()\n",
+ "print(\"The root path: {:}\".format(root_dir))\n",
+ "print(\"The library path: {:}\".format(lib_dir))\n",
+ "assert lib_dir.exists(), \"{:} does not exist\".format(lib_dir)\n",
+ "if str(lib_dir) not in sys.path:\n",
+ " sys.path.insert(0, str(lib_dir))\n",
+ "\n",
+ "from datasets.synthetic_example import create_example_v1"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "consistent-transition",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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7uAol8taWFhQrVZTKpVSrVbTwsICDXiAJ6BhFYC9tlMXcbqLAwCA/SadTgequ8C4GQAAAAAAAAAAAAAA2EuFQkFLS0vKZrNqtVrKZrNaWlpSoVBwHc0rm3M+NuffWmuZ87EP/dZv/VagugtszAoAgP9C13zHGPM/kbT1DuFnks5L+g+21BKSftsYE7r8ALDVlStXdPnyZSWTSVlrlUwmdfnyZV25csV1tKE333xzW6OdWCymN99801Gi7XwZUAp74wZfvo94caVSSdZaJRIJGWOUSCRkrVWpVHIdDQglGlYBAAAAwO5pt9uB6i4wbgYAAAAAAAAAAAAAAPZaoVBQpVJRvV5XpVJhnsJz6vV66vf7staq3++r1+u5jjRicXFRqVRKxhilUiktLi66jjQiEhm/THunugvdbjdQHQAA4HmYMO2obox5SdKfSnrl85KV9Festf/UGBOT9IeS8lv+yQVr7f95b1PurTNnztjbt2+7jgGEkjFmx6+F6dxWLpdVKpVUrVaVy+VULBZDNRiyuLioq1evDjv7bv4ZtiZBYVcul3Xu3Dk9evRI/X5f0WhUhw4d0q1bt0L18w47H17XPmTMZDKSpGazOfx93NxNvl6vuwuGA8mH10w+n1etVlMikRjWOp2OstmsKpWKu2AAnpsP5554PD724V4sFuNBEOApH849AOAC50cA8BfncADAQcd7IQAAmAQfril8yAgAAAAA47z++uu6e/euJA3XxUnSiRMn9MEHH7iMJumzdXvf+973ttV/4zd+IzTr9nzI6MN9Kxkng4yTQcbJICOwPxljfmStPTPua+FpPfiZ39IXjXck6bettf9Ukqy1PUl/XVJ/y9f/D8aY1/YuHgAEUy6X9Z3vfEc//vGPtb6+rh//+Mf6zne+o3K57Dra0PLysqanpxWLxSR9tth3enpay8vLjpONKpfLyufzymQyyufzofoeStKlS5f08OFD9fufvU31+309fPhQly5dcpwMB1Emk9GDBw9Gfh8fPHgwbMoDYFS1WlU8Hh+pxeNxVatVN4EAD4T92swH3/3udwPVAQAAAAAAAAAAAAAAAAAAAHzh3r17w43opS8a8Ny7d89xss/85m/+ZqC6C2fPnh3ZyFiSEomEzp496ygRAACAGyYsXauMMf99Sf94S+nPJL1prV1/7O99T9LlLaXft9b+yh5EdOLM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whgzt8+83q6cPXtWH330kQaDgcbjsZLJpHK5nF599VXX1aYajYbq9bqCIFA6ndZoNOK0TQAAAEdWV1fV6XTm5lGRTCY1Ho/n5nh6+XxeDx48mJsDAAAAAICjpVarMWxnCXz66afT59ePPsf+9NNPXVWa4fu+6vW6rLXK5XLqdruq1+uSFJk/o77v6+LFi3rw4IEmk4lu376tixcvSopORwAAAAAA4iw6R8gCAAAAAAAAABBxvV5PJ06cmG6gTSaTOnHihHq9nttij0in06FyFxqNhlZWVlQsFnXq1CkVi0WtrKxEarANp20CAABExxdffBEqd2He4J0n5S4cNpAzSoM67927FyoHAAAAAABAtB12kE2UDrhpNpuy1iqTycgYo0wmI2utms2m62pTV65c0e7uriaTiSRpMplod3dXV65ccdwMAAAAAICjwUTpZgVmnT9/3t66dct1DQAAAAAAAACApGq1qm63q0wmM82CIFClUlG73XZX7BHValUffPCBhsPhNMtms/rOd74TmY7SVyfzNZtNdTodeZ6nRqPBYBsAAADM9aThMFFZ90LHxYhDRwAAAAAAADy9dDqtvb29mTyVSmk0GjloNKtUKimXyx24N2Wt1WAwiMxBPMlkUtbamY7GmEgNAAcAAAAAIMqMMb+01p6f97HE8y4DAAAAAAAAAEBcNRoNGWMUBIGstQqCQMYYNRoN19WmGo2GCoWCTp48qbW1NZ08eVKFQiFSHQEAAABgnmw2K0lKJBLT69EcAAAAAAAA8ZJOp0PlLnieNzMIaDQayfM8N4UO8fhwaoZVAwAAAACwOAzfAQAAAAAAAADgKdVqNbVaLVUqFQ0GA1UqFbVaLdVqNdfVpmq1mi5duqR+v6/NzU31+31dunQpUh1939fFixd1+/Zt7ezs6Pbt27p48aJ833ddDQAAAIBDly9fliRNJpPp9WgOAAAAAADwPPm+r2q1qlKppGq1GsnnmVHveO7cORUKBaVSKRljlEqlVCgUdO7cOdfVpuJwCM/p06dljJkO3LHWyhij06dPO24GAAAAAMDRwPAdAAAAAAAAAABCqNVqarfb6vV6arfbkRpqI321uPL69esajUYyxmg0Gun69euRWmT51ltvaXd3V5PJRIlEQpPJRLu7u3rrrbdcVwMAAADg0JtvvqlkMnkgSyaTevPNNx01AgAAAAAA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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "def visualize_env():\n",
+ " \n",
+ " dpi, width, height = 10, 800, 400\n",
+ " figsize = width / float(dpi), height / float(dpi)\n",
+ " LabelSize, LegendFontsize, font_gap = 40, 40, 5\n",
+ "\n",
+ " fig = plt.figure(figsize=figsize)\n",
+ "\n",
+ " dynamic_env, _ = create_example_v1(num_per_task=250)\n",
+ " \n",
+ " timeaxis, xaxis, yaxis = [], [], []\n",
+ " for timestamp, dataset in dynamic_env:\n",
+ " num = dataset[0].shape[0]\n",
+ " timeaxis.append(torch.zeros(num) + timestamp)\n",
+ " xaxis.append(dataset[0][:,0])\n",
+ " # compute the ground truth\n",
+ " # function.set_timestamp(timestamp)\n",
+ " yaxis.append(dataset[1][:,0])\n",
+ " \n",
+ " timeaxis = torch.cat(timeaxis).numpy()\n",
+ " # import pdb; pdb.set_trace()\n",
+ " xaxis = torch.cat(xaxis).numpy()\n",
+ " yaxis = torch.cat(yaxis).numpy()\n",
+ "\n",
+ " cur_ax = fig.add_subplot(2, 1, 1)\n",
+ " cur_ax.scatter(timeaxis, xaxis, color=\"k\", linestyle=\"-\", alpha=0.9, label=None)\n",
+ " cur_ax.set_xlabel(\"Time\", fontsize=LabelSize)\n",
+ " cur_ax.set_ylabel(\"X\", rotation=0, fontsize=LabelSize)\n",
+ " for tick in cur_ax.xaxis.get_major_ticks():\n",
+ " tick.label.set_fontsize(LabelSize - font_gap)\n",
+ " tick.label.set_rotation(10)\n",
+ " for tick in cur_ax.yaxis.get_major_ticks():\n",
+ " tick.label.set_fontsize(LabelSize - font_gap)\n",
+ " \n",
+ " cur_ax = fig.add_subplot(2, 1, 2)\n",
+ " cur_ax.scatter(timeaxis, yaxis, color=\"k\", linestyle=\"-\", alpha=0.9, label=None)\n",
+ " cur_ax.set_xlabel(\"Time\", fontsize=LabelSize)\n",
+ " cur_ax.set_ylabel(\"Y\", rotation=0, fontsize=LabelSize)\n",
+ " for tick in cur_ax.xaxis.get_major_ticks():\n",
+ " tick.label.set_fontsize(LabelSize - font_gap)\n",
+ " tick.label.set_rotation(10)\n",
+ " for tick in cur_ax.yaxis.get_major_ticks():\n",
+ " tick.label.set_fontsize(LabelSize - font_gap)\n",
+ " plt.show()\n",
+ "\n",
+ "visualize_env()"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "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.8.8"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/AutoDL-Projects/notebooks/spaces-xmisc/synthetic-visualize-env.ipynb b/AutoDL-Projects/notebooks/spaces-xmisc/synthetic-visualize-env.ipynb
new file mode 100644
index 0000000..3ae2ea1
--- /dev/null
+++ b/AutoDL-Projects/notebooks/spaces-xmisc/synthetic-visualize-env.ipynb
@@ -0,0 +1,152 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "filled-multiple",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "The root path: /Users/xuanyidong/Desktop/AutoDL-Projects\n",
+ "The library path: /Users/xuanyidong/Desktop/AutoDL-Projects/lib\n"
+ ]
+ }
+ ],
+ "source": [
+ "import os, sys\n",
+ "import torch\n",
+ "from pathlib import Path\n",
+ "import numpy as np\n",
+ "import matplotlib\n",
+ "from matplotlib import cm\n",
+ "matplotlib.use(\"agg\")\n",
+ "import matplotlib.pyplot as plt\n",
+ "import matplotlib.ticker as ticker\n",
+ "\n",
+ "\n",
+ "__file__ = os.path.dirname(os.path.realpath(\"__file__\"))\n",
+ "root_dir = (Path(__file__).parent / \"..\").resolve()\n",
+ "lib_dir = (root_dir / \"lib\").resolve()\n",
+ "print(\"The root path: {:}\".format(root_dir))\n",
+ "print(\"The library path: {:}\".format(lib_dir))\n",
+ "assert lib_dir.exists(), \"{:} does not exist\".format(lib_dir)\n",
+ "if str(lib_dir) not in sys.path:\n",
+ " sys.path.insert(0, str(lib_dir))\n",
+ "\n",
+ "from datasets import ConstantGenerator, SinGenerator, SyntheticDEnv\n",
+ "from datasets import DynamicQuadraticFunc\n",
+ "from datasets.synthetic_example import create_example_v1"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "detected-second",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def draw_fig(save_dir, timestamp, xaxis, yaxis):\n",
+ " save_path = save_dir / '{:04d}'.format(timestamp)\n",
+ " # print('Plot the figure at timestamp-{:} into {:}'.format(timestamp, save_path))\n",
+ " dpi, width, height = 40, 1500, 1500\n",
+ " figsize = width / float(dpi), height / float(dpi)\n",
+ " LabelSize, LegendFontsize, font_gap = 80, 80, 5\n",
+ "\n",
+ " fig = plt.figure(figsize=figsize)\n",
+ " \n",
+ " cur_ax = fig.add_subplot(1, 1, 1)\n",
+ " cur_ax.scatter(xaxis, yaxis, color=\"k\", s=10, alpha=0.9, label=\"Timestamp={:02d}\".format(timestamp))\n",
+ " cur_ax.set_xlabel(\"X\", fontsize=LabelSize)\n",
+ " cur_ax.set_ylabel(\"f(X)\", rotation=0, fontsize=LabelSize)\n",
+ " cur_ax.set_xlim(-6, 6)\n",
+ " cur_ax.set_ylim(-40, 40)\n",
+ " for tick in cur_ax.xaxis.get_major_ticks():\n",
+ " tick.label.set_fontsize(LabelSize - font_gap)\n",
+ " tick.label.set_rotation(10)\n",
+ " for tick in cur_ax.yaxis.get_major_ticks():\n",
+ " tick.label.set_fontsize(LabelSize - font_gap)\n",
+ " \n",
+ " plt.legend(loc=1, fontsize=LegendFontsize)\n",
+ " fig.savefig(str(save_path) + '.pdf', dpi=dpi, bbox_inches=\"tight\", format=\"pdf\")\n",
+ " fig.savefig(str(save_path) + '.png', dpi=dpi, bbox_inches=\"tight\", format=\"png\")\n",
+ " plt.close(\"all\")\n",
+ "\n",
+ "\n",
+ "def visualize_env(save_dir):\n",
+ " save_dir.mkdir(parents=True, exist_ok=True)\n",
+ " dynamic_env, function = create_example_v1(100, num_per_task=500)\n",
+ " \n",
+ " additional_xaxis = np.arange(-6, 6, 0.1)\n",
+ " for timestamp, dataset in dynamic_env:\n",
+ " num = dataset.shape[0]\n",
+ " # timeaxis = (torch.zeros(num) + timestamp).numpy()\n",
+ " xaxis = dataset[:,0].numpy()\n",
+ " xaxis = np.concatenate((additional_xaxis, xaxis))\n",
+ " # compute the ground truth\n",
+ " function.set_timestamp(timestamp)\n",
+ " yaxis = function(xaxis)\n",
+ " draw_fig(save_dir, timestamp, xaxis, yaxis)\n",
+ "\n",
+ "home_dir = Path.home()\n",
+ "desktop_dir = home_dir / 'Desktop'\n",
+ "vis_save_dir = desktop_dir / 'vis-synthetic'\n",
+ "visualize_env(vis_save_dir)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "rapid-uruguay",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "ffmpeg -y -i /Users/xuanyidong/Desktop/vis-synthetic/%04d.png -pix_fmt yuv420p -vf fps=2 -vf scale=1000:1000 -vb 5000k /Users/xuanyidong/Desktop/vis-synthetic/vis.mp4\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "0"
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# Plot the data\n",
+ "cmd = 'ffmpeg -y -i {:}/%04d.png -pix_fmt yuv420p -vf fps=2 -vf scale=1000:1000 -vb 5000k {:}/vis.mp4'.format(vis_save_dir, vis_save_dir)\n",
+ "print(cmd)\n",
+ "os.system(cmd)"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "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.8.8"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/AutoDL-Projects/notebooks/spaces-xmisc/test-transformer-encoder.ipynb b/AutoDL-Projects/notebooks/spaces-xmisc/test-transformer-encoder.ipynb
new file mode 100644
index 0000000..89d4452
--- /dev/null
+++ b/AutoDL-Projects/notebooks/spaces-xmisc/test-transformer-encoder.ipynb
@@ -0,0 +1,277 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "3f754c96",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import torch\n",
+ "from xautodl import spaces\n",
+ "from xautodl.xlayers import super_core\n",
+ "\n",
+ "def _create_stel(input_dim, output_dim, order):\n",
+ " return super_core.SuperSequential(\n",
+ " super_core.SuperLinear(input_dim, output_dim),\n",
+ " super_core.SuperTransformerEncoderLayer(\n",
+ " output_dim,\n",
+ " num_heads=spaces.Categorical(2, 4, 6),\n",
+ " mlp_hidden_multiplier=spaces.Categorical(1, 2, 4),\n",
+ " order=order,\n",
+ " ),\n",
+ " )"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "81d42f4b",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "batch, seq_dim, input_dim = 1, 4, 6\n",
+ "order = super_core.LayerOrder.PreNorm"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "8056b37c",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "SuperSequential(\n",
+ " (0): SuperSequential(\n",
+ " (0): SuperLinear(in_features=6, out_features=Categorical(candidates=[12, 24, 36], default_index=None), bias=True)\n",
+ " (1): SuperTransformerEncoderLayer(\n",
+ " (norm1): SuperLayerNorm1D(shape=Categorical(candidates=[12, 24, 36], default_index=None), eps=1e-06, elementwise_affine=True)\n",
+ " (mha): SuperSelfAttention(\n",
+ " input_dim=Categorical(candidates=[12, 24, 36], default_index=None), proj_dim=Categorical(candidates=[12, 24, 36], default_index=None), num_heads=Categorical(candidates=[2, 4, 6], default_index=None), mask=False, infinity=1000000000.0\n",
+ " (q_fc): SuperLinear(in_features=Categorical(candidates=[12, 24, 36], default_index=None), out_features=Categorical(candidates=[12, 24, 36], default_index=None), bias=False)\n",
+ " (k_fc): SuperLinear(in_features=Categorical(candidates=[12, 24, 36], default_index=None), out_features=Categorical(candidates=[12, 24, 36], default_index=None), bias=False)\n",
+ " (v_fc): SuperLinear(in_features=Categorical(candidates=[12, 24, 36], default_index=None), out_features=Categorical(candidates=[12, 24, 36], default_index=None), bias=False)\n",
+ " (attn_drop): SuperDrop(p=0.0, dims=[-1, -1, -1, -1], recover=True)\n",
+ " )\n",
+ " (drop): Dropout(p=0.0, inplace=False)\n",
+ " (norm2): SuperLayerNorm1D(shape=Categorical(candidates=[12, 24, 36], default_index=None), eps=1e-06, elementwise_affine=True)\n",
+ " (mlp): SuperMLPv2(\n",
+ " in_features=Categorical(candidates=[12, 24, 36], default_index=None), hidden_multiplier=Categorical(candidates=[1, 2, 4], default_index=None), out_features=Categorical(candidates=[12, 24, 36], default_index=None), drop=None, fc1 -> act -> drop -> fc2 -> drop,\n",
+ " (_params): ParameterDict(\n",
+ " (fc1_super_weight): Parameter containing: [torch.FloatTensor of size 144x36]\n",
+ " (fc1_super_bias): Parameter containing: [torch.FloatTensor of size 144]\n",
+ " (fc2_super_weight): Parameter containing: [torch.FloatTensor of size 36x144]\n",
+ " (fc2_super_bias): Parameter containing: [torch.FloatTensor of size 36]\n",
+ " )\n",
+ " (act): GELU()\n",
+ " (drop): Dropout(p=0.0, inplace=False)\n",
+ " )\n",
+ " )\n",
+ " )\n",
+ " (1): SuperSequential(\n",
+ " (0): SuperLinear(in_features=Categorical(candidates=[12, 24, 36], default_index=None), out_features=Categorical(candidates=[24, 36, 48], default_index=None), bias=True)\n",
+ " (1): SuperTransformerEncoderLayer(\n",
+ " (norm1): SuperLayerNorm1D(shape=Categorical(candidates=[24, 36, 48], default_index=None), eps=1e-06, elementwise_affine=True)\n",
+ " (mha): SuperSelfAttention(\n",
+ " input_dim=Categorical(candidates=[24, 36, 48], default_index=None), proj_dim=Categorical(candidates=[24, 36, 48], default_index=None), num_heads=Categorical(candidates=[2, 4, 6], default_index=None), mask=False, infinity=1000000000.0\n",
+ " (q_fc): SuperLinear(in_features=Categorical(candidates=[24, 36, 48], default_index=None), out_features=Categorical(candidates=[24, 36, 48], default_index=None), bias=False)\n",
+ " (k_fc): SuperLinear(in_features=Categorical(candidates=[24, 36, 48], default_index=None), out_features=Categorical(candidates=[24, 36, 48], default_index=None), bias=False)\n",
+ " (v_fc): SuperLinear(in_features=Categorical(candidates=[24, 36, 48], default_index=None), out_features=Categorical(candidates=[24, 36, 48], default_index=None), bias=False)\n",
+ " (attn_drop): SuperDrop(p=0.0, dims=[-1, -1, -1, -1], recover=True)\n",
+ " )\n",
+ " (drop): Dropout(p=0.0, inplace=False)\n",
+ " (norm2): SuperLayerNorm1D(shape=Categorical(candidates=[24, 36, 48], default_index=None), eps=1e-06, elementwise_affine=True)\n",
+ " (mlp): SuperMLPv2(\n",
+ " in_features=Categorical(candidates=[24, 36, 48], default_index=None), hidden_multiplier=Categorical(candidates=[1, 2, 4], default_index=None), out_features=Categorical(candidates=[24, 36, 48], default_index=None), drop=None, fc1 -> act -> drop -> fc2 -> drop,\n",
+ " (_params): ParameterDict(\n",
+ " (fc1_super_weight): Parameter containing: [torch.FloatTensor of size 192x48]\n",
+ " (fc1_super_bias): Parameter containing: [torch.FloatTensor of size 192]\n",
+ " (fc2_super_weight): Parameter containing: [torch.FloatTensor of size 48x192]\n",
+ " (fc2_super_bias): Parameter containing: [torch.FloatTensor of size 48]\n",
+ " )\n",
+ " (act): GELU()\n",
+ " (drop): Dropout(p=0.0, inplace=False)\n",
+ " )\n",
+ " )\n",
+ " )\n",
+ " (2): SuperSequential(\n",
+ " (0): SuperLinear(in_features=Categorical(candidates=[24, 36, 48], default_index=None), out_features=Categorical(candidates=[36, 72, 100], default_index=None), bias=True)\n",
+ " (1): SuperTransformerEncoderLayer(\n",
+ " (norm1): SuperLayerNorm1D(shape=Categorical(candidates=[36, 72, 100], default_index=None), eps=1e-06, elementwise_affine=True)\n",
+ " (mha): SuperSelfAttention(\n",
+ " input_dim=Categorical(candidates=[36, 72, 100], default_index=None), proj_dim=Categorical(candidates=[36, 72, 100], default_index=None), num_heads=Categorical(candidates=[2, 4, 6], default_index=None), mask=False, infinity=1000000000.0\n",
+ " (q_fc): SuperLinear(in_features=Categorical(candidates=[36, 72, 100], default_index=None), out_features=Categorical(candidates=[36, 72, 100], default_index=None), bias=False)\n",
+ " (k_fc): SuperLinear(in_features=Categorical(candidates=[36, 72, 100], default_index=None), out_features=Categorical(candidates=[36, 72, 100], default_index=None), bias=False)\n",
+ " (v_fc): SuperLinear(in_features=Categorical(candidates=[36, 72, 100], default_index=None), out_features=Categorical(candidates=[36, 72, 100], default_index=None), bias=False)\n",
+ " (attn_drop): SuperDrop(p=0.0, dims=[-1, -1, -1, -1], recover=True)\n",
+ " )\n",
+ " (drop): Dropout(p=0.0, inplace=False)\n",
+ " (norm2): SuperLayerNorm1D(shape=Categorical(candidates=[36, 72, 100], default_index=None), eps=1e-06, elementwise_affine=True)\n",
+ " (mlp): SuperMLPv2(\n",
+ " in_features=Categorical(candidates=[36, 72, 100], default_index=None), hidden_multiplier=Categorical(candidates=[1, 2, 4], default_index=None), out_features=Categorical(candidates=[36, 72, 100], default_index=None), drop=None, fc1 -> act -> drop -> fc2 -> drop,\n",
+ " (_params): ParameterDict(\n",
+ " (fc1_super_weight): Parameter containing: [torch.FloatTensor of size 400x100]\n",
+ " (fc1_super_bias): Parameter containing: [torch.FloatTensor of size 400]\n",
+ " (fc2_super_weight): Parameter containing: [torch.FloatTensor of size 100x400]\n",
+ " (fc2_super_bias): Parameter containing: [torch.FloatTensor of size 100]\n",
+ " )\n",
+ " (act): GELU()\n",
+ " (drop): Dropout(p=0.0, inplace=False)\n",
+ " )\n",
+ " )\n",
+ " )\n",
+ ")\n"
+ ]
+ }
+ ],
+ "source": [
+ "out1_dim = spaces.Categorical(12, 24, 36)\n",
+ "out2_dim = spaces.Categorical(24, 36, 48)\n",
+ "out3_dim = spaces.Categorical(36, 72, 100)\n",
+ "layer1 = _create_stel(input_dim, out1_dim, order)\n",
+ "layer2 = _create_stel(out1_dim, out2_dim, order)\n",
+ "layer3 = _create_stel(out2_dim, out3_dim, order)\n",
+ "model = super_core.SuperSequential(layer1, layer2, layer3)\n",
+ "print(model)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "4fd53a7c",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "> \u001b[0;32m/Users/xuanyidong/anaconda3/lib/python3.8/site-packages/xautodl-0.9.9-py3.8.egg/xautodl/xlayers/super_transformer.py\u001b[0m(116)\u001b[0;36mforward_raw\u001b[0;34m()\u001b[0m\n",
+ "\u001b[0;32m 114 \u001b[0;31m \u001b[0;32mimport\u001b[0m \u001b[0mpdb\u001b[0m\u001b[0;34m;\u001b[0m \u001b[0mpdb\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mset_trace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0m\u001b[0;32m 115 \u001b[0;31m \u001b[0;31m# feed-forward layer -- MLP\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0m\u001b[0;32m--> 116 \u001b[0;31m \u001b[0my\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnorm2\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0m\u001b[0;32m 117 \u001b[0;31m \u001b[0mouts\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmlp\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0my\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0m\u001b[0;32m 118 \u001b[0;31m \u001b[0;32melif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_order\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0mLayerOrder\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mPostNorm\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0m\n",
+ "ipdb> print(self)\n",
+ "SuperTransformerEncoderLayer(\n",
+ " (norm1): SuperLayerNorm1D(shape=Categorical(candidates=[36, 72, 100], default_index=None), eps=1e-06, elementwise_affine=True)\n",
+ " (mha): SuperSelfAttention(\n",
+ " input_dim=Categorical(candidates=[36, 72, 100], default_index=None), proj_dim=Categorical(candidates=[36, 72, 100], default_index=None), num_heads=Categorical(candidates=[2, 4, 6], default_index=None), mask=False, infinity=1000000000.0\n",
+ " (q_fc): SuperLinear(in_features=Categorical(candidates=[36, 72, 100], default_index=None), out_features=Categorical(candidates=[36, 72, 100], default_index=None), bias=False)\n",
+ " (k_fc): SuperLinear(in_features=Categorical(candidates=[36, 72, 100], default_index=None), out_features=Categorical(candidates=[36, 72, 100], default_index=None), bias=False)\n",
+ " (v_fc): SuperLinear(in_features=Categorical(candidates=[36, 72, 100], default_index=None), out_features=Categorical(candidates=[36, 72, 100], default_index=None), bias=False)\n",
+ " (attn_drop): SuperDrop(p=0.0, dims=[-1, -1, -1, -1], recover=True)\n",
+ " )\n",
+ " (drop): Dropout(p=0.0, inplace=False)\n",
+ " (norm2): SuperLayerNorm1D(shape=Categorical(candidates=[36, 72, 100], default_index=None), eps=1e-06, elementwise_affine=True)\n",
+ " (mlp): SuperMLPv2(\n",
+ " in_features=Categorical(candidates=[36, 72, 100], default_index=None), hidden_multiplier=Categorical(candidates=[1, 2, 4], default_index=None), out_features=Categorical(candidates=[36, 72, 100], default_index=None), drop=None, fc1 -> act -> drop -> fc2 -> drop,\n",
+ " (_params): ParameterDict(\n",
+ " (fc1_super_weight): Parameter containing: [torch.FloatTensor of size 400x100]\n",
+ " (fc1_super_bias): Parameter containing: [torch.FloatTensor of size 400]\n",
+ " (fc2_super_weight): Parameter containing: [torch.FloatTensor of size 100x400]\n",
+ " (fc2_super_bias): Parameter containing: [torch.FloatTensor of size 100]\n",
+ " )\n",
+ " (act): GELU()\n",
+ " (drop): Dropout(p=0.0, inplace=False)\n",
+ " )\n",
+ ")\n",
+ "ipdb> print(inputs.shape)\n",
+ "torch.Size([1, 4, 100])\n",
+ "ipdb> print(x.shape)\n",
+ "torch.Size([1, 4, 96])\n",
+ "ipdb> print(self.mha)\n",
+ "SuperSelfAttention(\n",
+ " input_dim=Categorical(candidates=[36, 72, 100], default_index=None), proj_dim=Categorical(candidates=[36, 72, 100], default_index=None), num_heads=Categorical(candidates=[2, 4, 6], default_index=None), mask=False, infinity=1000000000.0\n",
+ " (q_fc): SuperLinear(in_features=Categorical(candidates=[36, 72, 100], default_index=None), out_features=Categorical(candidates=[36, 72, 100], default_index=None), bias=False)\n",
+ " (k_fc): SuperLinear(in_features=Categorical(candidates=[36, 72, 100], default_index=None), out_features=Categorical(candidates=[36, 72, 100], default_index=None), bias=False)\n",
+ " (v_fc): SuperLinear(in_features=Categorical(candidates=[36, 72, 100], default_index=None), out_features=Categorical(candidates=[36, 72, 100], default_index=None), bias=False)\n",
+ " (attn_drop): SuperDrop(p=0.0, dims=[-1, -1, -1, -1], recover=True)\n",
+ ")\n",
+ "ipdb> print(self.mha.candidate)\n",
+ "*** AttributeError: 'SuperSelfAttention' object has no attribute 'candidate'\n",
+ "ipdb> print(self.mha.abstract_candidate)\n",
+ "*** AttributeError: 'SuperSelfAttention' object has no attribute 'abstract_candidate'\n",
+ "ipdb> print(self.mha._abstract_child)\n",
+ "None\n",
+ "ipdb> print(self.abstract_child)\n",
+ "None\n",
+ "ipdb> print(self.abstract_child.abstract_child)\n",
+ "*** AttributeError: 'NoneType' object has no attribute 'abstract_child'\n",
+ "ipdb> print(self.mha)\n",
+ "SuperSelfAttention(\n",
+ " input_dim=Categorical(candidates=[36, 72, 100], default_index=None), proj_dim=Categorical(candidates=[36, 72, 100], default_index=None), num_heads=Categorical(candidates=[2, 4, 6], default_index=None), mask=False, infinity=1000000000.0\n",
+ " (q_fc): SuperLinear(in_features=Categorical(candidates=[36, 72, 100], default_index=None), out_features=Categorical(candidates=[36, 72, 100], default_index=None), bias=False)\n",
+ " (k_fc): SuperLinear(in_features=Categorical(candidates=[36, 72, 100], default_index=None), out_features=Categorical(candidates=[36, 72, 100], default_index=None), bias=False)\n",
+ " (v_fc): SuperLinear(in_features=Categorical(candidates=[36, 72, 100], default_index=None), out_features=Categorical(candidates=[36, 72, 100], default_index=None), bias=False)\n",
+ " (attn_drop): SuperDrop(p=0.0, dims=[-1, -1, -1, -1], recover=True)\n",
+ ")\n"
+ ]
+ }
+ ],
+ "source": [
+ "inputs = torch.rand(batch, seq_dim, input_dim)\n",
+ "outputs = model(inputs)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "05332b98",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "abstract_space = model.abstract_search_space\n",
+ "abstract_space.clean_last()\n",
+ "abstract_child = abstract_space.random(reuse_last=True)\n",
+ "# print(\"The abstract child program is:\\n{:}\".format(abstract_child))\n",
+ "model.enable_candidate()\n",
+ "model.set_super_run_type(super_core.SuperRunMode.Candidate)\n",
+ "model.apply_candidate(abstract_child)\n",
+ "outputs = model(inputs)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "3289f938",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "print(outputs.shape)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "36951cdf",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "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.8.8"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/BOHB.sh b/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/BOHB.sh
new file mode 100644
index 0000000..4a65276
--- /dev/null
+++ b/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/BOHB.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+# bash ./scripts-search/NAS-Bench-201-algos/BOHB.sh -1
+echo script name: $0
+echo $# arguments
+if [ "$#" -ne 2 ] ;then
+ echo "Input illegal number of parameters " $#
+ echo "Need 2 parameters for dataset and seed"
+ exit 1
+fi
+if [ "$TORCH_HOME" = "" ]; then
+ echo "Must set TORCH_HOME envoriment variable for data dir saving"
+ exit 1
+else
+ echo "TORCH_HOME : $TORCH_HOME"
+fi
+
+dataset=$1
+seed=$2
+channel=16
+num_cells=5
+max_nodes=4
+space=nas-bench-201
+#benchmark_file=${TORCH_HOME}/NAS-Bench-201-v1_0-e61699.pth
+benchmark_file=${TORCH_HOME}/NAS-Bench-201-v1_1-096897.pth
+
+save_dir=./output/search-cell-${space}/BOHB-${dataset}
+
+OMP_NUM_THREADS=4 python ./exps/NAS-Bench-201-algos/BOHB.py \
+ --save_dir ${save_dir} --max_nodes ${max_nodes} --channel ${channel} --num_cells ${num_cells} \
+ --dataset ${dataset} \
+ --search_space_name ${space} \
+ --arch_nas_dataset ${benchmark_file} \
+ --time_budget 12000 \
+ --n_iters 50 --num_samples 4 --random_fraction 0.0 --bandwidth_factor 3 \
+ --workers 4 --print_freq 200 --rand_seed ${seed}
diff --git a/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/DARTS-V1.sh b/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/DARTS-V1.sh
new file mode 100644
index 0000000..bcd4acc
--- /dev/null
+++ b/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/DARTS-V1.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+# bash ./scripts-search/NAS-Bench-201-algos/DARTS-V1.sh cifar10 0 -1
+echo script name: $0
+echo $# arguments
+if [ "$#" -ne 3 ] ;then
+ echo "Input illegal number of parameters " $#
+ echo "Need 3 parameters for dataset, tracking_status, and seed"
+ exit 1
+fi
+if [ "$TORCH_HOME" = "" ]; then
+ echo "Must set TORCH_HOME envoriment variable for data dir saving"
+ exit 1
+else
+ echo "TORCH_HOME : $TORCH_HOME"
+fi
+
+dataset=$1
+BN=$2
+seed=$3
+channel=16
+num_cells=5
+max_nodes=4
+space=nas-bench-201
+
+if [ "$dataset" == "cifar10" ] || [ "$dataset" == "cifar100" ]; then
+ data_path="$TORCH_HOME/cifar.python"
+else
+ data_path="$TORCH_HOME/cifar.python/ImageNet16"
+fi
+#benchmark_file=${TORCH_HOME}/NAS-Bench-201-v1_0-e61699.pth
+benchmark_file=${TORCH_HOME}/NAS-Bench-201-v1_1-096897.pth
+
+save_dir=./output/search-cell-${space}/DARTS-V1-${dataset}-BN${BN}
+
+OMP_NUM_THREADS=4 python ./exps/NAS-Bench-201-algos/DARTS-V1.py \
+ --save_dir ${save_dir} --max_nodes ${max_nodes} --channel ${channel} --num_cells ${num_cells} \
+ --dataset ${dataset} --data_path ${data_path} \
+ --search_space_name ${space} \
+ --config_path configs/nas-benchmark/algos/DARTS.config \
+ --arch_nas_dataset ${benchmark_file} \
+ --track_running_stats ${BN} \
+ --arch_learning_rate 0.0003 --arch_weight_decay 0.001 \
+ --workers 4 --print_freq 200 --rand_seed ${seed}
diff --git a/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/DARTS-V2.sh b/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/DARTS-V2.sh
new file mode 100644
index 0000000..a99400c
--- /dev/null
+++ b/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/DARTS-V2.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+# bash ./scripts-search/NAS-Bench-201-algos/DARTS-V2.sh cifar10 0 -1
+echo script name: $0
+echo $# arguments
+if [ "$#" -ne 3 ] ;then
+ echo "Input illegal number of parameters " $#
+ echo "Need 3 parameters for dataset, tracking_status, and seed"
+ exit 1
+fi
+if [ "$TORCH_HOME" = "" ]; then
+ echo "Must set TORCH_HOME envoriment variable for data dir saving"
+ exit 1
+else
+ echo "TORCH_HOME : $TORCH_HOME"
+fi
+
+dataset=$1
+BN=$2
+seed=$3
+channel=16
+num_cells=5
+max_nodes=4
+space=nas-bench-201
+
+if [ "$dataset" == "cifar10" ] || [ "$dataset" == "cifar100" ]; then
+ data_path="$TORCH_HOME/cifar.python"
+else
+ data_path="$TORCH_HOME/cifar.python/ImageNet16"
+fi
+#benchmark_file=${TORCH_HOME}/NAS-Bench-201-v1_0-e61699.pth
+benchmark_file=${TORCH_HOME}/NAS-Bench-201-v1_1-096897.pth
+
+save_dir=./output/search-cell-${space}/DARTS-V2-${dataset}-BN${BN}
+
+OMP_NUM_THREADS=4 python ./exps/NAS-Bench-201-algos/DARTS-V2.py \
+ --save_dir ${save_dir} --max_nodes ${max_nodes} --channel ${channel} --num_cells ${num_cells} \
+ --dataset ${dataset} --data_path ${data_path} \
+ --search_space_name ${space} \
+ --config_path configs/nas-benchmark/algos/DARTS.config \
+ --arch_nas_dataset ${benchmark_file} \
+ --track_running_stats ${BN} \
+ --arch_learning_rate 0.0003 --arch_weight_decay 0.001 \
+ --workers 4 --print_freq 200 --rand_seed ${seed}
diff --git a/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/ENAS.sh b/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/ENAS.sh
new file mode 100644
index 0000000..f00ea5f
--- /dev/null
+++ b/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/ENAS.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+# Efficient Neural Architecture Search via Parameter Sharing, ICML 2018
+# bash ./scripts-search/NAS-Bench-201-algos/ENAS.sh cifar10 0 -1
+echo script name: $0
+echo $# arguments
+if [ "$#" -ne 3 ] ;then
+ echo "Input illegal number of parameters " $#
+ echo "Need 3 parameters for dataset, BN-tracking-status, and seed"
+ exit 1
+fi
+if [ "$TORCH_HOME" = "" ]; then
+ echo "Must set TORCH_HOME envoriment variable for data dir saving"
+ exit 1
+else
+ echo "TORCH_HOME : $TORCH_HOME"
+fi
+
+dataset=$1
+BN=$2
+seed=$3
+channel=16
+num_cells=5
+max_nodes=4
+space=nas-bench-201
+
+if [ "$dataset" == "cifar10" ] || [ "$dataset" == "cifar100" ]; then
+ data_path="$TORCH_HOME/cifar.python"
+else
+ data_path="$TORCH_HOME/cifar.python/ImageNet16"
+fi
+#benchmark_file=${TORCH_HOME}/NAS-Bench-201-v1_0-e61699.pth
+benchmark_file=${TORCH_HOME}/NAS-Bench-201-v1_1-096897.pth
+
+save_dir=./output/search-cell-${space}/ENAS-${dataset}-BN${BN}
+
+OMP_NUM_THREADS=4 python ./exps/NAS-Bench-201-algos/ENAS.py \
+ --save_dir ${save_dir} --max_nodes ${max_nodes} --channel ${channel} --num_cells ${num_cells} \
+ --dataset ${dataset} --data_path ${data_path} \
+ --search_space_name ${space} \
+ --arch_nas_dataset ${benchmark_file} \
+ --track_running_stats ${BN} \
+ --config_path ./configs/nas-benchmark/algos/ENAS.config \
+ --controller_entropy_weight 0.0001 \
+ --controller_bl_dec 0.99 \
+ --controller_train_steps 50 \
+ --controller_num_aggregate 20 \
+ --controller_num_samples 100 \
+ --workers 4 --print_freq 200 --rand_seed ${seed}
diff --git a/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/GDAS.sh b/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/GDAS.sh
new file mode 100644
index 0000000..7b26abb
--- /dev/null
+++ b/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/GDAS.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+# bash ./scripts-search/NAS-Bench-201-algos/GDAS.sh cifar10 0 -1
+echo script name: $0
+echo $# arguments
+if [ "$#" -ne 3 ] ;then
+ echo "Input illegal number of parameters " $#
+ echo "Need 3 parameters for dataset, BN-tracking, and seed"
+ exit 1
+fi
+if [ "$TORCH_HOME" = "" ]; then
+ echo "Must set TORCH_HOME envoriment variable for data dir saving"
+ exit 1
+else
+ echo "TORCH_HOME : $TORCH_HOME"
+fi
+
+dataset=$1
+BN=$2
+seed=$3
+channel=16
+num_cells=5
+max_nodes=4
+space=nas-bench-201
+
+if [ "$dataset" == "cifar10" ] || [ "$dataset" == "cifar100" ]; then
+ data_path="$TORCH_HOME/cifar.python"
+else
+ data_path="$TORCH_HOME/cifar.python/ImageNet16"
+fi
+#benchmark_file=${TORCH_HOME}/NAS-Bench-201-v1_0-e61699.pth
+benchmark_file=${TORCH_HOME}/NAS-Bench-201-v1_1-096897.pth
+
+save_dir=./output/search-cell-${space}/GDAS-${dataset}-BN${BN}
+
+OMP_NUM_THREADS=4 python ./exps/NAS-Bench-201-algos/GDAS.py \
+ --save_dir ${save_dir} --max_nodes ${max_nodes} --channel ${channel} --num_cells ${num_cells} \
+ --dataset ${dataset} --data_path ${data_path} \
+ --search_space_name ${space} \
+ --arch_nas_dataset ${benchmark_file} \
+ --config_path configs/nas-benchmark/algos/GDAS.config \
+ --tau_max 10 --tau_min 0.1 --track_running_stats ${BN} \
+ --arch_learning_rate 0.0003 --arch_weight_decay 0.001 \
+ --workers 4 --print_freq 200 --rand_seed ${seed}
diff --git a/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/R-EA.sh b/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/R-EA.sh
new file mode 100644
index 0000000..08ff15d
--- /dev/null
+++ b/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/R-EA.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+# Regularized Evolution for Image Classifier Architecture Search, AAAI 2019
+# bash ./scripts-search/NAS-Bench-201-algos/R-EA.sh cifar10 3 -1
+echo script name: $0
+echo $# arguments
+if [ "$#" -ne 3 ] ;then
+ echo "Input illegal number of parameters " $#
+ echo "Need 3 parameters for the-dataset-name, the-ea-sample-size and the-seed"
+ exit 1
+fi
+if [ "$TORCH_HOME" = "" ]; then
+ echo "Must set TORCH_HOME envoriment variable for data dir saving"
+ exit 1
+else
+ echo "TORCH_HOME : $TORCH_HOME"
+fi
+
+#dataset=cifar10
+dataset=$1
+sample_size=$2
+seed=$3
+channel=16
+num_cells=5
+max_nodes=4
+space=nas-bench-201
+#benchmark_file=${TORCH_HOME}/NAS-Bench-201-v1_0-e61699.pth
+benchmark_file=${TORCH_HOME}/NAS-Bench-201-v1_1-096897.pth
+
+save_dir=./output/search-cell-${space}/R-EA-${dataset}-SS${sample_size}
+
+OMP_NUM_THREADS=4 python ./exps/NAS-Bench-201-algos/R_EA.py \
+ --save_dir ${save_dir} --max_nodes ${max_nodes} --channel ${channel} --num_cells ${num_cells} \
+ --dataset ${dataset} \
+ --search_space_name ${space} \
+ --arch_nas_dataset ${benchmark_file} \
+ --time_budget 12000 \
+ --ea_cycles 200 --ea_population 10 --ea_sample_size ${sample_size} --ea_fast_by_api 1 \
+ --workers 4 --print_freq 200 --rand_seed ${seed}
diff --git a/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/RANDOM-NAS.sh b/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/RANDOM-NAS.sh
new file mode 100644
index 0000000..f6d1be9
--- /dev/null
+++ b/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/RANDOM-NAS.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+# Random Search and Reproducibility for Neural Architecture Search, UAI 2019
+# bash ./scripts-search/NAS-Bench-201-algos/RANDOM-NAS.sh cifar10 0 -1
+echo script name: $0
+echo $# arguments
+if [ "$#" -ne 3 ] ;then
+ echo "Input illegal number of parameters " $#
+ echo "Need 3 parameters for dataset, BN-tracking-status, and seed"
+ exit 1
+fi
+if [ "$TORCH_HOME" = "" ]; then
+ echo "Must set TORCH_HOME envoriment variable for data dir saving"
+ exit 1
+else
+ echo "TORCH_HOME : $TORCH_HOME"
+fi
+
+dataset=$1
+BN=$2
+seed=$3
+channel=16
+num_cells=5
+max_nodes=4
+space=nas-bench-201
+
+if [ "$dataset" == "cifar10" ] || [ "$dataset" == "cifar100" ]; then
+ data_path="$TORCH_HOME/cifar.python"
+else
+ data_path="$TORCH_HOME/cifar.python/ImageNet16"
+fi
+#benchmark_file=${TORCH_HOME}/NAS-Bench-201-v1_0-e61699.pth
+benchmark_file=${TORCH_HOME}/NAS-Bench-201-v1_1-096897.pth
+
+save_dir=./output/search-cell-${space}/RANDOM-NAS-${dataset}-BN${BN}
+
+OMP_NUM_THREADS=4 python ./exps/NAS-Bench-201-algos/RANDOM-NAS.py \
+ --save_dir ${save_dir} --max_nodes ${max_nodes} --channel ${channel} --num_cells ${num_cells} \
+ --dataset ${dataset} --data_path ${data_path} \
+ --search_space_name ${space} \
+ --track_running_stats ${BN} \
+ --arch_nas_dataset ${benchmark_file} \
+ --config_path ./configs/nas-benchmark/algos/RANDOM.config \
+ --select_num 100 \
+ --workers 4 --print_freq 200 --rand_seed ${seed}
diff --git a/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/README.md b/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/README.md
new file mode 100644
index 0000000..2edc677
--- /dev/null
+++ b/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/README.md
@@ -0,0 +1,3 @@
+# 10 NAS algorithms in NAS-Bench-201
+
+Each script in this folder corresponds to one NAS algorithm, you can simple run it by one command.
diff --git a/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/REINFORCE.sh b/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/REINFORCE.sh
new file mode 100644
index 0000000..a120131
--- /dev/null
+++ b/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/REINFORCE.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+# bash ./scripts-search/NAS-Bench-201-algos/REINFORCE.sh 0.001 -1
+echo script name: $0
+echo $# arguments
+if [ "$#" -ne 3 ] ;then
+ echo "Input illegal number of parameters " $#
+ echo "Need 3 parameters for dataset, LR, and seed"
+ exit 1
+fi
+if [ "$TORCH_HOME" = "" ]; then
+ echo "Must set TORCH_HOME envoriment variable for data dir saving"
+ exit 1
+else
+ echo "TORCH_HOME : $TORCH_HOME"
+fi
+
+dataset=$1
+LR=$2
+seed=$3
+channel=16
+num_cells=5
+max_nodes=4
+space=nas-bench-201
+#benchmark_file=${TORCH_HOME}/NAS-Bench-201-v1_0-e61699.pth
+benchmark_file=${TORCH_HOME}/NAS-Bench-201-v1_1-096897.pth
+
+save_dir=./output/search-cell-${space}/REINFORCE-${dataset}-${LR}
+
+OMP_NUM_THREADS=4 python ./exps/NAS-Bench-201-algos/reinforce.py \
+ --save_dir ${save_dir} --max_nodes ${max_nodes} --channel ${channel} --num_cells ${num_cells} \
+ --dataset ${dataset} \
+ --search_space_name ${space} \
+ --arch_nas_dataset ${benchmark_file} \
+ --time_budget 12000 \
+ --learning_rate ${LR} --EMA_momentum 0.9 \
+ --workers 4 --print_freq 200 --rand_seed ${seed}
diff --git a/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/Random.sh b/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/Random.sh
new file mode 100644
index 0000000..6bb34fd
--- /dev/null
+++ b/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/Random.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# bash ./scripts-search/NAS-Bench-201-algos/Random.sh -1
+echo script name: $0
+echo $# arguments
+if [ "$#" -ne 2 ] ;then
+ echo "Input illegal number of parameters " $#
+ echo "Need 2 parameters for dataset and seed"
+ exit 1
+fi
+if [ "$TORCH_HOME" = "" ]; then
+ echo "Must set TORCH_HOME envoriment variable for data dir saving"
+ exit 1
+else
+ echo "TORCH_HOME : $TORCH_HOME"
+fi
+
+dataset=$1
+seed=$2
+channel=16
+num_cells=5
+max_nodes=4
+space=nas-bench-201
+#benchmark_file=${TORCH_HOME}/NAS-Bench-201-v1_0-e61699.pth
+benchmark_file=${TORCH_HOME}/NAS-Bench-201-v1_1-096897.pth
+
+save_dir=./output/search-cell-${space}/RAND-${dataset}
+
+OMP_NUM_THREADS=4 python ./exps/NAS-Bench-201-algos/RANDOM.py \
+ --save_dir ${save_dir} --max_nodes ${max_nodes} --channel ${channel} --num_cells ${num_cells} \
+ --dataset ${dataset} \
+ --search_space_name ${space} \
+ --arch_nas_dataset ${benchmark_file} \
+ --time_budget 12000 \
+ --workers 4 --print_freq 200 --rand_seed ${seed}
diff --git a/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/SETN.sh b/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/SETN.sh
new file mode 100644
index 0000000..c2f1301
--- /dev/null
+++ b/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/SETN.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+# One-Shot Neural Architecture Search via Self-Evaluated Template Network, ICCV 2019
+# bash ./scripts-search/NAS-Bench-201-algos/SETN.sh cifar10 0 -1
+echo script name: $0
+echo $# arguments
+if [ "$#" -ne 3 ] ;then
+ echo "Input illegal number of parameters " $#
+ echo "Need 3 parameters for dataset, BN-tracking-status, and seed"
+ exit 1
+fi
+if [ "$TORCH_HOME" = "" ]; then
+ echo "Must set TORCH_HOME envoriment variable for data dir saving"
+ exit 1
+else
+ echo "TORCH_HOME : $TORCH_HOME"
+fi
+
+dataset=$1
+BN=$2
+seed=$3
+channel=16
+num_cells=5
+max_nodes=4
+space=nas-bench-201
+
+if [ "$dataset" == "cifar10" ] || [ "$dataset" == "cifar100" ]; then
+ data_path="$TORCH_HOME/cifar.python"
+else
+ data_path="$TORCH_HOME/cifar.python/ImageNet16"
+fi
+#benchmark_file=${TORCH_HOME}/NAS-Bench-201-v1_0-e61699.pth
+benchmark_file=${TORCH_HOME}/NAS-Bench-201-v1_1-096897.pth
+
+save_dir=./output/search-cell-${space}/SETN-${dataset}-BN${BN}
+
+OMP_NUM_THREADS=4 python ./exps/NAS-Bench-201-algos/SETN.py \
+ --save_dir ${save_dir} --max_nodes ${max_nodes} --channel ${channel} --num_cells ${num_cells} \
+ --dataset ${dataset} --data_path ${data_path} \
+ --search_space_name ${space} \
+ --arch_nas_dataset ${benchmark_file} \
+ --config_path configs/nas-benchmark/algos/SETN.config \
+ --track_running_stats ${BN} \
+ --arch_learning_rate 0.0003 --arch_weight_decay 0.001 \
+ --select_num 100 \
+ --workers 4 --print_freq 200 --rand_seed ${seed}
diff --git a/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/hps/DARTS-test-Gradient.sh b/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/hps/DARTS-test-Gradient.sh
new file mode 100644
index 0000000..73f6e2e
--- /dev/null
+++ b/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/hps/DARTS-test-Gradient.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+# bash ./scripts-search/NAS-Bench-201-algos/DARTS-test-Gradient.sh cifar10 0 5
+echo script name: $0
+echo $# arguments
+if [ "$#" -ne 3 ] ;then
+ echo "Input illegal number of parameters " $#
+ echo "Need 3 parameters for dataset, tracking_status, and gradient_clip"
+ exit 1
+fi
+if [ "$TORCH_HOME" = "" ]; then
+ echo "Must set TORCH_HOME envoriment variable for data dir saving"
+ exit 1
+else
+ echo "TORCH_HOME : $TORCH_HOME"
+fi
+
+dataset=$1
+BN=$2
+gradient_clip=$3
+seed=-1
+channel=16
+num_cells=5
+max_nodes=4
+space=nas-bench-201
+
+if [ "$dataset" == "cifar10" ] || [ "$dataset" == "cifar100" ]; then
+ data_path="$TORCH_HOME/cifar.python"
+else
+ data_path="$TORCH_HOME/cifar.python/ImageNet16"
+fi
+#benchmark_file=${TORCH_HOME}/NAS-Bench-201-v1_0-e61699.pth
+benchmark_file=${TORCH_HOME}/NAS-Bench-201-v1_1-096897.pth
+
+save_dir=./output/search-cell-${space}/DARTS-V1-${dataset}-BN${BN}-Gradient${gradient_clip}
+
+OMP_NUM_THREADS=4 python ./exps/NAS-Bench-201-algos/DARTS-V1.py \
+ --save_dir ${save_dir} --max_nodes ${max_nodes} --channel ${channel} --num_cells ${num_cells} \
+ --dataset ${dataset} --data_path ${data_path} \
+ --search_space_name ${space} \
+ --config_path configs/nas-benchmark/algos/DARTS.config \
+ --arch_nas_dataset ${benchmark_file} \
+ --track_running_stats ${BN} --gradient_clip ${gradient_clip} \
+ --arch_learning_rate 0.0003 --arch_weight_decay 0.001 \
+ --workers 4 --print_freq 200 --rand_seed ${seed}
diff --git a/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/hps/GRID-RL.sh b/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/hps/GRID-RL.sh
new file mode 100644
index 0000000..8684d4d
--- /dev/null
+++ b/AutoDL-Projects/scripts-search/NAS-Bench-201-algos/hps/GRID-RL.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+echo script name: $0
+
+#lrs="0.01 0.02 0.1 0.2 0.5 1.0 1.5 2.0 2.5 3.0"
+lrs="0.01 0.02 0.1 0.2 0.5"
+
+for lr in ${lrs}
+do
+ bash ./scripts-search/NAS-Bench-201-algos/REINFORCE.sh ${lr} -1
+done
diff --git a/AutoDL-Projects/scripts-search/NAS-Bench-201/build.sh b/AutoDL-Projects/scripts-search/NAS-Bench-201/build.sh
new file mode 100644
index 0000000..fa87746
--- /dev/null
+++ b/AutoDL-Projects/scripts-search/NAS-Bench-201/build.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+# bash scripts-search/NAS-Bench-201/build.sh
+echo script name: $0
+echo $# arguments
+if [ "$#" -ne 0 ] ;then
+ echo "Input illegal number of parameters " $#
+ echo "Need 0 parameters"
+ exit 1
+fi
+
+save_dir=./output/nas_bench_201_package
+echo "Prepare to build the package in ${save_dir}"
+rm -rf ${save_dir}
+mkdir -p ${save_dir}
+
+#cp NAS-Bench-201.md ${save_dir}/README.md
+sed '125,187d' NAS-Bench-201.md > ${save_dir}/README.md
+cp LICENSE.md ${save_dir}/LICENSE.md
+cp -r lib/nas_201_api ${save_dir}/
+rm -rf ${save_dir}/nas_201_api/__pycache__
+cp exps/NAS-Bench-201/dist-setup.py ${save_dir}/setup.py
+
+cd ${save_dir}
+# python setup.py sdist bdist_wheel
+# twine upload --repository-url https://test.pypi.org/legacy/ dist/*
+# twine upload dist/*
diff --git a/AutoDL-Projects/scripts-search/NAS-Bench-201/meta-gen.sh b/AutoDL-Projects/scripts-search/NAS-Bench-201/meta-gen.sh
new file mode 100644
index 0000000..a62d2a1
--- /dev/null
+++ b/AutoDL-Projects/scripts-search/NAS-Bench-201/meta-gen.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# bash scripts-search/NAS-Bench-201/meta-gen.sh NAS-BENCH-201 4
+echo script name: $0
+echo $# arguments
+if [ "$#" -ne 2 ] ;then
+ echo "Input illegal number of parameters " $#
+ echo "Need 2 parameters for save-dir-name and maximum-node-in-cell"
+ exit 1
+fi
+
+name=$1
+node=$2
+
+save_dir=./output/${name}-${node}
+
+python ./exps/NAS-Bench-201/main.py --mode meta --save_dir ${save_dir} --max_node ${node}
diff --git a/AutoDL-Projects/scripts-search/NAS-Bench-201/train-a-net.sh b/AutoDL-Projects/scripts-search/NAS-Bench-201/train-a-net.sh
new file mode 100644
index 0000000..12eda2c
--- /dev/null
+++ b/AutoDL-Projects/scripts-search/NAS-Bench-201/train-a-net.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# bash ./scripts-search/NAS-Bench-201/train-a-net.sh resnet 16 5
+echo script name: $0
+echo $# arguments
+if [ "$#" -ne 3 ] ;then
+ echo "Input illegal number of parameters " $#
+ echo "Need 3 parameters for network, channel, num-of-cells"
+ exit 1
+fi
+if [ "$TORCH_HOME" = "" ]; then
+ echo "Must set TORCH_HOME envoriment variable for data dir saving"
+ exit 1
+else
+ echo "TORCH_HOME : $TORCH_HOME"
+fi
+
+model=$1
+channel=$2
+num_cells=$3
+
+save_dir=./output/NAS-BENCH-201-4/
+
+OMP_NUM_THREADS=4 python ./exps/NAS-Bench-201/main.py \
+ --mode specific-${model} --save_dir ${save_dir} --max_node 4 \
+ --datasets cifar10 cifar10 cifar100 ImageNet16-120 \
+ --use_less 0 \
+ --splits 1 0 0 0 \
+ --xpaths $TORCH_HOME/cifar.python \
+ $TORCH_HOME/cifar.python \
+ $TORCH_HOME/cifar.python \
+ $TORCH_HOME/cifar.python/ImageNet16 \
+ --channel ${channel} --num_cells ${num_cells} \
+ --workers 4 \
+ --seeds 777 888 999
diff --git a/AutoDL-Projects/scripts-search/NAS-Bench-201/train-models.sh b/AutoDL-Projects/scripts-search/NAS-Bench-201/train-models.sh
new file mode 100644
index 0000000..f691f40
--- /dev/null
+++ b/AutoDL-Projects/scripts-search/NAS-Bench-201/train-models.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+# bash ./scripts-search/train-models.sh 0/1 0 100 -1 '777 888 999'
+echo script name: $0
+echo $# arguments
+if [ "$#" -ne 5 ] ;then
+ echo "Input illegal number of parameters " $#
+ echo "Need 5 parameters for use-less-or-not, start-and-end, arch-index, and seeds"
+ exit 1
+fi
+if [ "$TORCH_HOME" = "" ]; then
+ echo "Must set TORCH_HOME envoriment variable for data dir saving"
+ exit 1
+else
+ echo "TORCH_HOME : $TORCH_HOME"
+fi
+
+use_less=$1
+xstart=$2
+xend=$3
+arch_index=$4
+all_seeds=$5
+
+save_dir=./output/NAS-BENCH-201-4/
+
+if [ ${arch_index} == "-1" ]; then
+ mode=new
+else
+ mode=cover
+fi
+
+OMP_NUM_THREADS=4 python ./exps/NAS-Bench-201/main.py \
+ --mode ${mode} --save_dir ${save_dir} --max_node 4 \
+ --use_less ${use_less} \
+ --datasets cifar10 cifar10 cifar100 ImageNet16-120 \
+ --splits 1 0 0 0 \
+ --xpaths $TORCH_HOME/cifar.python \
+ $TORCH_HOME/cifar.python \
+ $TORCH_HOME/cifar.python \
+ $TORCH_HOME/cifar.python/ImageNet16 \
+ --channel 16 --num_cells 5 \
+ --workers 4 \
+ --srange ${xstart} ${xend} --arch_index ${arch_index} \
+ --seeds ${all_seeds}
diff --git a/AutoDL-Projects/scripts-search/NASNet-space-search-by-DARTS1V.sh b/AutoDL-Projects/scripts-search/NASNet-space-search-by-DARTS1V.sh
new file mode 100644
index 0000000..95c73a5
--- /dev/null
+++ b/AutoDL-Projects/scripts-search/NASNet-space-search-by-DARTS1V.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+# bash ./scripts-search/NASNet-space-search-by-DARTS1V.sh cifar10 -1
+echo script name: $0
+echo $# arguments
+if [ "$#" -ne 2 ] ;then
+ echo "Input illegal number of parameters " $#
+ echo "Need 2 parameters for dataset, and seed"
+ exit 1
+fi
+if [ "$TORCH_HOME" = "" ]; then
+ echo "Must set TORCH_HOME envoriment variable for data dir saving"
+ exit 1
+else
+ echo "TORCH_HOME : $TORCH_HOME"
+fi
+
+dataset=$1
+BN=1
+seed=$2
+channel=16
+num_cells=5
+max_nodes=4
+space=darts
+
+if [ "$dataset" == "cifar10" ] || [ "$dataset" == "cifar100" ]; then
+ data_path="$TORCH_HOME/cifar.python"
+else
+ data_path="$TORCH_HOME/cifar.python/ImageNet16"
+fi
+
+save_dir=./output/search-cell-${space}/DARTS-V1-${dataset}-BN${BN}
+
+OMP_NUM_THREADS=4 python ./exps/NAS-Bench-201-algos/DARTS-V1.py \
+ --save_dir ${save_dir} --max_nodes ${max_nodes} --channel ${channel} --num_cells ${num_cells} \
+ --dataset ${dataset} --data_path ${data_path} \
+ --search_space_name ${space} \
+ --config_path configs/search-opts/DARTS-NASNet-CIFAR.config \
+ --model_config configs/search-archs/DARTS-NASNet-CIFAR.config \
+ --track_running_stats ${BN} \
+ --arch_learning_rate 0.0003 --arch_weight_decay 0.001 \
+ --workers 4 --print_freq 200 --rand_seed ${seed}
diff --git a/AutoDL-Projects/scripts-search/NASNet-space-search-by-GDAS-FRC.sh b/AutoDL-Projects/scripts-search/NASNet-space-search-by-GDAS-FRC.sh
new file mode 100644
index 0000000..40b16e0
--- /dev/null
+++ b/AutoDL-Projects/scripts-search/NASNet-space-search-by-GDAS-FRC.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+# bash ./scripts-search/NASNet-space-search-by-GDAS-FRC.sh cifar10 0 -1
+echo script name: $0
+echo $# arguments
+if [ "$#" -ne 3 ] ;then
+ echo "Input illegal number of parameters " $#
+ echo "Need 3 parameters for dataset, track_running_stats, and seed"
+ exit 1
+fi
+if [ "$TORCH_HOME" = "" ]; then
+ echo "Must set TORCH_HOME envoriment variable for data dir saving"
+ exit 1
+else
+ echo "TORCH_HOME : $TORCH_HOME"
+fi
+
+dataset=$1
+track_running_stats=$2
+seed=$3
+space=darts
+
+if [ "$dataset" == "cifar10" ] || [ "$dataset" == "cifar100" ]; then
+ data_path="$TORCH_HOME/cifar.python"
+else
+ data_path="$TORCH_HOME/cifar.python/ImageNet16"
+fi
+
+save_dir=./output/search-cell-${space}/GDAS-FRC-${dataset}-BN${track_running_stats}
+
+OMP_NUM_THREADS=4 python ./exps/algos/GDAS.py \
+ --save_dir ${save_dir} \
+ --dataset ${dataset} --data_path ${data_path} \
+ --search_space_name ${space} \
+ --config_path configs/search-opts/GDAS-NASNet-CIFAR.config \
+ --model_config configs/search-archs/GDASFRC-NASNet-CIFAR.config \
+ --tau_max 10 --tau_min 0.1 --track_running_stats ${track_running_stats} \
+ --arch_learning_rate 0.0003 --arch_weight_decay 0.001 \
+ --workers 4 --print_freq 200 --rand_seed ${seed}
diff --git a/AutoDL-Projects/scripts-search/NASNet-space-search-by-GDAS.sh b/AutoDL-Projects/scripts-search/NASNet-space-search-by-GDAS.sh
new file mode 100644
index 0000000..1a28bd5
--- /dev/null
+++ b/AutoDL-Projects/scripts-search/NASNet-space-search-by-GDAS.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+# bash ./scripts-search/NASNet-space-search-by-GDAS.sh cifar10 1 -1
+echo script name: $0
+echo $# arguments
+if [ "$#" -ne 3 ] ;then
+ echo "Input illegal number of parameters " $#
+ echo "Need 3 parameters for dataset, track_running_stats, and seed"
+ exit 1
+fi
+if [ "$TORCH_HOME" = "" ]; then
+ echo "Must set TORCH_HOME envoriment variable for data dir saving"
+ exit 1
+else
+ echo "TORCH_HOME : $TORCH_HOME"
+fi
+
+dataset=$1
+track_running_stats=$2
+seed=$3
+space=darts
+
+if [ "$dataset" == "cifar10" ] || [ "$dataset" == "cifar100" ]; then
+ data_path="$TORCH_HOME/cifar.python"
+else
+ data_path="$TORCH_HOME/cifar.python/ImageNet16"
+fi
+
+save_dir=./output/search-cell-${space}/GDAS-${dataset}-BN${track_running_stats}
+
+OMP_NUM_THREADS=4 python ./exps/NAS-Bench-201-algos/GDAS.py \
+ --save_dir ${save_dir} \
+ --dataset ${dataset} --data_path ${data_path} \
+ --search_space_name ${space} \
+ --config_path configs/search-opts/GDAS-NASNet-CIFAR.config \
+ --model_config configs/search-archs/GDAS-NASNet-CIFAR.config \
+ --tau_max 10 --tau_min 0.1 --track_running_stats ${track_running_stats} \
+ --arch_learning_rate 0.0003 --arch_weight_decay 0.001 \
+ --workers 4 --print_freq 200 --rand_seed ${seed}
diff --git a/AutoDL-Projects/scripts-search/NASNet-space-search-by-SETN.sh b/AutoDL-Projects/scripts-search/NASNet-space-search-by-SETN.sh
new file mode 100644
index 0000000..f99437f
--- /dev/null
+++ b/AutoDL-Projects/scripts-search/NASNet-space-search-by-SETN.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+# bash ./scripts-search/NASNet-space-search-by-SETN.sh cifar10 1 -1
+# [TO BE DONE]
+echo script name: $0
+echo $# arguments
+if [ "$#" -ne 3 ] ;then
+ echo "Input illegal number of parameters " $#
+ echo "Need 3 parameters for dataset, track_running_stats, and seed"
+ exit 1
+fi
+if [ "$TORCH_HOME" = "" ]; then
+ echo "Must set TORCH_HOME envoriment variable for data dir saving"
+ exit 1
+else
+ echo "TORCH_HOME : $TORCH_HOME"
+fi
+
+dataset=$1
+track_running_stats=$2
+seed=$3
+space=darts
+
+if [ "$dataset" == "cifar10" ] || [ "$dataset" == "cifar100" ]; then
+ data_path="$TORCH_HOME/cifar.python"
+else
+ data_path="$TORCH_HOME/cifar.python/ImageNet16"
+fi
+
+save_dir=./output/search-cell-${space}/SETN-${dataset}-BN${track_running_stats}
+
+OMP_NUM_THREADS=4 python ./exps/NAS-Bench-201-algos/SETN.py \
+ --save_dir ${save_dir} \
+ --dataset ${dataset} --data_path ${data_path} \
+ --search_space_name ${space} \
+ --config_path configs/search-opts/SETN-NASNet-CIFAR.config \
+ --model_config configs/search-archs/SETN-NASNet-CIFAR.config \
+ --track_running_stats ${track_running_stats} \
+ --select_num 1000 \
+ --arch_learning_rate 0.0003 --arch_weight_decay 0.001 \
+ --workers 4 --print_freq 200 --rand_seed ${seed}
diff --git a/AutoDL-Projects/scripts-search/NATS/search-size.sh b/AutoDL-Projects/scripts-search/NATS/search-size.sh
new file mode 100644
index 0000000..86329f5
--- /dev/null
+++ b/AutoDL-Projects/scripts-search/NATS/search-size.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+# bash scripts-search/NATS/search-size.sh 0 0.3 777
+echo script name: $0
+echo $# arguments
+if [ "$#" -ne 3 ] ;then
+ echo "Input illegal number of parameters " $#
+ echo "Need 3 parameters for GPU-device, warmup-ratio, and seed"
+ exit 1
+fi
+if [ "$TORCH_HOME" = "" ]; then
+ echo "Must set TORCH_HOME envoriment variable for data dir saving"
+ exit 1
+else
+ echo "TORCH_HOME : $TORCH_HOME"
+fi
+
+device=$1
+ratio=$2
+seed=$3
+
+CUDA_VISIBLE_DEVICES=${device} python ./exps/NATS-algos/search-size.py --dataset cifar10 --data_path $TORCH_HOME/cifar.python --algo tas --warmup_ratio ${ratio} --rand_seed ${seed}
+CUDA_VISIBLE_DEVICES=${device} python ./exps/NATS-algos/search-size.py --dataset cifar100 --data_path $TORCH_HOME/cifar.python --algo tas --warmup_ratio ${ratio} --rand_seed ${seed}
+CUDA_VISIBLE_DEVICES=${device} python ./exps/NATS-algos/search-size.py --dataset ImageNet16-120 --data_path $TORCH_HOME/cifar.python/ImageNet16 --algo tas --warmup_ratio ${ratio} --rand_seed ${seed}
+
+#
+CUDA_VISIBLE_DEVICES=${device} python ./exps/NATS-algos/search-size.py --dataset cifar10 --data_path $TORCH_HOME/cifar.python --algo mask_gumbel --warmup_ratio ${ratio} --rand_seed ${seed}
+CUDA_VISIBLE_DEVICES=${device} python ./exps/NATS-algos/search-size.py --dataset cifar100 --data_path $TORCH_HOME/cifar.python --algo mask_gumbel --warmup_ratio ${ratio} --rand_seed ${seed}
+CUDA_VISIBLE_DEVICES=${device} python ./exps/NATS-algos/search-size.py --dataset ImageNet16-120 --data_path $TORCH_HOME/cifar.python/ImageNet16 --algo mask_gumbel --warmup_ratio ${ratio} --rand_seed ${seed}
+
+#
+CUDA_VISIBLE_DEVICES=${device} python ./exps/NATS-algos/search-size.py --dataset cifar10 --data_path $TORCH_HOME/cifar.python --algo mask_rl --arch_weight_decay 0 --warmup_ratio ${ratio} --rand_seed ${seed}
+CUDA_VISIBLE_DEVICES=${device} python ./exps/NATS-algos/search-size.py --dataset cifar100 --data_path $TORCH_HOME/cifar.python --algo mask_rl --arch_weight_decay 0 --warmup_ratio ${ratio} --rand_seed ${seed}
+CUDA_VISIBLE_DEVICES=${device} python ./exps/NATS-algos/search-size.py --dataset ImageNet16-120 --data_path $TORCH_HOME/cifar.python/ImageNet16 --algo mask_rl --arch_weight_decay 0 --warmup_ratio ${ratio} --rand_seed ${seed}
diff --git a/AutoDL-Projects/scripts-search/search-depth-cifar.sh b/AutoDL-Projects/scripts-search/search-depth-cifar.sh
new file mode 100644
index 0000000..c84ba9d
--- /dev/null
+++ b/AutoDL-Projects/scripts-search/search-depth-cifar.sh
@@ -0,0 +1,78 @@
+#!/bin/bash
+# bash ./scripts-search/search-depth-cifar.sh cifar10 ResNet110 CIFAR 0 0 0.57 777
+# bash ./scripts-search/search-depth-cifar.sh cifar10 ResNet110 CIFARX 0 0 0.57 777
+set -e
+echo script name: $0
+echo $# arguments
+if [ "$#" -ne 7 ] ;then
+ echo "Input illegal number of parameters " $#
+ echo "Need 7 parameters for the dataset and the-model-name and the-optimizer and gumbel-max/min and FLOP-ratio and the-random-seed"
+ exit 1
+fi
+if [ "$TORCH_HOME" = "" ]; then
+ echo "Must set TORCH_HOME envoriment variable for data dir saving"
+ exit 1
+else
+ echo "TORCH_HOME : $TORCH_HOME"
+fi
+
+dataset=$1
+model=$2
+optim=$3
+batch=256
+gumbel_min=$4
+gumbel_max=$5
+expected_FLOP_ratio=$6
+rseed=$7
+
+
+SAVE_ROOT="./output"
+
+save_dir=${SAVE_ROOT}/search-depth/${dataset}-${model}-${optim}-Gumbel_${gumbel_min}_${gumbel_max}-${expected_FLOP_ratio}
+
+python --version
+
+OMP_NUM_THREADS=4 python ./exps/TAS/search-shape.py --dataset ${dataset} \
+ --data_path $TORCH_HOME/cifar.python \
+ --model_config ./configs/archs/CIFAR-${model}.config \
+ --split_path ./.latent-data/splits/${dataset}-0.5.pth \
+ --optim_config ./configs/search-opts/${optim}.config \
+ --search_shape depth \
+ --procedure search \
+ --FLOP_ratio ${expected_FLOP_ratio} \
+ --FLOP_weight 2 --FLOP_tolerant 0.05 \
+ --save_dir ${save_dir} \
+ --gumbel_tau_max ${gumbel_max} --gumbel_tau_min ${gumbel_min} \
+ --cutout_length -1 \
+ --batch_size ${batch} --rand_seed ${rseed} --workers 4 \
+ --eval_frequency 1 --print_freq 100 --print_freq_eval 200
+
+
+if [ "$rseed" = "-1" ]; then
+ echo "Skip training the best configuration"
+else
+ # normal training
+ xsave_dir=${save_dir}/seed-${rseed}-NMT
+ OMP_NUM_THREADS=4 python ./exps/basic/basic-main.py --dataset ${dataset} \
+ --data_path $TORCH_HOME/cifar.python \
+ --model_config ${save_dir}/seed-${rseed}-last.config \
+ --optim_config ./configs/opts/CIFAR-E300-W5-L1-COS.config \
+ --procedure basic \
+ --save_dir ${xsave_dir} \
+ --cutout_length -1 \
+ --batch_size 256 --rand_seed ${rseed} --workers 4 \
+ --eval_frequency 1 --print_freq 100 --print_freq_eval 200
+ # KD training
+ xsave_dir=${save_dir}/seed-${rseed}-KDT
+ OMP_NUM_THREADS=4 python ./exps/basic/KD-main.py --dataset ${dataset} \
+ --data_path $TORCH_HOME/cifar.python \
+ --model_config ${save_dir}/seed-${rseed}-last.config \
+ --optim_config ./configs/opts/CIFAR-E300-W5-L1-COS.config \
+ --KD_checkpoint ./.latent-data/basemodels/${dataset}/${model}.pth \
+ --procedure Simple-KD \
+ --save_dir ${xsave_dir} \
+ --KD_alpha 0.9 --KD_temperature 4 \
+ --cutout_length -1 \
+ --batch_size 256 --rand_seed ${rseed} --workers 4 \
+ --eval_frequency 1 --print_freq 100 --print_freq_eval 200
+fi
diff --git a/AutoDL-Projects/scripts-search/search-depth-gumbel.sh b/AutoDL-Projects/scripts-search/search-depth-gumbel.sh
new file mode 100644
index 0000000..0be416f
--- /dev/null
+++ b/AutoDL-Projects/scripts-search/search-depth-gumbel.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+# bash ./scripts-search/search-depth-gumbel.sh cifar10 ResNet110 CIFARX 0.57 777
+set -e
+echo script name: $0
+echo $# arguments
+if [ "$#" -ne 5 ] ;then
+ echo "Input illegal number of parameters " $#
+ echo "Need 5 parameters for the dataset and the-model-name and the-optimizer and FLOP-ratio and the-random-seed"
+ exit 1
+fi
+if [ "$TORCH_HOME" = "" ]; then
+ echo "Must set TORCH_HOME envoriment variable for data dir saving"
+ exit 1
+else
+ echo "TORCH_HOME : $TORCH_HOME"
+fi
+
+dataset=$1
+model=$2
+optim=$3
+expected_FLOP_ratio=$4
+rseed=$5
+
+bash ./scripts-search/search-depth-cifar.sh ${dataset} ${model} ${optim} 0.1 5 ${expected_FLOP_ratio} ${rseed}
diff --git a/AutoDL-Projects/scripts-search/search-shape-cifar.sh b/AutoDL-Projects/scripts-search/search-shape-cifar.sh
new file mode 100644
index 0000000..45b223f
--- /dev/null
+++ b/AutoDL-Projects/scripts-search/search-shape-cifar.sh
@@ -0,0 +1,73 @@
+#!/bin/bash
+# bash ./scripts-search/search-shape-cifar.sh cifar10 ResNet110 CIFAR 0.57 777
+set -e
+echo script name: $0
+echo $# arguments
+if [ "$#" -ne 5 ] ;then
+ echo "Input illegal number of parameters " $#
+ echo "Need 5 parameters for the dataset and the-model-name and the-optimizer and FLOP-ratio and the-random-seed"
+ exit 1
+fi
+if [ "$TORCH_HOME" = "" ]; then
+ echo "Must set TORCH_HOME envoriment variable for data dir saving"
+ exit 1
+else
+ echo "TORCH_HOME : $TORCH_HOME"
+fi
+
+dataset=$1
+model=$2
+optim=$3
+batch=256
+gumbel_min=0.1
+gumbel_max=5
+expected_FLOP_ratio=$4
+rseed=$5
+
+save_dir=./output/search-shape/${dataset}-${model}-${optim}-Gumbel_${gumbel_min}_${gumbel_max}-${expected_FLOP_ratio}
+
+python --version
+
+OMP_NUM_THREADS=4 python ./exps/TAS/search-transformable.py --dataset ${dataset} \
+ --data_path $TORCH_HOME/cifar.python \
+ --model_config ./configs/archs/CIFAR-${model}.config \
+ --split_path ./.latent-data/splits/${dataset}-0.5.pth \
+ --optim_config ./configs/search-opts/${optim}.config \
+ --procedure search-v2 \
+ --FLOP_ratio ${expected_FLOP_ratio} \
+ --FLOP_weight 2 --FLOP_tolerant 0.05 \
+ --save_dir ${save_dir} \
+ --gumbel_tau_max ${gumbel_max} --gumbel_tau_min ${gumbel_min} \
+ --cutout_length -1 \
+ --batch_size ${batch} --rand_seed ${rseed} --workers 6 \
+ --eval_frequency 1 --print_freq 100 --print_freq_eval 200
+
+
+if [ "$rseed" = "-1" ]; then
+ echo "Skip training the last configuration"
+else
+ # normal training
+ xsave_dir=${save_dir}/seed-${rseed}-NMT
+ OMP_NUM_THREADS=4 python ./exps/basic/basic-main.py --dataset ${dataset} \
+ --data_path $TORCH_HOME/cifar.python \
+ --model_config ${save_dir}/seed-${rseed}-last.config \
+ --optim_config ./configs/opts/CIFAR-E300-W5-L1-COS.config \
+ --procedure basic \
+ --save_dir ${xsave_dir} \
+ --cutout_length -1 \
+ --batch_size 256 --rand_seed ${rseed} --workers 6 \
+ --eval_frequency 1 --print_freq 100 --print_freq_eval 200
+ # KD training
+ xsave_dir=${save_dir}/seed-${rseed}-KDT
+ OMP_NUM_THREADS=4 python ./exps/basic/KD-main.py --dataset ${dataset} \
+ --data_path $TORCH_HOME/cifar.python \
+ --model_config ${save_dir}/seed-${rseed}-last.config \
+ --optim_config ./configs/opts/CIFAR-E300-W5-L1-COS.config \
+ --KD_checkpoint ./.latent-data/basemodels/${dataset}/${model}.pth \
+ --procedure Simple-KD \
+ --save_dir ${xsave_dir} \
+ --KD_alpha 0.9 --KD_temperature 4 \
+ --cutout_length -1 \
+ --batch_size 256 --rand_seed ${rseed} --workers 6 \
+ --eval_frequency 1 --print_freq 100 --print_freq_eval 200
+fi
diff --git a/AutoDL-Projects/scripts-search/search-width-cifar.sh b/AutoDL-Projects/scripts-search/search-width-cifar.sh
new file mode 100644
index 0000000..4919b79
--- /dev/null
+++ b/AutoDL-Projects/scripts-search/search-width-cifar.sh
@@ -0,0 +1,78 @@
+#!/bin/bash
+# bash ./scripts-search/search-width-cifar.sh cifar10 ResNet110 CIFAR 0 0 0.57 777
+# bash ./scripts-search/search-width-cifar.sh cifar10 ResNet110 CIFARX 0 0 0.57 777
+set -e
+echo script name: $0
+echo $# arguments
+if [ "$#" -ne 7 ] ;then
+ echo "Input illegal number of parameters " $#
+ echo "Need 7 parameters for the dataset and the-model-name and the-optimizer and gumbel-max/min and FLOP-ratio and the-random-seed"
+ exit 1
+fi
+if [ "$TORCH_HOME" = "" ]; then
+ echo "Must set TORCH_HOME envoriment variable for data dir saving"
+ exit 1
+else
+ echo "TORCH_HOME : $TORCH_HOME"
+fi
+
+dataset=$1
+model=$2
+optim=$3
+batch=256
+gumbel_min=$4
+gumbel_max=$5
+expected_FLOP_ratio=$6
+rseed=$7
+
+
+SAVE_ROOT="./output"
+
+save_dir=${SAVE_ROOT}/search-width/${dataset}-${model}-${optim}-Gumbel_${gumbel_min}_${gumbel_max}-${expected_FLOP_ratio}
+
+python --version
+
+OMP_NUM_THREADS=4 python ./exps/TAS/search-shape.py --dataset ${dataset} \
+ --data_path $TORCH_HOME/cifar.python \
+ --model_config ./configs/archs/CIFAR-${model}.config \
+ --split_path ./.latent-data/splits/${dataset}-0.5.pth \
+ --optim_config ./configs/search-opts/${optim}.config \
+ --search_shape width \
+ --procedure search \
+ --FLOP_ratio ${expected_FLOP_ratio} \
+ --FLOP_weight 2 --FLOP_tolerant 0.05 \
+ --save_dir ${save_dir} \
+ --gumbel_tau_max ${gumbel_max} --gumbel_tau_min ${gumbel_min} \
+ --cutout_length -1 \
+ --batch_size ${batch} --rand_seed ${rseed} --workers 4 \
+ --eval_frequency 1 --print_freq 100 --print_freq_eval 200
+
+
+if [ "$rseed" = "-1" ]; then
+ echo "Skip training the best configuration"
+else
+ # normal training
+ xsave_dir=${save_dir}/seed-${rseed}-NMT
+ OMP_NUM_THREADS=4 python ./exps/basic/basic-main.py --dataset ${dataset} \
+ --data_path $TORCH_HOME/cifar.python \
+ --model_config ${save_dir}/seed-${rseed}-last.config \
+ --optim_config ./configs/opts/CIFAR-E300-W5-L1-COS.config \
+ --procedure basic \
+ --save_dir ${xsave_dir} \
+ --cutout_length -1 \
+ --batch_size 256 --rand_seed ${rseed} --workers 4 \
+ --eval_frequency 1 --print_freq 100 --print_freq_eval 200
+ # KD training
+ xsave_dir=${save_dir}/seed-${rseed}-KDT
+ OMP_NUM_THREADS=4 python ./exps/basic/KD-main.py --dataset ${dataset} \
+ --data_path $TORCH_HOME/cifar.python \
+ --model_config ${save_dir}/seed-${rseed}-last.config \
+ --optim_config ./configs/opts/CIFAR-E300-W5-L1-COS.config \
+ --KD_checkpoint ./.latent-data/basemodels/${dataset}/${model}.pth \
+ --procedure Simple-KD \
+ --save_dir ${xsave_dir} \
+ --KD_alpha 0.9 --KD_temperature 4 \
+ --cutout_length -1 \
+ --batch_size 256 --rand_seed ${rseed} --workers 4 \
+ --eval_frequency 1 --print_freq 100 --print_freq_eval 200
+fi
diff --git a/AutoDL-Projects/scripts-search/search-width-gumbel.sh b/AutoDL-Projects/scripts-search/search-width-gumbel.sh
new file mode 100644
index 0000000..5478891
--- /dev/null
+++ b/AutoDL-Projects/scripts-search/search-width-gumbel.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+# bash ./scripts-search/search-width-gumbel.sh cifar10 ResNet110 CIFARX 0.57 777
+set -e
+echo script name: $0
+echo $# arguments
+if [ "$#" -ne 5 ] ;then
+ echo "Input illegal number of parameters " $#
+ echo "Need 5 parameters for the dataset and the-model-name and the-optimizer and FLOP-ratio and the-random-seed"
+ exit 1
+fi
+if [ "$TORCH_HOME" = "" ]; then
+ echo "Must set TORCH_HOME envoriment variable for data dir saving"
+ exit 1
+else
+ echo "TORCH_HOME : $TORCH_HOME"
+fi
+
+dataset=$1
+model=$2
+optim=$3
+expected_FLOP_ratio=$4
+rseed=$5
+
+bash ./scripts-search/search-width-cifar.sh ${dataset} ${model} ${optim} 0.1 5 ${expected_FLOP_ratio} ${rseed}
diff --git a/AutoDL-Projects/scripts/NATS-Bench/train-shapes.sh b/AutoDL-Projects/scripts/NATS-Bench/train-shapes.sh
new file mode 100644
index 0000000..b261fe2
--- /dev/null
+++ b/AutoDL-Projects/scripts/NATS-Bench/train-shapes.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+##############################################################################
+# NATS-Bench: Benchmarking NAS algorithms for Architecture Topology and Size #
+##############################################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020.01 #
+##############################################################################
+# CUDA_VISIBLE_DEVICES=0 bash scripts/NATS-Bench/train-shapes.sh 00000-05000 12 777
+# bash ./scripts/NATS-Bench/train-shapes.sh 05001-10000 12 777
+# bash ./scripts/NATS-Bench/train-shapes.sh 10001-14500 12 777
+# bash ./scripts/NATS-Bench/train-shapes.sh 14501-18000 12 777
+# bash ./scripts/NATS-Bench/train-shapes.sh 18001-19500 12 777
+# bash ./scripts/NATS-Bench/train-shapes.sh 19501-23500 12 777
+# bash ./scripts/NATS-Bench/train-shapes.sh 23501-27500 12 777
+# bash ./scripts/NATS-Bench/train-shapes.sh 27501-30000 12 777
+# bash ./scripts/NATS-Bench/train-shapes.sh 30001-32767 12 777
+#
+# CUDA_VISIBLE_DEVICES=2 bash ./scripts/NATS-Bench/train-shapes.sh 01000-03999,04050-05000,06000-09000,11000-14500,15000-18500,20000-23500,25000-27500,29000-30000 12 777
+# SLURM_PROCID=1 SLURM_NTASKS=5 bash ./scripts/NATS-Bench/train-shapes.sh 01000-03999,04050-05000,06000-09000,11000-14500,15000-18500,20000-23500,25000-27500,29000-30000 90 777
+# [GCP] bash ./scripts/NATS-Bench/train-shapes.sh 00000-09999 90 777
+# [UTS] bash ./scripts/NATS-Bench/train-shapes.sh 30000-32767 90 777
+##############################################################################
+echo script name: $0
+echo $# arguments
+if [ "$#" -ne 3 ] ;then
+ echo "Input illegal number of parameters " $#
+ echo "Need 3 parameters for start-and-end, hyper-parameters-opt-file, and seeds"
+ exit 1
+fi
+if [ "$TORCH_HOME" = "" ]; then
+ echo "Must set TORCH_HOME envoriment variable for data dir saving"
+ exit 1
+else
+ echo "TORCH_HOME : $TORCH_HOME"
+fi
+
+srange=$1
+opt=$2
+all_seeds=$3
+cpus=4
+
+save_dir=./output/NATS-Bench-size/
+
+OMP_NUM_THREADS=${cpus} python exps/NATS-Bench/main-sss.py \
+ --mode new --srange ${srange} --hyper ${opt} --save_dir ${save_dir} \
+ --datasets cifar10 cifar10 cifar100 ImageNet16-120 \
+ --splits 1 0 0 0 \
+ --xpaths $TORCH_HOME/cifar.python \
+ $TORCH_HOME/cifar.python \
+ $TORCH_HOME/cifar.python \
+ $TORCH_HOME/cifar.python/ImageNet16 \
+ --workers ${cpus} \
+ --seeds ${all_seeds}
diff --git a/AutoDL-Projects/scripts/NATS-Bench/train-topology.sh b/AutoDL-Projects/scripts/NATS-Bench/train-topology.sh
new file mode 100644
index 0000000..7b93936
--- /dev/null
+++ b/AutoDL-Projects/scripts/NATS-Bench/train-topology.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+##############################################################################
+# NATS-Bench: Benchmarking NAS algorithms for Architecture Topology and Size #
+##############################################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020.01 #
+##############################################################################
+# [saturn1] CUDA_VISIBLE_DEVICES=0 bash scripts/NATS-Bench/train-topology.sh 00000-02000 200 "777 888 999"
+# [saturn1] CUDA_VISIBLE_DEVICES=0 bash scripts/NATS-Bench/train-topology.sh 02000-04000 200 "777 888 999"
+# [saturn1] CUDA_VISIBLE_DEVICES=1 bash scripts/NATS-Bench/train-topology.sh 04000-06000 200 "777 888 999"
+# [saturn1] CUDA_VISIBLE_DEVICES=1 bash scripts/NATS-Bench/train-topology.sh 06000-08000 200 "777 888 999"
+#
+# CUDA_VISIBLE_DEVICES=0 bash scripts/NATS-Bench/train-topology.sh 00000-05000 12 777
+# bash ./scripts/NATS-Bench/train-topology.sh 05001-10000 12 777
+# bash ./scripts/NATS-Bench/train-topology.sh 10001-14500 12 777
+# bash ./scripts/NATS-Bench/train-topology.sh 14501-15624 12 777
+#
+##############################################################################
+echo script name: $0
+echo $# arguments
+if [ "$#" -ne 3 ] ;then
+ echo "Input illegal number of parameters " $#
+ echo "Need 3 parameters for start-and-end, hyper-parameters-opt-file, and seeds"
+ exit 1
+fi
+if [ "$TORCH_HOME" = "" ]; then
+ echo "Must set TORCH_HOME envoriment variable for data dir saving"
+ exit 1
+else
+ echo "TORCH_HOME : $TORCH_HOME"
+fi
+
+srange=$1
+opt=$2
+all_seeds=$3
+cpus=4
+
+save_dir=./output/NATS-Bench-topology/
+
+OMP_NUM_THREADS=${cpus} python exps/NATS-Bench/main-tss.py \
+ --mode new --srange ${srange} --hyper ${opt} --save_dir ${save_dir} \
+ --datasets cifar10 cifar10 cifar100 ImageNet16-120 \
+ --splits 1 0 0 0 \
+ --xpaths $TORCH_HOME/cifar.python \
+ $TORCH_HOME/cifar.python \
+ $TORCH_HOME/cifar.python \
+ $TORCH_HOME/cifar.python/ImageNet16 \
+ --workers ${cpus} \
+ --seeds ${all_seeds}
diff --git a/AutoDL-Projects/scripts/TAS/prepare.sh b/AutoDL-Projects/scripts/TAS/prepare.sh
new file mode 100644
index 0000000..005d552
--- /dev/null
+++ b/AutoDL-Projects/scripts/TAS/prepare.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+# bash ./scripts/TAS/prepare.sh
+#datasets='cifar10 cifar100 imagenet-1k'
+#ratios='0.5 0.8 0.9'
+ratios='0.5'
+save_dir=./.latent-data/splits
+
+for ratio in ${ratios}
+do
+ python ./exps/TAS/prepare.py --name cifar10 --root $TORCH_HOME/cifar.python --save ${save_dir}/cifar10-${ratio}.pth --ratio ${ratio}
+ python ./exps/TAS/prepare.py --name cifar100 --root $TORCH_HOME/cifar.python --save ${save_dir}/cifar100-${ratio}.pth --ratio ${ratio}
+ python ./exps/TAS/prepare.py --name imagenet-1k --root $TORCH_HOME/ILSVRC2012 --save ${save_dir}/imagenet-1k-${ratio}.pth --ratio ${ratio}
+done
diff --git a/AutoDL-Projects/scripts/base-train.sh b/AutoDL-Projects/scripts/base-train.sh
new file mode 100644
index 0000000..cd80903
--- /dev/null
+++ b/AutoDL-Projects/scripts/base-train.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+# bash ./scripts/base-train.sh cifar10 ResNet110 E300 L1 256 -1
+echo script name: $0
+echo $# arguments
+if [ "$#" -ne 6 ] ;then
+ echo "Input illegal number of parameters " $#
+ echo "Need 6 parameters for the dataset and the-model-name and epochs and LR and the-batch-size and the-random-seed"
+ exit 1
+fi
+if [ "$TORCH_HOME" = "" ]; then
+ echo "Must set TORCH_HOME envoriment variable for data dir saving"
+ exit 1
+else
+ echo "TORCH_HOME : $TORCH_HOME"
+fi
+
+dataset=$1
+model=$2
+epoch=$3
+LR=$4
+batch=$5
+rseed=$6
+
+
+save_dir=./output/basic/${dataset}/${model}-${epoch}-${LR}-${batch}
+
+python --version
+
+OMP_NUM_THREADS=4 python ./exps/basic/basic-main.py --dataset ${dataset} \
+ --data_path $TORCH_HOME/cifar.python \
+ --model_config ./configs/archs/CIFAR-${model}.config \
+ --optim_config ./configs/opts/CIFAR-${epoch}-W5-${LR}-COS.config \
+ --procedure basic \
+ --save_dir ${save_dir} \
+ --cutout_length -1 \
+ --batch_size ${batch} --rand_seed ${rseed} --workers 4 \
+ --eval_frequency 1 --print_freq 100 --print_freq_eval 200
diff --git a/AutoDL-Projects/scripts/black.sh b/AutoDL-Projects/scripts/black.sh
new file mode 100644
index 0000000..43acb79
--- /dev/null
+++ b/AutoDL-Projects/scripts/black.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+# bash ./scripts/black.sh
+
+# script=$(readlink -f "$0")
+# scriptpath=$(dirname "$script")
+# echo $scriptpath
+
+# delete Python cache files
+find . | grep -E "(__pycache__|\.pyc|\.DS_Store|\.pyo$)" | xargs rm -rf
+
+black ./tests/
+black ./xautodl/procedures
+black ./xautodl/datasets
+black ./xautodl/xlayers
+black ./exps/trading
+rm -rf ./xautodl.egg-info
+rm -rf ./build
+rm -rf ./dist
+rm -rf ./.pytest_cache
diff --git a/AutoDL-Projects/scripts/experimental/train-vit.sh b/AutoDL-Projects/scripts/experimental/train-vit.sh
new file mode 100644
index 0000000..3a36974
--- /dev/null
+++ b/AutoDL-Projects/scripts/experimental/train-vit.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+# bash ./scripts/experimental/train-vit.sh cifar10 -1
+echo script name: $0
+echo $# arguments
+if [ "$#" -ne 2 ] ;then
+ echo "Input illegal number of parameters " $#
+ echo "Need 2 parameters for dataset and random-seed"
+ exit 1
+fi
+if [ "$TORCH_HOME" = "" ]; then
+ echo "Must set TORCH_HOME envoriment variable for data dir saving"
+ exit 1
+else
+ echo "TORCH_HOME : $TORCH_HOME"
+fi
+
+dataset=$1
+rseed=$2
+
+save_dir=./outputs/${dataset}/vit-experimental
+
+python --version
+
+python ./exps/basic/xmain.py --save_dir ${save_dir} --rand_seed ${rseed} \
+ --train_data_config ./configs/yaml.data/${dataset}.train \
+ --valid_data_config ./configs/yaml.data/${dataset}.test \
+ --data_path $TORCH_HOME/cifar.python \
+ --model_config ./configs/yaml.model/vit-cifar10.s0 \
+ --optim_config ./configs/yaml.opt/vit.cifar \
+ --loss_config ./configs/yaml.loss/cross-entropy \
+ --metric_config ./configs/yaml.loss/top-ce \
+ --batch_size 256 \
+ --lr 0.003 --weight_decay 0.3 --scheduler warm-cos --steps 10000
diff --git a/AutoDL-Projects/scripts/nas-infer-train.sh b/AutoDL-Projects/scripts/nas-infer-train.sh
new file mode 100644
index 0000000..b111720
--- /dev/null
+++ b/AutoDL-Projects/scripts/nas-infer-train.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+# bash ./scripts/nas-infer-train.sh cifar10 SETN 256 -1
+echo script name: $0
+echo $# arguments
+if [ "$#" -ne 4 ] ;then
+ echo "Input illegal number of parameters " $#
+ echo "Need 4 parameters for dataset, the-model-name, the-batch-size and the-random-seed"
+ exit 1
+fi
+if [ "$TORCH_HOME" = "" ]; then
+ echo "Must set TORCH_HOME envoriment variable for data dir saving"
+ exit 1
+else
+ echo "TORCH_HOME : $TORCH_HOME"
+fi
+
+dataset=$1
+model=$2
+batch=$3
+rseed=$4
+
+if [ ${dataset} == 'cifar10' ] || [ ${dataset} == 'cifar100' ]; then
+ xpath=$TORCH_HOME/cifar.python
+ base=CIFAR
+ workers=4
+ cutout_length=16
+elif [ ${dataset} == 'imagenet-1k' ]; then
+ xpath=$TORCH_HOME/ILSVRC2012
+ base=IMAGENET
+ workers=28
+ cutout_length=-1
+else
+ exit 1
+ echo 'Unknown dataset: '${dataset}
+fi
+
+SAVE_ROOT="./output"
+
+save_dir=${SAVE_ROOT}/nas-infer/${dataset}-${model}-${batch}
+
+python --version
+
+python ./exps/basic/basic-main.py --dataset ${dataset} \
+ --data_path ${xpath} --model_source nas \
+ --model_config ./configs/archs/NAS-${base}-${model}.config \
+ --optim_config ./configs/opts/NAS-${base}.config \
+ --procedure basic \
+ --save_dir ${save_dir} \
+ --cutout_length ${cutout_length} \
+ --batch_size ${batch} --rand_seed ${rseed} --workers ${workers} \
+ --eval_frequency 1 --print_freq 500 --print_freq_eval 1000
diff --git a/AutoDL-Projects/scripts/retrain-searched-net.sh b/AutoDL-Projects/scripts/retrain-searched-net.sh
new file mode 100644
index 0000000..c437c7f
--- /dev/null
+++ b/AutoDL-Projects/scripts/retrain-searched-net.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+# bash ./scripts/retrain-searched-net.sh cifar10 ${NAME} ${PATH} 256 -1
+echo script name: $0
+echo $# arguments
+if [ "$#" -ne 5 ] ;then
+ echo "Input illegal number of parameters " $#
+ echo "Need 5 parameters for dataset, the save dir base name, the model path, the batch size, the random seed"
+ exit 1
+fi
+if [ "$TORCH_HOME" = "" ]; then
+ echo "Must set TORCH_HOME envoriment variable for data dir saving"
+ exit 1
+else
+ echo "TORCH_HOME : $TORCH_HOME"
+fi
+
+dataset=$1
+save_name=$2
+model_path=$3
+batch=$4
+rseed=$5
+
+if [ ${dataset} == 'cifar10' ] || [ ${dataset} == 'cifar100' ]; then
+ xpath=$TORCH_HOME/cifar.python
+ base=CIFAR
+ workers=4
+ cutout_length=16
+elif [ ${dataset} == 'imagenet-1k' ]; then
+ xpath=$TORCH_HOME/ILSVRC2012
+ base=IMAGENET
+ workers=28
+ cutout_length=-1
+else
+ exit 1
+ echo 'Unknown dataset: '${dataset}
+fi
+
+SAVE_ROOT="./output"
+
+save_dir=${SAVE_ROOT}/nas-infer/${dataset}-BS${batch}-${save_name}
+
+python --version
+
+python ./exps/basic/basic-main.py --dataset ${dataset} \
+ --data_path ${xpath} --model_source autodl-searched \
+ --model_config ./configs/archs/NAS-${base}-none.config \
+ --optim_config ./configs/opts/NAS-${base}.config \
+ --extra_model_path ${model_path} \
+ --procedure basic \
+ --save_dir ${save_dir} \
+ --cutout_length ${cutout_length} \
+ --batch_size ${batch} --rand_seed ${rseed} --workers ${workers} \
+ --eval_frequency 1 --print_freq 500 --print_freq_eval 1000
diff --git a/AutoDL-Projects/scripts/tas-infer-train.sh b/AutoDL-Projects/scripts/tas-infer-train.sh
new file mode 100644
index 0000000..433d5b3
--- /dev/null
+++ b/AutoDL-Projects/scripts/tas-infer-train.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+# bash ./scripts/tas-infer-train.sh cifar10 C100-ResNet32 -1
+set -e
+echo script name: $0
+echo $# arguments
+if [ "$#" -ne 3 ] ;then
+ echo "Input illegal number of parameters " $#
+ echo "Need 3 parameters for the dataset and the-config-name and the-random-seed"
+ exit 1
+fi
+if [ "$TORCH_HOME" = "" ]; then
+ echo "Must set TORCH_HOME envoriment variable for data dir saving"
+ exit 1
+else
+ echo "TORCH_HOME : $TORCH_HOME"
+fi
+
+dataset=$1
+model=$2
+rseed=$3
+batch=256
+
+save_dir=./output/search-shape/TAS-INFER-${dataset}-${model}
+
+if [ ${dataset} == 'cifar10' ] || [ ${dataset} == 'cifar100' ]; then
+ xpath=$TORCH_HOME/cifar.python
+ opt_config=./configs/opts/CIFAR-E300-W5-L1-COS.config
+ workers=4
+elif [ ${dataset} == 'imagenet-1k' ]; then
+ xpath=$TORCH_HOME/ILSVRC2012
+ #opt_config=./configs/opts/ImageNet-E120-Cos-Smooth.config
+ opt_config=./configs/opts/RImageNet-E120-Cos-Soft.config
+ workers=28
+else
+ echo 'Unknown dataset: '${dataset}
+ exit 1
+fi
+
+python --version
+
+# normal training
+xsave_dir=${save_dir}-NMT
+OMP_NUM_THREADS=4 python ./exps/basic/basic-main.py --dataset ${dataset} \
+ --data_path ${xpath} \
+ --model_config ./configs/NeurIPS-2019/${model}.config \
+ --optim_config ${opt_config} \
+ --procedure basic \
+ --save_dir ${xsave_dir} \
+ --cutout_length -1 \
+ --batch_size ${batch} --rand_seed ${rseed} --workers ${workers} \
+ --eval_frequency 1 --print_freq 100 --print_freq_eval 200
+
+# KD training
+xsave_dir=${save_dir}-KDT
+OMP_NUM_THREADS=4 python ./exps/basic/KD-main.py --dataset ${dataset} \
+ --data_path ${xpath} \
+ --model_config ./configs/NeurIPS-2019/${model}.config \
+ --optim_config ${opt_config} \
+ --KD_checkpoint ./.latent-data/basemodels/${dataset}/${model}.pth \
+ --procedure Simple-KD \
+ --save_dir ${xsave_dir} \
+ --KD_alpha 0.9 --KD_temperature 4 \
+ --cutout_length -1 \
+ --batch_size ${batch} --rand_seed ${rseed} --workers ${workers} \
+ --eval_frequency 1 --print_freq 100 --print_freq_eval 200
diff --git a/AutoDL-Projects/scripts/trade/baseline.sh b/AutoDL-Projects/scripts/trade/baseline.sh
new file mode 100644
index 0000000..e9bfe6f
--- /dev/null
+++ b/AutoDL-Projects/scripts/trade/baseline.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+#
+# bash scripts/trade/baseline.sh 0 csi300
+# bash scripts/trade/baseline.sh 1 csi100
+# bash scripts/trade/baseline.sh 1 all
+#
+set -e
+echo script name: $0
+echo $# arguments
+
+if [ "$#" -ne 2 ] ;then
+ echo "Input illegal number of parameters " $#
+ exit 1
+fi
+
+gpu=$1
+market=$2
+
+# algorithms="NAIVE-V1 NAIVE-V2 MLP GRU LSTM ALSTM XGBoost LightGBM SFM TabNet DoubleE"
+algorithms="XGBoost LightGBM SFM TabNet DoubleE"
+
+for alg in ${algorithms}
+do
+ python exps/trading/baselines.py --alg ${alg} --gpu ${gpu} --market ${market}
+done
diff --git a/AutoDL-Projects/scripts/trade/tsf-all.sh b/AutoDL-Projects/scripts/trade/tsf-all.sh
new file mode 100644
index 0000000..acc810b
--- /dev/null
+++ b/AutoDL-Projects/scripts/trade/tsf-all.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+#
+# bash scripts/trade/tsf-all.sh 0 csi300 0_0
+# bash scripts/trade/tsf-all.sh 0 csi300 0.1_0
+# bash scripts/trade/tsf-all.sh 1 all
+#
+set -e
+echo script name: $0
+echo $# arguments
+
+if [ "$#" -ne 3 ] ;then
+ echo "Input illegal number of parameters " $#
+ exit 1
+fi
+
+gpu=$1
+market=$2
+drop=$3
+
+channels="6 12 24 32 48 64"
+#depths="1 2 3 4 5 6 7 8"
+
+for channel in ${channels}
+do
+ python exps/trading/baselines.py --alg TSF-1x${channel}-drop${drop} \
+ TSF-2x${channel}-drop${drop} \
+ TSF-3x${channel}-drop${drop} \
+ TSF-4x${channel}-drop${drop} \
+ TSF-5x${channel}-drop${drop} \
+ TSF-6x${channel}-drop${drop} \
+ TSF-7x${channel}-drop${drop} \
+ TSF-8x${channel}-drop${drop} \
+ --gpu ${gpu} --market ${market} --shared_dataset True
+done
diff --git a/AutoDL-Projects/scripts/trade/tsf-time.sh b/AutoDL-Projects/scripts/trade/tsf-time.sh
new file mode 100644
index 0000000..ec0aeb3
--- /dev/null
+++ b/AutoDL-Projects/scripts/trade/tsf-time.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+#
+# bash scripts/trade/tsf-time.sh 0 csi300 TSF-2x24-drop0_0
+# bash scripts/trade/tsf-time.sh 1 csi100
+# bash scripts/trade/tsf-time.sh 1 all
+#
+set -e
+echo script name: $0
+echo $# arguments
+
+if [ "$#" -ne 3 ] ;then
+ echo "Input illegal number of parameters " $#
+ exit 1
+fi
+
+gpu=$1
+market=$2
+base=$3
+xtimes="2008-01-01 2008-07-01 2009-01-01 2009-07-01 2010-01-01 2011-01-01 2012-01-01 2013-01-01"
+
+for xtime in ${xtimes}
+do
+
+ python exps/trading/baselines.py --alg ${base}s${xtime} --gpu ${gpu} --market ${market} --shared_dataset False
+
+done
diff --git a/AutoDL-Projects/scripts/trade/tsf.sh b/AutoDL-Projects/scripts/trade/tsf.sh
new file mode 100644
index 0000000..2757c50
--- /dev/null
+++ b/AutoDL-Projects/scripts/trade/tsf.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+#
+# bash scripts/trade/tsf.sh 0 csi300 3 0_0
+# bash scripts/trade/tsf.sh 0 csi300 3 0.1_0
+# bash scripts/trade/tsf.sh 1 csi100 3 0.2_0
+# bash scripts/trade/tsf.sh 1 all 3 0.1_0
+#
+set -e
+echo script name: $0
+echo $# arguments
+
+if [ "$#" -ne 4 ] ;then
+ echo "Input illegal number of parameters " $#
+ exit 1
+fi
+
+gpu=$1
+market=$2
+depth=$3
+drop=$4
+
+channels="6 12 24 32 48 64"
+
+for channel in ${channels}
+do
+
+ python exps/trading/baselines.py --alg TSF-${depth}x${channel}-drop${drop} --gpu ${gpu} --market ${market}
+
+done
diff --git a/AutoDL-Projects/setup.py b/AutoDL-Projects/setup.py
new file mode 100644
index 0000000..c268b78
--- /dev/null
+++ b/AutoDL-Projects/setup.py
@@ -0,0 +1,68 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.05 #
+#####################################################
+"""The setup function for pypi."""
+# The following is to make nats_bench avaliable on Python Package Index (PyPI)
+#
+# conda install -c conda-forge twine # Use twine to upload nats_bench to pypi
+#
+# python setup.py sdist bdist_wheel
+# python setup.py --help-commands
+# twine check dist/*
+#
+# twine upload --repository-url https://test.pypi.org/legacy/ dist/*
+# twine upload dist/*
+# https://pypi.org/project/xautodl
+#
+# TODO(xuanyidong): upload it to conda
+#
+# [2021.06.01] v0.9.9
+# [2021.08.14] v1.0.0
+#
+import os
+from setuptools import setup, find_packages
+
+NAME = "xautodl"
+REQUIRES_PYTHON = ">=3.6"
+DESCRIPTION = "Automated Deep Learning Package"
+
+VERSION = "1.0.0"
+
+
+def read(fname="README.md"):
+ with open(
+ os.path.join(os.path.dirname(__file__), fname), encoding="utf-8"
+ ) as cfile:
+ return cfile.read()
+
+
+# What packages are required for this module to be executed?
+REQUIRED = ["numpy>=1.16.5", "pyyaml>=5.0.0", "fvcore"]
+
+packages = find_packages(
+ exclude=("tests", "scripts", "scripts-search", "lib*", "exps*")
+)
+print("packages: {:}".format(packages))
+
+setup(
+ name=NAME,
+ version=VERSION,
+ author="Xuanyi Dong",
+ author_email="dongxuanyi888@gmail.com",
+ description=DESCRIPTION,
+ license="MIT Licence",
+ keywords="NAS Dataset API DeepLearning",
+ url="https://github.com/D-X-Y/AutoDL-Projects",
+ packages=packages,
+ install_requires=REQUIRED,
+ python_requires=REQUIRES_PYTHON,
+ long_description=read("README.md"),
+ long_description_content_type="text/markdown",
+ classifiers=[
+ "Programming Language :: Python",
+ "Programming Language :: Python :: 3",
+ "Topic :: Database",
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
+ "License :: OSI Approved :: MIT License",
+ ],
+)
diff --git a/AutoDL-Projects/tests/test_basic_space.py b/AutoDL-Projects/tests/test_basic_space.py
new file mode 100644
index 0000000..f0a7fab
--- /dev/null
+++ b/AutoDL-Projects/tests/test_basic_space.py
@@ -0,0 +1,121 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.03 #
+#####################################################
+# pytest tests/test_basic_space.py -s #
+#####################################################
+import random
+import unittest
+
+from xautodl.spaces import Categorical
+from xautodl.spaces import Continuous
+from xautodl.spaces import Integer
+from xautodl.spaces import is_determined
+from xautodl.spaces import get_min
+from xautodl.spaces import get_max
+
+
+class TestBasicSpace(unittest.TestCase):
+ """Test the basic search spaces."""
+
+ def test_categorical(self):
+ space = Categorical(1, 2, 3, 4)
+ for i in range(4):
+ self.assertEqual(space[i], i + 1)
+ self.assertEqual(
+ "Categorical(candidates=[1, 2, 3, 4], default_index=None)", str(space)
+ )
+
+ def test_integer(self):
+ space = Integer(lower=1, upper=4)
+ for i in range(4):
+ self.assertEqual(space[i], i + 1)
+ self.assertEqual("Integer(lower=1, upper=4, default=None)", str(space))
+ self.assertEqual(get_max(space), 4)
+ self.assertEqual(get_min(space), 1)
+
+ def test_continuous(self):
+ random.seed(999)
+ space = Continuous(0, 1)
+ self.assertGreaterEqual(space.random().value, 0)
+ self.assertGreaterEqual(1, space.random().value)
+
+ lower, upper = 1.5, 4.6
+ space = Continuous(lower, upper, log=False)
+ values = []
+ for i in range(1000000):
+ x = space.random(reuse_last=False).value
+ self.assertGreaterEqual(x, lower)
+ self.assertGreaterEqual(upper, x)
+ values.append(x)
+ self.assertAlmostEqual((lower + upper) / 2, sum(values) / len(values), places=2)
+ self.assertEqual(
+ "Continuous(lower=1.5, upper=4.6, default_value=None, log_scale=False)",
+ str(space),
+ )
+
+ def test_determined_and_has(self):
+ # Test Non-nested Space
+ space = Categorical(1, 2, 3, 4)
+ self.assertFalse(space.determined)
+ self.assertTrue(space.has(2))
+ self.assertFalse(space.has(6))
+ space = Categorical(4)
+ self.assertTrue(space.determined)
+
+ space = Continuous(0.11, 0.12)
+ self.assertTrue(space.has(0.115))
+ self.assertFalse(space.has(0.1))
+ self.assertFalse(space.determined)
+ space = Continuous(0.11, 0.11)
+ self.assertTrue(space.determined)
+
+ # Test Nested Space
+ space_1 = Categorical(1, 2, 3, 4)
+ space_2 = Categorical(1)
+ nested_space = Categorical(space_1)
+ self.assertFalse(nested_space.determined)
+ self.assertTrue(nested_space.has(4))
+ nested_space = Categorical(space_2)
+ self.assertTrue(nested_space.determined)
+
+ # Test Nested Space 2
+ nested_space = Categorical(
+ Categorical(1, 2, 3),
+ Categorical(4, Categorical(5, 6, 7, Categorical(8, 9), 10), 11),
+ 12,
+ )
+ print("\nThe nested search space:\n{:}".format(nested_space))
+ for i in range(1, 13):
+ self.assertTrue(nested_space.has(i))
+
+ # Test Simple Op
+ self.assertTrue(is_determined(1))
+ self.assertFalse(is_determined(nested_space))
+
+ def test_duplicate(self):
+ space = Categorical(1, 2, 3, 4)
+ x = space.random()
+ for _ in range(100):
+ self.assertEqual(x, space.random(reuse_last=True))
+
+
+class TestAbstractSpace(unittest.TestCase):
+ """Test the abstract search spaces."""
+
+ def test_continous(self):
+ print("")
+ space = Continuous(0, 1)
+ self.assertEqual(space, space.abstract())
+ print("The abstract search space for Continuous: {:}".format(space.abstract()))
+
+ space = Categorical(1, 2, 3)
+ self.assertEqual(len(space.abstract()), 3)
+ print(space.abstract())
+
+ nested_space = Categorical(
+ Categorical(1, 2, 3),
+ Categorical(4, Categorical(5, 6, 7, Categorical(8, 9), 10), 11),
+ 12,
+ )
+ abstract_nested_space = nested_space.abstract()
+ print("The abstract nested search space:\n{:}".format(abstract_nested_space))
diff --git a/AutoDL-Projects/tests/test_import.py b/AutoDL-Projects/tests/test_import.py
new file mode 100644
index 0000000..88a221d
--- /dev/null
+++ b/AutoDL-Projects/tests/test_import.py
@@ -0,0 +1,21 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.03 #
+#####################################################
+# pytest ./tests/test_import.py #
+#####################################################
+def test_import():
+ from xautodl import config_utils
+ from xautodl import datasets
+ from xautodl import log_utils
+ from xautodl import models
+ from xautodl import nas_infer_model
+ from xautodl import procedures
+ from xautodl import trade_models
+ from xautodl import utils
+
+ from xautodl import xlayers
+ from xautodl import xmisc
+ from xautodl import xmodels
+ from xautodl import spaces
+
+ print("Check all imports done")
diff --git a/AutoDL-Projects/tests/test_loader.py b/AutoDL-Projects/tests/test_loader.py
new file mode 100644
index 0000000..fd3a4a0
--- /dev/null
+++ b/AutoDL-Projects/tests/test_loader.py
@@ -0,0 +1,29 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.03 #
+#####################################################
+# pytest tests/test_loader.py -s #
+#####################################################
+import unittest
+import tempfile
+import torch
+
+from xautodl.datasets import get_datasets
+
+
+def test_simple():
+ xdir = tempfile.mkdtemp()
+ train_data, valid_data, xshape, class_num = get_datasets("cifar10", xdir, -1)
+ print(train_data)
+ print(valid_data)
+
+ xloader = torch.utils.data.DataLoader(
+ train_data, batch_size=256, shuffle=True, num_workers=4, pin_memory=True
+ )
+ print(xloader)
+ print(next(iter(xloader)))
+
+ for i, data in enumerate(xloader):
+ print(i)
+
+
+test_simple()
diff --git a/AutoDL-Projects/tests/test_math_static.py b/AutoDL-Projects/tests/test_math_static.py
new file mode 100644
index 0000000..e55bb7a
--- /dev/null
+++ b/AutoDL-Projects/tests/test_math_static.py
@@ -0,0 +1,32 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.03 #
+#####################################################
+# pytest tests/test_math_static.py -s #
+#####################################################
+import unittest
+
+from xautodl.datasets.math_core import QuadraticSFunc
+from xautodl.datasets.math_core import ConstantFunc
+
+
+class TestConstantFunc(unittest.TestCase):
+ """Test the constant function."""
+
+ def test_simple(self):
+ function = ConstantFunc(0.1)
+ for i in range(100):
+ assert function(i) == 0.1
+
+
+class TestQuadraticSFunc(unittest.TestCase):
+ """Test the quadratic function."""
+
+ def test_simple(self):
+ function = QuadraticSFunc({0: 1, 1: 2, 2: 1})
+ print(function)
+ for x in (0, 0.5, 1):
+ print("f({:})={:}".format(x, function(x)))
+ thresh = 1e-7
+ self.assertTrue(abs(function(0) - 1) < thresh)
+ self.assertTrue(abs(function(0.5) - 0.5 * 0.5 - 2 * 0.5 - 1) < thresh)
+ self.assertTrue(abs(function(1) - 1 - 2 - 1) < thresh)
diff --git a/AutoDL-Projects/tests/test_misc_scheduler.py b/AutoDL-Projects/tests/test_misc_scheduler.py
new file mode 100644
index 0000000..bbf14b5
--- /dev/null
+++ b/AutoDL-Projects/tests/test_misc_scheduler.py
@@ -0,0 +1,73 @@
+####################################################
+# Copyright (c) Facebook, Inc. and its affiliates. #
+####################################################
+# Inspired from https://github.com/facebookresearch/detectron2/blob/master/tests/test_scheduler.py
+####################################################
+import math
+import numpy as np
+from unittest import TestCase
+
+import torch
+
+from xautodl.xmisc.scheduler_utils import CosineParamScheduler, MultiStepParamScheduler
+from xautodl.xmisc.scheduler_utils import LRMultiplier, WarmupParamScheduler
+
+
+class TestScheduler(TestCase):
+ """Test the scheduler."""
+
+ def test_warmup_multistep(self):
+ p = torch.nn.Parameter(torch.zeros(0))
+ opt = torch.optim.SGD([p], lr=5)
+
+ multiplier = WarmupParamScheduler(
+ MultiStepParamScheduler(
+ [1, 0.1, 0.01, 0.001],
+ milestones=[10, 15, 20],
+ num_updates=30,
+ ),
+ 0.001,
+ 5 / 30,
+ )
+ sched = LRMultiplier(opt, multiplier, 30)
+ # This is an equivalent of:
+ # sched = WarmupMultiStepLR(
+ # opt, milestones=[10, 15, 20], gamma=0.1, warmup_factor=0.001, warmup_iters=5)
+
+ p.sum().backward()
+ opt.step()
+
+ lrs = [0.005]
+ for _ in range(30):
+ sched.step()
+ lrs.append(opt.param_groups[0]["lr"])
+ self.assertTrue(np.allclose(lrs[:5], [0.005, 1.004, 2.003, 3.002, 4.001]))
+ self.assertTrue(np.allclose(lrs[5:10], 5.0))
+ self.assertTrue(np.allclose(lrs[10:15], 0.5))
+ self.assertTrue(np.allclose(lrs[15:20], 0.05))
+ self.assertTrue(np.allclose(lrs[20:], 0.005))
+
+ def test_warmup_cosine(self):
+ p = torch.nn.Parameter(torch.zeros(0))
+ opt = torch.optim.SGD([p], lr=5)
+ multiplier = WarmupParamScheduler(
+ CosineParamScheduler(1, 0),
+ 0.001,
+ 5 / 30,
+ )
+ sched = LRMultiplier(opt, multiplier, 30)
+
+ p.sum().backward()
+ opt.step()
+ self.assertEqual(opt.param_groups[0]["lr"], 0.005)
+ lrs = [0.005]
+
+ for _ in range(30):
+ sched.step()
+ lrs.append(opt.param_groups[0]["lr"])
+ for idx, lr in enumerate(lrs):
+ expected_cosine = 2.5 * (1.0 + math.cos(math.pi * idx / 30))
+ if idx >= 5:
+ self.assertAlmostEqual(lr, expected_cosine)
+ else:
+ self.assertNotAlmostEqual(lr, expected_cosine)
diff --git a/AutoDL-Projects/tests/test_super_att.py b/AutoDL-Projects/tests/test_super_att.py
new file mode 100644
index 0000000..8fbdb35
--- /dev/null
+++ b/AutoDL-Projects/tests/test_super_att.py
@@ -0,0 +1,67 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.03 #
+#####################################################
+# pytest ./tests/test_super_att.py -s #
+#####################################################
+import random
+import unittest
+from parameterized import parameterized
+
+import torch
+from xautodl import spaces
+from xautodl.xlayers import super_core
+
+
+class TestSuperSelfAttention(unittest.TestCase):
+ """Test the super attention layer."""
+
+ def _internal_func(self, inputs, model):
+ outputs = model(inputs)
+ abstract_space = model.abstract_search_space
+ print(
+ "The abstract search space for SuperSelfAttention is:\n{:}".format(
+ abstract_space
+ )
+ )
+ abstract_space.clean_last()
+ abstract_child = abstract_space.random(reuse_last=True)
+ print("The abstract child program is:\n{:}".format(abstract_child))
+ model.set_super_run_type(super_core.SuperRunMode.Candidate)
+ model.enable_candidate()
+ model.apply_candidate(abstract_child)
+ outputs = model(inputs)
+ return abstract_child, outputs
+
+ def test_super_attention(self):
+ proj_dim = spaces.Categorical(12, 24, 36)
+ num_heads = spaces.Categorical(2, 4, 6)
+ model = super_core.SuperSelfAttention(10, proj_dim, num_heads)
+ print(model)
+ model.apply_verbose(True)
+
+ inputs = torch.rand(4, 20, 10) # batch size, sequence length, channel
+ abstract_child, outputs = self._internal_func(inputs, model)
+ output_shape = (4, 20, abstract_child["proj"]["_out_features"].value)
+ self.assertEqual(tuple(outputs.shape), output_shape)
+
+ @parameterized.expand([[6], [12], [24], [48]])
+ def test_transformer_encoder(self, input_dim):
+ output_dim = spaces.Categorical(12, 24, 36)
+ model = super_core.SuperSequential(
+ super_core.SuperLinear(input_dim, output_dim),
+ super_core.SuperTransformerEncoderLayer(
+ output_dim,
+ num_heads=spaces.Categorical(2, 4, 6),
+ mlp_hidden_multiplier=spaces.Categorical(1, 2, 4),
+ ),
+ )
+ print(model)
+ model.apply_verbose(True)
+ inputs = torch.rand(4, 20, input_dim)
+ abstract_child, outputs = self._internal_func(inputs, model)
+ output_shape = (
+ 4,
+ 20,
+ output_dim.abstract(reuse_last=True).random(reuse_last=True).value,
+ )
+ self.assertEqual(tuple(outputs.shape), output_shape)
diff --git a/AutoDL-Projects/tests/test_super_container.py b/AutoDL-Projects/tests/test_super_container.py
new file mode 100644
index 0000000..a14f539
--- /dev/null
+++ b/AutoDL-Projects/tests/test_super_container.py
@@ -0,0 +1,85 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.03 #
+#####################################################
+# pytest ./tests/test_super_container.py -s #
+#####################################################
+import random
+import unittest
+import pytest
+
+import torch
+from xautodl import spaces
+from xautodl.xlayers import super_core
+
+
+"""Test the super container layers."""
+
+
+def _internal_func(inputs, model):
+ outputs = model(inputs)
+ abstract_space = model.abstract_search_space
+ print(
+ "The abstract search space for SuperAttention is:\n{:}".format(abstract_space)
+ )
+ abstract_space.clean_last()
+ abstract_child = abstract_space.random(reuse_last=True)
+ print("The abstract child program is:\n{:}".format(abstract_child))
+ model.enable_candidate()
+ model.set_super_run_type(super_core.SuperRunMode.Candidate)
+ model.apply_candidate(abstract_child)
+ outputs = model(inputs)
+ return abstract_child, outputs
+
+
+def _create_stel(input_dim, output_dim, order):
+ return super_core.SuperSequential(
+ super_core.SuperLinear(input_dim, output_dim),
+ super_core.SuperTransformerEncoderLayer(
+ output_dim,
+ num_heads=spaces.Categorical(2, 4, 6),
+ mlp_hidden_multiplier=spaces.Categorical(1, 2, 4),
+ order=order,
+ ),
+ )
+
+
+@pytest.mark.parametrize("batch", (1, 2, 4))
+@pytest.mark.parametrize("seq_dim", (1, 10, 30))
+@pytest.mark.parametrize("input_dim", (6, 12, 24, 27))
+@pytest.mark.parametrize(
+ "order", (super_core.LayerOrder.PreNorm, super_core.LayerOrder.PostNorm)
+)
+def test_super_sequential(batch, seq_dim, input_dim, order):
+ out1_dim = spaces.Categorical(12, 24, 36)
+ out2_dim = spaces.Categorical(24, 36, 48)
+ out3_dim = spaces.Categorical(36, 72, 100)
+ layer1 = _create_stel(input_dim, out1_dim, order)
+ layer2 = _create_stel(out1_dim, out2_dim, order)
+ layer3 = _create_stel(out2_dim, out3_dim, order)
+ model = super_core.SuperSequential(layer1, layer2, layer3)
+ print(model)
+ model.apply_verbose(True)
+ inputs = torch.rand(batch, seq_dim, input_dim)
+ abstract_child, outputs = _internal_func(inputs, model)
+ output_shape = (
+ batch,
+ seq_dim,
+ out3_dim.abstract(reuse_last=True).random(reuse_last=True).value,
+ )
+ assert tuple(outputs.shape) == output_shape
+
+
+def test_super_sequential_v1():
+ model = super_core.SuperSequential(
+ super_core.SuperSimpleNorm(1, 1),
+ torch.nn.ReLU(),
+ super_core.SuperLeakyReLU(),
+ super_core.SuperLinear(10, 10),
+ super_core.SuperReLU(),
+ )
+ inputs = torch.rand(10, 10)
+ print(model)
+ outputs = model(inputs)
+
+ abstract_search_space = model.abstract_search_space
+ print(abstract_search_space)
diff --git a/AutoDL-Projects/tests/test_super_mlp.py b/AutoDL-Projects/tests/test_super_mlp.py
new file mode 100644
index 0000000..b60a68c
--- /dev/null
+++ b/AutoDL-Projects/tests/test_super_mlp.py
@@ -0,0 +1,130 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.03 #
+#####################################################
+# pytest ./tests/test_super_model.py -s #
+#####################################################
+import torch
+import unittest
+
+from xautodl.xlayers import super_core
+from xautodl import spaces
+
+
+class TestSuperLinear(unittest.TestCase):
+ """Test the super linear."""
+
+ def test_super_linear(self):
+ out_features = spaces.Categorical(12, 24, 36)
+ bias = spaces.Categorical(True, False)
+ model = super_core.SuperLinear(10, out_features, bias=bias)
+ print("The simple super linear module is:\n{:}".format(model))
+ model.apply_verbose(True)
+
+ print(model.super_run_type)
+ self.assertTrue(model.bias)
+
+ inputs = torch.rand(20, 10)
+ print("Input shape: {:}".format(inputs.shape))
+ print("Weight shape: {:}".format(model._super_weight.shape))
+ print("Bias shape: {:}".format(model._super_bias.shape))
+ outputs = model(inputs)
+ self.assertEqual(tuple(outputs.shape), (20, 36))
+
+ abstract_space = model.abstract_search_space
+ abstract_space.clean_last()
+ abstract_child = abstract_space.random()
+ print("The abstract searc space:\n{:}".format(abstract_space))
+ print("The abstract child program:\n{:}".format(abstract_child))
+
+ model.set_super_run_type(super_core.SuperRunMode.Candidate)
+ model.enable_candidate()
+ model.apply_candidate(abstract_child)
+
+ output_shape = (20, abstract_child["_out_features"].value)
+ outputs = model(inputs)
+ self.assertEqual(tuple(outputs.shape), output_shape)
+
+ def test_super_mlp_v1(self):
+ hidden_features = spaces.Categorical(12, 24, 36)
+ out_features = spaces.Categorical(24, 36, 48)
+ mlp = super_core.SuperMLPv1(10, hidden_features, out_features)
+ print(mlp)
+ mlp.apply_verbose(False)
+ self.assertTrue(mlp.fc1._out_features, mlp.fc2._in_features)
+
+ inputs = torch.rand(4, 10)
+ outputs = mlp(inputs)
+ self.assertEqual(tuple(outputs.shape), (4, 48))
+
+ abstract_space = mlp.abstract_search_space
+ print(
+ "The abstract search space for SuperMLPv1 is:\n{:}".format(abstract_space)
+ )
+ self.assertEqual(
+ abstract_space["fc1"]["_out_features"],
+ abstract_space["fc2"]["_in_features"],
+ )
+ self.assertTrue(
+ abstract_space["fc1"]["_out_features"]
+ is abstract_space["fc2"]["_in_features"]
+ )
+
+ abstract_space.clean_last()
+ abstract_child = abstract_space.random(reuse_last=True)
+ print("The abstract child program is:\n{:}".format(abstract_child))
+ self.assertEqual(
+ abstract_child["fc1"]["_out_features"].value,
+ abstract_child["fc2"]["_in_features"].value,
+ )
+
+ mlp.set_super_run_type(super_core.SuperRunMode.Candidate)
+ mlp.enable_candidate()
+ mlp.apply_candidate(abstract_child)
+ outputs = mlp(inputs)
+ output_shape = (4, abstract_child["fc2"]["_out_features"].value)
+ self.assertEqual(tuple(outputs.shape), output_shape)
+
+ def test_super_mlp_v2(self):
+ hidden_multiplier = spaces.Categorical(1.0, 2.0, 3.0)
+ out_features = spaces.Categorical(24, 36, 48)
+ mlp = super_core.SuperMLPv2(10, hidden_multiplier, out_features)
+ print(mlp)
+ mlp.apply_verbose(False)
+
+ inputs = torch.rand(4, 10)
+ outputs = mlp(inputs)
+ self.assertEqual(tuple(outputs.shape), (4, 48))
+
+ abstract_space = mlp.abstract_search_space
+ print(
+ "The abstract search space for SuperMLPv2 is:\n{:}".format(abstract_space)
+ )
+
+ abstract_space.clean_last()
+ abstract_child = abstract_space.random(reuse_last=True)
+ print("The abstract child program is:\n{:}".format(abstract_child))
+
+ mlp.set_super_run_type(super_core.SuperRunMode.Candidate)
+ mlp.enable_candidate()
+ mlp.apply_candidate(abstract_child)
+ outputs = mlp(inputs)
+ output_shape = (4, abstract_child["_out_features"].value)
+ self.assertEqual(tuple(outputs.shape), output_shape)
+
+ def test_super_stem(self):
+ out_features = spaces.Categorical(24, 36, 48)
+ model = super_core.SuperAlphaEBDv1(6, out_features)
+ inputs = torch.rand(4, 360)
+
+ abstract_space = model.abstract_search_space
+ abstract_space.clean_last()
+ abstract_child = abstract_space.random(reuse_last=True)
+ print("The abstract searc space:\n{:}".format(abstract_space))
+ print("The abstract child program:\n{:}".format(abstract_child))
+
+ model.set_super_run_type(super_core.SuperRunMode.Candidate)
+ model.enable_candidate()
+ model.apply_candidate(abstract_child)
+ outputs = model(inputs)
+ output_shape = (4, 60, abstract_child["_embed_dim"].value)
+ self.assertEqual(tuple(outputs.shape), output_shape)
diff --git a/AutoDL-Projects/tests/test_super_norm.py b/AutoDL-Projects/tests/test_super_norm.py
new file mode 100644
index 0000000..fc3a5ab
--- /dev/null
+++ b/AutoDL-Projects/tests/test_super_norm.py
@@ -0,0 +1,79 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.03 #
+#####################################################
+# pytest ./tests/test_super_norm.py -s #
+#####################################################
+import unittest
+
+import torch
+from xautodl.xlayers import super_core
+from xautodl import spaces
+
+
+class TestSuperSimpleNorm(unittest.TestCase):
+ """Test the super simple norm."""
+
+ def test_super_simple_norm(self):
+ out_features = spaces.Categorical(12, 24, 36)
+ bias = spaces.Categorical(True, False)
+ model = super_core.SuperSequential(
+ super_core.SuperSimpleNorm(5, 0.5),
+ super_core.SuperLinear(10, out_features, bias=bias),
+ )
+ print("The simple super module is:\n{:}".format(model))
+ model.apply_verbose(True)
+
+ print(model.super_run_type)
+ self.assertTrue(model[1].bias)
+
+ inputs = torch.rand(20, 10)
+ print("Input shape: {:}".format(inputs.shape))
+ outputs = model(inputs)
+ self.assertEqual(tuple(outputs.shape), (20, 36))
+
+ abstract_space = model.abstract_search_space
+ abstract_space.clean_last()
+ abstract_child = abstract_space.random()
+ print("The abstract searc space:\n{:}".format(abstract_space))
+ print("The abstract child program:\n{:}".format(abstract_child))
+
+ model.set_super_run_type(super_core.SuperRunMode.Candidate)
+ model.enable_candidate()
+ model.apply_candidate(abstract_child)
+
+ output_shape = (20, abstract_child["1"]["_out_features"].value)
+ outputs = model(inputs)
+ self.assertEqual(tuple(outputs.shape), output_shape)
+
+ def test_super_simple_learn_norm(self):
+ out_features = spaces.Categorical(12, 24, 36)
+ bias = spaces.Categorical(True, False)
+ model = super_core.SuperSequential(
+ super_core.SuperSimpleLearnableNorm(),
+ super_core.SuperIdentity(),
+ super_core.SuperLinear(10, out_features, bias=bias),
+ )
+ print("The simple super module is:\n{:}".format(model))
+ model.apply_verbose(True)
+
+ print(model.super_run_type)
+ self.assertTrue(model[2].bias)
+
+ inputs = torch.rand(20, 10)
+ print("Input shape: {:}".format(inputs.shape))
+ outputs = model(inputs)
+ self.assertEqual(tuple(outputs.shape), (20, 36))
+
+ abstract_space = model.abstract_search_space
+ abstract_space.clean_last()
+ abstract_child = abstract_space.random()
+ print("The abstract searc space:\n{:}".format(abstract_space))
+ print("The abstract child program:\n{:}".format(abstract_child))
+
+ model.set_super_run_type(super_core.SuperRunMode.Candidate)
+ model.enable_candidate()
+ model.apply_candidate(abstract_child)
+
+ output_shape = (20, abstract_child["2"]["_out_features"].value)
+ outputs = model(inputs)
+ self.assertEqual(tuple(outputs.shape), output_shape)
diff --git a/AutoDL-Projects/tests/test_super_rearrange.py b/AutoDL-Projects/tests/test_super_rearrange.py
new file mode 100644
index 0000000..df1862b
--- /dev/null
+++ b/AutoDL-Projects/tests/test_super_rearrange.py
@@ -0,0 +1,24 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.03 #
+#####################################################
+# pytest ./tests/test_super_rearrange.py -s #
+#####################################################
+import unittest
+
+import torch
+from xautodl import xlayers
+
+
+class TestSuperReArrange(unittest.TestCase):
+ """Test the super re-arrange layer."""
+
+ def test_super_re_arrange(self):
+ layer = xlayers.SuperReArrange(
+ "b c (h p1) (w p2) -> b (h w) (c p1 p2)", p1=4, p2=4
+ )
+ tensor = torch.rand((8, 4, 32, 32))
+ print("The tensor shape: {:}".format(tensor.shape))
+ print(layer)
+ outs = layer(tensor)
+ print("The output tensor shape: {:}".format(outs.shape))
+ assert tuple(outs.shape) == (8, 32 * 32 // 16, 4 * 4 * 4)
diff --git a/AutoDL-Projects/tests/test_super_vit.py b/AutoDL-Projects/tests/test_super_vit.py
new file mode 100644
index 0000000..05b13b1
--- /dev/null
+++ b/AutoDL-Projects/tests/test_super_vit.py
@@ -0,0 +1,43 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.03 #
+#####################################################
+# pytest ./tests/test_super_vit.py -s #
+#####################################################
+import unittest
+from parameterized import parameterized
+
+import torch
+from xautodl.xmodels import transformers
+from xautodl.utils.flop_benchmark import count_parameters
+
+
+class TestSuperViT(unittest.TestCase):
+ """Test the super re-arrange layer."""
+
+ def test_super_vit(self):
+ model = transformers.get_transformer("vit-base-16")
+ tensor = torch.rand((2, 3, 224, 224))
+ print("The tensor shape: {:}".format(tensor.shape))
+ # print(model)
+ outs = model(tensor)
+ print("The output tensor shape: {:}".format(outs.shape))
+
+ @parameterized.expand(
+ [
+ ["vit-cifar10-p4-d4-h4-c32", 32],
+ ["vit-base-16", 224],
+ ["vit-large-16", 224],
+ ["vit-huge-14", 224],
+ ]
+ )
+ def test_imagenet(self, name, resolution):
+ tensor = torch.rand((2, 3, resolution, resolution))
+ config = transformers.name2config[name]
+ model = transformers.get_transformer(config)
+ outs = model(tensor)
+ size = count_parameters(model, "mb", True)
+ print(
+ "{:10s} : size={:.2f}MB, out-shape: {:}".format(
+ name, size, tuple(outs.shape)
+ )
+ )
diff --git a/AutoDL-Projects/tests/test_synthetic_env.py b/AutoDL-Projects/tests/test_synthetic_env.py
new file mode 100644
index 0000000..4f2d75a
--- /dev/null
+++ b/AutoDL-Projects/tests/test_synthetic_env.py
@@ -0,0 +1,20 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.04 #
+#####################################################
+# pytest tests/test_synthetic_env.py -s #
+#####################################################
+import unittest
+
+from xautodl.datasets.synthetic_core import get_synthetic_env
+
+
+class TestSynethicEnv(unittest.TestCase):
+ """Test the synethtic environment."""
+
+ def test_simple(self):
+ versions = ["v1", "v2", "v3", "v4"]
+ for version in versions:
+ env = get_synthetic_env(version=version)
+ print(env)
+ for timestamp, (x, y) in env:
+ self.assertEqual(x.shape, (1000, env._data_generator.ndim))
diff --git a/AutoDL-Projects/tests/test_synthetic_utils.py b/AutoDL-Projects/tests/test_synthetic_utils.py
new file mode 100644
index 0000000..e366ab2
--- /dev/null
+++ b/AutoDL-Projects/tests/test_synthetic_utils.py
@@ -0,0 +1,23 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.03 #
+#####################################################
+# pytest tests/test_synthetic_utils.py -s #
+#####################################################
+import unittest
+
+from xautodl.datasets.synthetic_core import TimeStamp
+
+
+class TestTimeStamp(unittest.TestCase):
+ """Test the timestamp generator."""
+
+ def test_simple(self):
+ for mode in (None, "train", "valid", "test"):
+ generator = TimeStamp(0, 1)
+ print(generator)
+ for idx, (i, xtime) in enumerate(generator):
+ self.assertTrue(i == idx)
+ if idx == 0:
+ self.assertTrue(xtime == 0)
+ if idx + 1 == len(generator):
+ self.assertTrue(abs(xtime - 1) < 1e-8)
diff --git a/AutoDL-Projects/tests/test_tas.py b/AutoDL-Projects/tests/test_tas.py
new file mode 100644
index 0000000..53f3702
--- /dev/null
+++ b/AutoDL-Projects/tests/test_tas.py
@@ -0,0 +1,24 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019 #
+##################################################
+import torch
+import torch.nn as nn
+import unittest
+
+from xautodl.models.shape_searchs.SoftSelect import ChannelWiseInter
+
+
+class TestTASFunc(unittest.TestCase):
+ """Test the TAS function."""
+
+ def test_channel_interplation(self):
+ tensors = torch.rand((16, 128, 7, 7))
+
+ for oc in range(200, 210):
+ out_v1 = ChannelWiseInter(tensors, oc, "v1")
+ out_v2 = ChannelWiseInter(tensors, oc, "v2")
+ assert (out_v1 == out_v2).any().item() == 1
+ for oc in range(48, 160):
+ out_v1 = ChannelWiseInter(tensors, oc, "v1")
+ out_v2 = ChannelWiseInter(tensors, oc, "v2")
+ assert (out_v1 == out_v2).any().item() == 1
diff --git a/AutoDL-Projects/tests/test_torch.sh b/AutoDL-Projects/tests/test_torch.sh
new file mode 100644
index 0000000..989d682
--- /dev/null
+++ b/AutoDL-Projects/tests/test_torch.sh
@@ -0,0 +1,4 @@
+# bash ./tests/test_torch.sh
+
+pytest ./tests/test_torch_gpu_bugs.py::test_create -s
+CUDA_VISIBLE_DEVICES="" pytest ./tests/test_torch_gpu_bugs.py::test_load -s
diff --git a/AutoDL-Projects/tests/test_torch_gpu_bugs.py b/AutoDL-Projects/tests/test_torch_gpu_bugs.py
new file mode 100644
index 0000000..6c3731d
--- /dev/null
+++ b/AutoDL-Projects/tests/test_torch_gpu_bugs.py
@@ -0,0 +1,40 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.03 #
+#####################################################
+# pytest ./tests/test_torch_gpu_bugs.py::test_create
+#
+# CUDA_VISIBLE_DEVICES="" pytest ./tests/test_torch_gpu_bugs.py::test_load
+#####################################################
+import os, sys, time, torch
+import pickle
+import tempfile
+from pathlib import Path
+
+root_dir = (Path(__file__).parent / ".." / "..").resolve()
+
+from xautodl.trade_models.quant_transformer import QuantTransformer
+
+
+def test_create():
+ """Test the basic quant-model."""
+ if not torch.cuda.is_available():
+ return
+ quant_model = QuantTransformer(GPU=0)
+ temp_dir = root_dir / "tests" / ".pytest_cache"
+ temp_dir.mkdir(parents=True, exist_ok=True)
+ temp_file = temp_dir / "quant-model.pkl"
+ with temp_file.open("wb") as f:
+ # quant_model.to(None)
+ quant_model.to("cpu")
+ # del quant_model.model
+ # del quant_model.train_optimizer
+ pickle.dump(quant_model, f)
+ print("save into {:}".format(temp_file))
+
+
+def test_load():
+ temp_file = root_dir / "tests" / ".pytest_cache" / "quant-model.pkl"
+ with temp_file.open("rb") as f:
+ model = pickle.load(f)
+ print(model.model)
+ print(model.train_optimizer)
diff --git a/AutoDL-Projects/xautodl/__init__.py b/AutoDL-Projects/xautodl/__init__.py
new file mode 100644
index 0000000..9efccfe
--- /dev/null
+++ b/AutoDL-Projects/xautodl/__init__.py
@@ -0,0 +1,12 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.05 #
+#####################################################
+# An Automated Deep Learning Package to support #
+# research activities. #
+#####################################################
+
+
+def version():
+ versions = ["0.9.9"] # 2021.06.01
+ versions = ["1.0.0"] # 2021.08.14
+ return versions[-1]
diff --git a/AutoDL-Projects/xautodl/config_utils/__init__.py b/AutoDL-Projects/xautodl/config_utils/__init__.py
new file mode 100644
index 0000000..2ee6bae
--- /dev/null
+++ b/AutoDL-Projects/xautodl/config_utils/__init__.py
@@ -0,0 +1,20 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019 #
+##################################################
+# general config related functions
+from .config_utils import load_config, dict2config, configure2str
+
+# the args setting for different experiments
+from .basic_args import obtain_basic_args
+from .attention_args import obtain_attention_args
+from .random_baseline import obtain_RandomSearch_args
+from .cls_kd_args import obtain_cls_kd_args
+from .cls_init_args import obtain_cls_init_args
+from .search_single_args import obtain_search_single_args
+from .search_args import obtain_search_args
+
+# for network pruning
+from .pruning_args import obtain_pruning_args
+
+# utils for args
+from .args_utils import arg_str2bool
diff --git a/AutoDL-Projects/xautodl/config_utils/args_utils.py b/AutoDL-Projects/xautodl/config_utils/args_utils.py
new file mode 100644
index 0000000..f58e475
--- /dev/null
+++ b/AutoDL-Projects/xautodl/config_utils/args_utils.py
@@ -0,0 +1,12 @@
+import argparse
+
+
+def arg_str2bool(v):
+ if isinstance(v, bool):
+ return v
+ elif v.lower() in ("yes", "true", "t", "y", "1"):
+ return True
+ elif v.lower() in ("no", "false", "f", "n", "0"):
+ return False
+ else:
+ raise argparse.ArgumentTypeError("Boolean value expected.")
diff --git a/AutoDL-Projects/xautodl/config_utils/attention_args.py b/AutoDL-Projects/xautodl/config_utils/attention_args.py
new file mode 100644
index 0000000..f5876ac
--- /dev/null
+++ b/AutoDL-Projects/xautodl/config_utils/attention_args.py
@@ -0,0 +1,32 @@
+import random, argparse
+from .share_args import add_shared_args
+
+
+def obtain_attention_args():
+ parser = argparse.ArgumentParser(
+ description="Train a classification model on typical image classification datasets.",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ )
+ parser.add_argument("--resume", type=str, help="Resume path.")
+ parser.add_argument("--init_model", type=str, help="The initialization model path.")
+ parser.add_argument(
+ "--model_config", type=str, help="The path to the model configuration"
+ )
+ parser.add_argument(
+ "--optim_config", type=str, help="The path to the optimizer configuration"
+ )
+ parser.add_argument("--procedure", type=str, help="The procedure basic prefix.")
+ parser.add_argument("--att_channel", type=int, help=".")
+ parser.add_argument("--att_spatial", type=str, help=".")
+ parser.add_argument("--att_active", type=str, help=".")
+ add_shared_args(parser)
+ # Optimization options
+ parser.add_argument(
+ "--batch_size", type=int, default=2, help="Batch size for training."
+ )
+ args = parser.parse_args()
+
+ if args.rand_seed is None or args.rand_seed < 0:
+ args.rand_seed = random.randint(1, 100000)
+ assert args.save_dir is not None, "save-path argument can not be None"
+ return args
diff --git a/AutoDL-Projects/xautodl/config_utils/basic_args.py b/AutoDL-Projects/xautodl/config_utils/basic_args.py
new file mode 100644
index 0000000..21c18b6
--- /dev/null
+++ b/AutoDL-Projects/xautodl/config_utils/basic_args.py
@@ -0,0 +1,44 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020 #
+##################################################
+import random, argparse
+from .share_args import add_shared_args
+
+
+def obtain_basic_args():
+ parser = argparse.ArgumentParser(
+ description="Train a classification model on typical image classification datasets.",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ )
+ parser.add_argument("--resume", type=str, help="Resume path.")
+ parser.add_argument("--init_model", type=str, help="The initialization model path.")
+ parser.add_argument(
+ "--model_config", type=str, help="The path to the model configuration"
+ )
+ parser.add_argument(
+ "--optim_config", type=str, help="The path to the optimizer configuration"
+ )
+ parser.add_argument("--procedure", type=str, help="The procedure basic prefix.")
+ parser.add_argument(
+ "--model_source",
+ type=str,
+ default="normal",
+ help="The source of model defination.",
+ )
+ parser.add_argument(
+ "--extra_model_path",
+ type=str,
+ default=None,
+ help="The extra model ckp file (help to indicate the searched architecture).",
+ )
+ add_shared_args(parser)
+ # Optimization options
+ parser.add_argument(
+ "--batch_size", type=int, default=2, help="Batch size for training."
+ )
+ args = parser.parse_args()
+
+ if args.rand_seed is None or args.rand_seed < 0:
+ args.rand_seed = random.randint(1, 100000)
+ assert args.save_dir is not None, "save-path argument can not be None"
+ return args
diff --git a/AutoDL-Projects/xautodl/config_utils/cls_init_args.py b/AutoDL-Projects/xautodl/config_utils/cls_init_args.py
new file mode 100644
index 0000000..96c5bb9
--- /dev/null
+++ b/AutoDL-Projects/xautodl/config_utils/cls_init_args.py
@@ -0,0 +1,32 @@
+import random, argparse
+from .share_args import add_shared_args
+
+
+def obtain_cls_init_args():
+ parser = argparse.ArgumentParser(
+ description="Train a classification model on typical image classification datasets.",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ )
+ parser.add_argument("--resume", type=str, help="Resume path.")
+ parser.add_argument("--init_model", type=str, help="The initialization model path.")
+ parser.add_argument(
+ "--model_config", type=str, help="The path to the model configuration"
+ )
+ parser.add_argument(
+ "--optim_config", type=str, help="The path to the optimizer configuration"
+ )
+ parser.add_argument("--procedure", type=str, help="The procedure basic prefix.")
+ parser.add_argument(
+ "--init_checkpoint", type=str, help="The checkpoint path to the initial model."
+ )
+ add_shared_args(parser)
+ # Optimization options
+ parser.add_argument(
+ "--batch_size", type=int, default=2, help="Batch size for training."
+ )
+ args = parser.parse_args()
+
+ if args.rand_seed is None or args.rand_seed < 0:
+ args.rand_seed = random.randint(1, 100000)
+ assert args.save_dir is not None, "save-path argument can not be None"
+ return args
diff --git a/AutoDL-Projects/xautodl/config_utils/cls_kd_args.py b/AutoDL-Projects/xautodl/config_utils/cls_kd_args.py
new file mode 100644
index 0000000..03f208a
--- /dev/null
+++ b/AutoDL-Projects/xautodl/config_utils/cls_kd_args.py
@@ -0,0 +1,43 @@
+import random, argparse
+from .share_args import add_shared_args
+
+
+def obtain_cls_kd_args():
+ parser = argparse.ArgumentParser(
+ description="Train a classification model on typical image classification datasets.",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ )
+ parser.add_argument("--resume", type=str, help="Resume path.")
+ parser.add_argument("--init_model", type=str, help="The initialization model path.")
+ parser.add_argument(
+ "--model_config", type=str, help="The path to the model configuration"
+ )
+ parser.add_argument(
+ "--optim_config", type=str, help="The path to the optimizer configuration"
+ )
+ parser.add_argument("--procedure", type=str, help="The procedure basic prefix.")
+ parser.add_argument(
+ "--KD_checkpoint",
+ type=str,
+ help="The teacher checkpoint in knowledge distillation.",
+ )
+ parser.add_argument(
+ "--KD_alpha", type=float, help="The alpha parameter in knowledge distillation."
+ )
+ parser.add_argument(
+ "--KD_temperature",
+ type=float,
+ help="The temperature parameter in knowledge distillation.",
+ )
+ # parser.add_argument('--KD_feature', type=float, help='Knowledge distillation at the feature level.')
+ add_shared_args(parser)
+ # Optimization options
+ parser.add_argument(
+ "--batch_size", type=int, default=2, help="Batch size for training."
+ )
+ args = parser.parse_args()
+
+ if args.rand_seed is None or args.rand_seed < 0:
+ args.rand_seed = random.randint(1, 100000)
+ assert args.save_dir is not None, "save-path argument can not be None"
+ return args
diff --git a/AutoDL-Projects/xautodl/config_utils/config_utils.py b/AutoDL-Projects/xautodl/config_utils/config_utils.py
new file mode 100644
index 0000000..733ecc0
--- /dev/null
+++ b/AutoDL-Projects/xautodl/config_utils/config_utils.py
@@ -0,0 +1,135 @@
+# Copyright (c) Facebook, Inc. and its affiliates.
+# All rights reserved.
+#
+# This source code is licensed under the license found in the
+# LICENSE file in the root directory of this source tree.
+#
+import os, json
+from os import path as osp
+from pathlib import Path
+from collections import namedtuple
+
+support_types = ("str", "int", "bool", "float", "none")
+
+
+def convert_param(original_lists):
+ assert isinstance(original_lists, list), "The type is not right : {:}".format(
+ original_lists
+ )
+ ctype, value = original_lists[0], original_lists[1]
+ assert ctype in support_types, "Ctype={:}, support={:}".format(ctype, support_types)
+ is_list = isinstance(value, list)
+ if not is_list:
+ value = [value]
+ outs = []
+ for x in value:
+ if ctype == "int":
+ x = int(x)
+ elif ctype == "str":
+ x = str(x)
+ elif ctype == "bool":
+ x = bool(int(x))
+ elif ctype == "float":
+ x = float(x)
+ elif ctype == "none":
+ if x.lower() != "none":
+ raise ValueError(
+ "For the none type, the value must be none instead of {:}".format(x)
+ )
+ x = None
+ else:
+ raise TypeError("Does not know this type : {:}".format(ctype))
+ outs.append(x)
+ if not is_list:
+ outs = outs[0]
+ return outs
+
+
+def load_config(path, extra, logger):
+ path = str(path)
+ if hasattr(logger, "log"):
+ logger.log(path)
+ assert os.path.exists(path), "Can not find {:}".format(path)
+ # Reading data back
+ with open(path, "r") as f:
+ data = json.load(f)
+ content = {k: convert_param(v) for k, v in data.items()}
+ assert extra is None or isinstance(
+ extra, dict
+ ), "invalid type of extra : {:}".format(extra)
+ if isinstance(extra, dict):
+ content = {**content, **extra}
+ Arguments = namedtuple("Configure", " ".join(content.keys()))
+ content = Arguments(**content)
+ if hasattr(logger, "log"):
+ logger.log("{:}".format(content))
+ return content
+
+
+def configure2str(config, xpath=None):
+ if not isinstance(config, dict):
+ config = config._asdict()
+
+ def cstring(x):
+ return '"{:}"'.format(x)
+
+ def gtype(x):
+ if isinstance(x, list):
+ x = x[0]
+ if isinstance(x, str):
+ return "str"
+ elif isinstance(x, bool):
+ return "bool"
+ elif isinstance(x, int):
+ return "int"
+ elif isinstance(x, float):
+ return "float"
+ elif x is None:
+ return "none"
+ else:
+ raise ValueError("invalid : {:}".format(x))
+
+ def cvalue(x, xtype):
+ if isinstance(x, list):
+ is_list = True
+ else:
+ is_list, x = False, [x]
+ temps = []
+ for temp in x:
+ if xtype == "bool":
+ temp = cstring(int(temp))
+ elif xtype == "none":
+ temp = cstring("None")
+ else:
+ temp = cstring(temp)
+ temps.append(temp)
+ if is_list:
+ return "[{:}]".format(", ".join(temps))
+ else:
+ return temps[0]
+
+ xstrings = []
+ for key, value in config.items():
+ xtype = gtype(value)
+ string = " {:20s} : [{:8s}, {:}]".format(
+ cstring(key), cstring(xtype), cvalue(value, xtype)
+ )
+ xstrings.append(string)
+ Fstring = "{\n" + ",\n".join(xstrings) + "\n}"
+ if xpath is not None:
+ parent = Path(xpath).resolve().parent
+ parent.mkdir(parents=True, exist_ok=True)
+ if osp.isfile(xpath):
+ os.remove(xpath)
+ with open(xpath, "w") as text_file:
+ text_file.write("{:}".format(Fstring))
+ return Fstring
+
+
+def dict2config(xdict, logger):
+ assert isinstance(xdict, dict), "invalid type : {:}".format(type(xdict))
+ Arguments = namedtuple("Configure", " ".join(xdict.keys()))
+ content = Arguments(**xdict)
+ if hasattr(logger, "log"):
+ logger.log("{:}".format(content))
+ return content
diff --git a/AutoDL-Projects/xautodl/config_utils/pruning_args.py b/AutoDL-Projects/xautodl/config_utils/pruning_args.py
new file mode 100644
index 0000000..01d3504
--- /dev/null
+++ b/AutoDL-Projects/xautodl/config_utils/pruning_args.py
@@ -0,0 +1,48 @@
+import os, sys, time, random, argparse
+from .share_args import add_shared_args
+
+
+def obtain_pruning_args():
+ parser = argparse.ArgumentParser(
+ description="Train a classification model on typical image classification datasets.",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ )
+ parser.add_argument("--resume", type=str, help="Resume path.")
+ parser.add_argument("--init_model", type=str, help="The initialization model path.")
+ parser.add_argument(
+ "--model_config", type=str, help="The path to the model configuration"
+ )
+ parser.add_argument(
+ "--optim_config", type=str, help="The path to the optimizer configuration"
+ )
+ parser.add_argument("--procedure", type=str, help="The procedure basic prefix.")
+ parser.add_argument(
+ "--keep_ratio",
+ type=float,
+ help="The left channel ratio compared to the original network.",
+ )
+ parser.add_argument("--model_version", type=str, help="The network version.")
+ parser.add_argument(
+ "--KD_alpha", type=float, help="The alpha parameter in knowledge distillation."
+ )
+ parser.add_argument(
+ "--KD_temperature",
+ type=float,
+ help="The temperature parameter in knowledge distillation.",
+ )
+ parser.add_argument("--Regular_W_feat", type=float, help="The .")
+ parser.add_argument("--Regular_W_conv", type=float, help="The .")
+ add_shared_args(parser)
+ # Optimization options
+ parser.add_argument(
+ "--batch_size", type=int, default=2, help="Batch size for training."
+ )
+ args = parser.parse_args()
+
+ if args.rand_seed is None or args.rand_seed < 0:
+ args.rand_seed = random.randint(1, 100000)
+ assert args.save_dir is not None, "save-path argument can not be None"
+ assert (
+ args.keep_ratio > 0 and args.keep_ratio <= 1
+ ), "invalid keep ratio : {:}".format(args.keep_ratio)
+ return args
diff --git a/AutoDL-Projects/xautodl/config_utils/random_baseline.py b/AutoDL-Projects/xautodl/config_utils/random_baseline.py
new file mode 100644
index 0000000..184da91
--- /dev/null
+++ b/AutoDL-Projects/xautodl/config_utils/random_baseline.py
@@ -0,0 +1,44 @@
+import os, sys, time, random, argparse
+from .share_args import add_shared_args
+
+
+def obtain_RandomSearch_args():
+ parser = argparse.ArgumentParser(
+ description="Train a classification model on typical image classification datasets.",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ )
+ parser.add_argument("--resume", type=str, help="Resume path.")
+ parser.add_argument("--init_model", type=str, help="The initialization model path.")
+ parser.add_argument(
+ "--expect_flop", type=float, help="The expected flop keep ratio."
+ )
+ parser.add_argument(
+ "--arch_nums",
+ type=int,
+ help="The maximum number of running random arch generating..",
+ )
+ parser.add_argument(
+ "--model_config", type=str, help="The path to the model configuration"
+ )
+ parser.add_argument(
+ "--optim_config", type=str, help="The path to the optimizer configuration"
+ )
+ parser.add_argument(
+ "--random_mode",
+ type=str,
+ choices=["random", "fix"],
+ help="The path to the optimizer configuration",
+ )
+ parser.add_argument("--procedure", type=str, help="The procedure basic prefix.")
+ add_shared_args(parser)
+ # Optimization options
+ parser.add_argument(
+ "--batch_size", type=int, default=2, help="Batch size for training."
+ )
+ args = parser.parse_args()
+
+ if args.rand_seed is None or args.rand_seed < 0:
+ args.rand_seed = random.randint(1, 100000)
+ assert args.save_dir is not None, "save-path argument can not be None"
+ # assert args.flop_ratio_min < args.flop_ratio_max, 'flop-ratio {:} vs {:}'.format(args.flop_ratio_min, args.flop_ratio_max)
+ return args
diff --git a/AutoDL-Projects/xautodl/config_utils/search_args.py b/AutoDL-Projects/xautodl/config_utils/search_args.py
new file mode 100644
index 0000000..2d278dc
--- /dev/null
+++ b/AutoDL-Projects/xautodl/config_utils/search_args.py
@@ -0,0 +1,53 @@
+import os, sys, time, random, argparse
+from .share_args import add_shared_args
+
+
+def obtain_search_args():
+ parser = argparse.ArgumentParser(
+ description="Train a classification model on typical image classification datasets.",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ )
+ parser.add_argument("--resume", type=str, help="Resume path.")
+ parser.add_argument(
+ "--model_config", type=str, help="The path to the model configuration"
+ )
+ parser.add_argument(
+ "--optim_config", type=str, help="The path to the optimizer configuration"
+ )
+ parser.add_argument("--split_path", type=str, help="The split file path.")
+ # parser.add_argument('--arch_para_pure', type=int, help='The architecture-parameter pure or not.')
+ parser.add_argument(
+ "--gumbel_tau_max", type=float, help="The maximum tau for Gumbel."
+ )
+ parser.add_argument(
+ "--gumbel_tau_min", type=float, help="The minimum tau for Gumbel."
+ )
+ parser.add_argument("--procedure", type=str, help="The procedure basic prefix.")
+ parser.add_argument("--FLOP_ratio", type=float, help="The expected FLOP ratio.")
+ parser.add_argument("--FLOP_weight", type=float, help="The loss weight for FLOP.")
+ parser.add_argument(
+ "--FLOP_tolerant", type=float, help="The tolerant range for FLOP."
+ )
+ # ablation studies
+ parser.add_argument(
+ "--ablation_num_select",
+ type=int,
+ help="The number of randomly selected channels.",
+ )
+ add_shared_args(parser)
+ # Optimization options
+ parser.add_argument(
+ "--batch_size", type=int, default=2, help="Batch size for training."
+ )
+ args = parser.parse_args()
+
+ if args.rand_seed is None or args.rand_seed < 0:
+ args.rand_seed = random.randint(1, 100000)
+ assert args.save_dir is not None, "save-path argument can not be None"
+ assert args.gumbel_tau_max is not None and args.gumbel_tau_min is not None
+ assert (
+ args.FLOP_tolerant is not None and args.FLOP_tolerant > 0
+ ), "invalid FLOP_tolerant : {:}".format(FLOP_tolerant)
+ # assert args.arch_para_pure is not None, 'arch_para_pure is not None: {:}'.format(args.arch_para_pure)
+ # args.arch_para_pure = bool(args.arch_para_pure)
+ return args
diff --git a/AutoDL-Projects/xautodl/config_utils/search_single_args.py b/AutoDL-Projects/xautodl/config_utils/search_single_args.py
new file mode 100644
index 0000000..6203b17
--- /dev/null
+++ b/AutoDL-Projects/xautodl/config_utils/search_single_args.py
@@ -0,0 +1,48 @@
+import os, sys, time, random, argparse
+from .share_args import add_shared_args
+
+
+def obtain_search_single_args():
+ parser = argparse.ArgumentParser(
+ description="Train a classification model on typical image classification datasets.",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ )
+ parser.add_argument("--resume", type=str, help="Resume path.")
+ parser.add_argument(
+ "--model_config", type=str, help="The path to the model configuration"
+ )
+ parser.add_argument(
+ "--optim_config", type=str, help="The path to the optimizer configuration"
+ )
+ parser.add_argument("--split_path", type=str, help="The split file path.")
+ parser.add_argument("--search_shape", type=str, help="The shape to be searched.")
+ # parser.add_argument('--arch_para_pure', type=int, help='The architecture-parameter pure or not.')
+ parser.add_argument(
+ "--gumbel_tau_max", type=float, help="The maximum tau for Gumbel."
+ )
+ parser.add_argument(
+ "--gumbel_tau_min", type=float, help="The minimum tau for Gumbel."
+ )
+ parser.add_argument("--procedure", type=str, help="The procedure basic prefix.")
+ parser.add_argument("--FLOP_ratio", type=float, help="The expected FLOP ratio.")
+ parser.add_argument("--FLOP_weight", type=float, help="The loss weight for FLOP.")
+ parser.add_argument(
+ "--FLOP_tolerant", type=float, help="The tolerant range for FLOP."
+ )
+ add_shared_args(parser)
+ # Optimization options
+ parser.add_argument(
+ "--batch_size", type=int, default=2, help="Batch size for training."
+ )
+ args = parser.parse_args()
+
+ if args.rand_seed is None or args.rand_seed < 0:
+ args.rand_seed = random.randint(1, 100000)
+ assert args.save_dir is not None, "save-path argument can not be None"
+ assert args.gumbel_tau_max is not None and args.gumbel_tau_min is not None
+ assert (
+ args.FLOP_tolerant is not None and args.FLOP_tolerant > 0
+ ), "invalid FLOP_tolerant : {:}".format(FLOP_tolerant)
+ # assert args.arch_para_pure is not None, 'arch_para_pure is not None: {:}'.format(args.arch_para_pure)
+ # args.arch_para_pure = bool(args.arch_para_pure)
+ return args
diff --git a/AutoDL-Projects/xautodl/config_utils/share_args.py b/AutoDL-Projects/xautodl/config_utils/share_args.py
new file mode 100644
index 0000000..241696e
--- /dev/null
+++ b/AutoDL-Projects/xautodl/config_utils/share_args.py
@@ -0,0 +1,39 @@
+import os, sys, time, random, argparse
+
+
+def add_shared_args(parser):
+ # Data Generation
+ parser.add_argument("--dataset", type=str, help="The dataset name.")
+ parser.add_argument("--data_path", type=str, help="The dataset name.")
+ parser.add_argument(
+ "--cutout_length", type=int, help="The cutout length, negative means not use."
+ )
+ # Printing
+ parser.add_argument(
+ "--print_freq", type=int, default=100, help="print frequency (default: 200)"
+ )
+ parser.add_argument(
+ "--print_freq_eval",
+ type=int,
+ default=100,
+ help="print frequency (default: 200)",
+ )
+ # Checkpoints
+ parser.add_argument(
+ "--eval_frequency",
+ type=int,
+ default=1,
+ help="evaluation frequency (default: 200)",
+ )
+ parser.add_argument(
+ "--save_dir", type=str, help="Folder to save checkpoints and log."
+ )
+ # Acceleration
+ parser.add_argument(
+ "--workers",
+ type=int,
+ default=8,
+ help="number of data loading workers (default: 8)",
+ )
+ # Random Seed
+ parser.add_argument("--rand_seed", type=int, default=-1, help="manual seed")
diff --git a/AutoDL-Projects/xautodl/log_utils/__init__.py b/AutoDL-Projects/xautodl/log_utils/__init__.py
new file mode 100644
index 0000000..4c9f165
--- /dev/null
+++ b/AutoDL-Projects/xautodl/log_utils/__init__.py
@@ -0,0 +1,16 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019 #
+##################################################
+# every package does not rely on pytorch or tensorflow
+# I tried to list all dependency here: os, sys, time, numpy, (possibly) matplotlib
+##################################################
+from .logger import Logger, PrintLogger
+from .meter import AverageMeter
+from .time_utils import (
+ time_for_file,
+ time_string,
+ time_string_short,
+ time_print,
+ convert_secs2time,
+)
+from .pickle_wrap import pickle_save, pickle_load
diff --git a/AutoDL-Projects/xautodl/log_utils/logger.py b/AutoDL-Projects/xautodl/log_utils/logger.py
new file mode 100644
index 0000000..71f3866
--- /dev/null
+++ b/AutoDL-Projects/xautodl/log_utils/logger.py
@@ -0,0 +1,173 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019 #
+##################################################
+from pathlib import Path
+import importlib, warnings
+import os, sys, time, numpy as np
+
+if sys.version_info.major == 2: # Python 2.x
+ from StringIO import StringIO as BIO
+else: # Python 3.x
+ from io import BytesIO as BIO
+
+if importlib.util.find_spec("tensorflow"):
+ import tensorflow as tf
+
+
+class PrintLogger(object):
+ def __init__(self):
+ """Create a summary writer logging to log_dir."""
+ self.name = "PrintLogger"
+
+ def log(self, string):
+ print(string)
+
+ def close(self):
+ print("-" * 30 + " close printer " + "-" * 30)
+
+
+class Logger(object):
+ def __init__(self, log_dir, seed, create_model_dir=True, use_tf=False):
+ """Create a summary writer logging to log_dir."""
+ self.seed = int(seed)
+ self.log_dir = Path(log_dir)
+ self.model_dir = Path(log_dir) / "checkpoint"
+ self.log_dir.mkdir(parents=True, exist_ok=True)
+ if create_model_dir:
+ self.model_dir.mkdir(parents=True, exist_ok=True)
+ # self.meta_dir.mkdir(mode=0o775, parents=True, exist_ok=True)
+
+ self.use_tf = bool(use_tf)
+ self.tensorboard_dir = self.log_dir / (
+ "tensorboard-{:}".format(time.strftime("%d-%h", time.gmtime(time.time())))
+ )
+ # self.tensorboard_dir = self.log_dir / ('tensorboard-{:}'.format(time.strftime( '%d-%h-at-%H:%M:%S', time.gmtime(time.time()) )))
+ self.logger_path = self.log_dir / "seed-{:}-T-{:}.log".format(
+ self.seed, time.strftime("%d-%h-at-%H-%M-%S", time.gmtime(time.time()))
+ )
+ self.logger_file = open(self.logger_path, "w")
+
+ if self.use_tf:
+ self.tensorboard_dir.mkdir(mode=0o775, parents=True, exist_ok=True)
+ self.writer = tf.summary.FileWriter(str(self.tensorboard_dir))
+ else:
+ self.writer = None
+
+ def __repr__(self):
+ return "{name}(dir={log_dir}, use-tf={use_tf}, writer={writer})".format(
+ name=self.__class__.__name__, **self.__dict__
+ )
+
+ def path(self, mode):
+ valids = ("model", "best", "info", "log", None)
+ if mode is None:
+ return self.log_dir
+ elif mode == "model":
+ return self.model_dir / "seed-{:}-basic.pth".format(self.seed)
+ elif mode == "best":
+ return self.model_dir / "seed-{:}-best.pth".format(self.seed)
+ elif mode == "info":
+ return self.log_dir / "seed-{:}-last-info.pth".format(self.seed)
+ elif mode == "log":
+ return self.log_dir
+ else:
+ raise TypeError("Unknow mode = {:}, valid modes = {:}".format(mode, valids))
+
+ def extract_log(self):
+ return self.logger_file
+
+ def close(self):
+ self.logger_file.close()
+ if self.writer is not None:
+ self.writer.close()
+
+ def log(self, string, save=True, stdout=False):
+ if stdout:
+ sys.stdout.write(string)
+ sys.stdout.flush()
+ else:
+ print(string)
+ if save:
+ self.logger_file.write("{:}\n".format(string))
+ self.logger_file.flush()
+
+ def scalar_summary(self, tags, values, step):
+ """Log a scalar variable."""
+ if not self.use_tf:
+ warnings.warn("Do set use-tensorflow installed but call scalar_summary")
+ else:
+ assert isinstance(tags, list) == isinstance(
+ values, list
+ ), "Type : {:} vs {:}".format(type(tags), type(values))
+ if not isinstance(tags, list):
+ tags, values = [tags], [values]
+ for tag, value in zip(tags, values):
+ summary = tf.Summary(
+ value=[tf.Summary.Value(tag=tag, simple_value=value)]
+ )
+ self.writer.add_summary(summary, step)
+ self.writer.flush()
+
+ def image_summary(self, tag, images, step):
+ """Log a list of images."""
+ import scipy
+
+ if not self.use_tf:
+ warnings.warn("Do set use-tensorflow installed but call scalar_summary")
+ return
+
+ img_summaries = []
+ for i, img in enumerate(images):
+ # Write the image to a string
+ try:
+ s = StringIO()
+ except:
+ s = BytesIO()
+ scipy.misc.toimage(img).save(s, format="png")
+
+ # Create an Image object
+ img_sum = tf.Summary.Image(
+ encoded_image_string=s.getvalue(),
+ height=img.shape[0],
+ width=img.shape[1],
+ )
+ # Create a Summary value
+ img_summaries.append(
+ tf.Summary.Value(tag="{}/{}".format(tag, i), image=img_sum)
+ )
+
+ # Create and write Summary
+ summary = tf.Summary(value=img_summaries)
+ self.writer.add_summary(summary, step)
+ self.writer.flush()
+
+ def histo_summary(self, tag, values, step, bins=1000):
+ """Log a histogram of the tensor of values."""
+ if not self.use_tf:
+ raise ValueError("Do not have tensorflow")
+ import tensorflow as tf
+
+ # Create a histogram using numpy
+ counts, bin_edges = np.histogram(values, bins=bins)
+
+ # Fill the fields of the histogram proto
+ hist = tf.HistogramProto()
+ hist.min = float(np.min(values))
+ hist.max = float(np.max(values))
+ hist.num = int(np.prod(values.shape))
+ hist.sum = float(np.sum(values))
+ hist.sum_squares = float(np.sum(values**2))
+
+ # Drop the start of the first bin
+ bin_edges = bin_edges[1:]
+
+ # Add bin edges and counts
+ for edge in bin_edges:
+ hist.bucket_limit.append(edge)
+ for c in counts:
+ hist.bucket.append(c)
+
+ # Create and write Summary
+ summary = tf.Summary(value=[tf.Summary.Value(tag=tag, histo=hist)])
+ self.writer.add_summary(summary, step)
+ self.writer.flush()
diff --git a/AutoDL-Projects/xautodl/log_utils/meter.py b/AutoDL-Projects/xautodl/log_utils/meter.py
new file mode 100644
index 0000000..2bbab98
--- /dev/null
+++ b/AutoDL-Projects/xautodl/log_utils/meter.py
@@ -0,0 +1,120 @@
+import numpy as np
+
+
+class AverageMeter(object):
+ """Computes and stores the average and current value"""
+
+ def __init__(self):
+ self.reset()
+
+ def reset(self):
+ self.val = 0.0
+ self.avg = 0.0
+ self.sum = 0.0
+ self.count = 0.0
+
+ def update(self, val, n=1):
+ self.val = val
+ self.sum += val * n
+ self.count += n
+ self.avg = self.sum / self.count
+
+ def __repr__(self):
+ return "{name}(val={val}, avg={avg}, count={count})".format(
+ name=self.__class__.__name__, **self.__dict__
+ )
+
+
+class RecorderMeter(object):
+ """Computes and stores the minimum loss value and its epoch index"""
+
+ def __init__(self, total_epoch):
+ self.reset(total_epoch)
+
+ def reset(self, total_epoch):
+ assert total_epoch > 0, "total_epoch should be greater than 0 vs {:}".format(
+ total_epoch
+ )
+ self.total_epoch = total_epoch
+ self.current_epoch = 0
+ self.epoch_losses = np.zeros(
+ (self.total_epoch, 2), dtype=np.float32
+ ) # [epoch, train/val]
+ self.epoch_losses = self.epoch_losses - 1
+ self.epoch_accuracy = np.zeros(
+ (self.total_epoch, 2), dtype=np.float32
+ ) # [epoch, train/val]
+ self.epoch_accuracy = self.epoch_accuracy
+
+ def update(self, idx, train_loss, train_acc, val_loss, val_acc):
+ assert (
+ idx >= 0 and idx < self.total_epoch
+ ), "total_epoch : {} , but update with the {} index".format(
+ self.total_epoch, idx
+ )
+ self.epoch_losses[idx, 0] = train_loss
+ self.epoch_losses[idx, 1] = val_loss
+ self.epoch_accuracy[idx, 0] = train_acc
+ self.epoch_accuracy[idx, 1] = val_acc
+ self.current_epoch = idx + 1
+ return self.max_accuracy(False) == self.epoch_accuracy[idx, 1]
+
+ def max_accuracy(self, istrain):
+ if self.current_epoch <= 0:
+ return 0
+ if istrain:
+ return self.epoch_accuracy[: self.current_epoch, 0].max()
+ else:
+ return self.epoch_accuracy[: self.current_epoch, 1].max()
+
+ def plot_curve(self, save_path):
+ import matplotlib
+
+ matplotlib.use("agg")
+ import matplotlib.pyplot as plt
+
+ title = "the accuracy/loss curve of train/val"
+ dpi = 100
+ width, height = 1600, 1000
+ legend_fontsize = 10
+ figsize = width / float(dpi), height / float(dpi)
+
+ fig = plt.figure(figsize=figsize)
+ x_axis = np.array([i for i in range(self.total_epoch)]) # epochs
+ y_axis = np.zeros(self.total_epoch)
+
+ plt.xlim(0, self.total_epoch)
+ plt.ylim(0, 100)
+ interval_y = 5
+ interval_x = 5
+ plt.xticks(np.arange(0, self.total_epoch + interval_x, interval_x))
+ plt.yticks(np.arange(0, 100 + interval_y, interval_y))
+ plt.grid()
+ plt.title(title, fontsize=20)
+ plt.xlabel("the training epoch", fontsize=16)
+ plt.ylabel("accuracy", fontsize=16)
+
+ y_axis[:] = self.epoch_accuracy[:, 0]
+ plt.plot(x_axis, y_axis, color="g", linestyle="-", label="train-accuracy", lw=2)
+ plt.legend(loc=4, fontsize=legend_fontsize)
+
+ y_axis[:] = self.epoch_accuracy[:, 1]
+ plt.plot(x_axis, y_axis, color="y", linestyle="-", label="valid-accuracy", lw=2)
+ plt.legend(loc=4, fontsize=legend_fontsize)
+
+ y_axis[:] = self.epoch_losses[:, 0]
+ plt.plot(
+ x_axis, y_axis * 50, color="g", linestyle=":", label="train-loss-x50", lw=2
+ )
+ plt.legend(loc=4, fontsize=legend_fontsize)
+
+ y_axis[:] = self.epoch_losses[:, 1]
+ plt.plot(
+ x_axis, y_axis * 50, color="y", linestyle=":", label="valid-loss-x50", lw=2
+ )
+ plt.legend(loc=4, fontsize=legend_fontsize)
+
+ if save_path is not None:
+ fig.savefig(save_path, dpi=dpi, bbox_inches="tight")
+ print("---- save figure {} into {}".format(title, save_path))
+ plt.close(fig)
diff --git a/AutoDL-Projects/xautodl/log_utils/pickle_wrap.py b/AutoDL-Projects/xautodl/log_utils/pickle_wrap.py
new file mode 100644
index 0000000..e1f00a4
--- /dev/null
+++ b/AutoDL-Projects/xautodl/log_utils/pickle_wrap.py
@@ -0,0 +1,21 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.01 #
+#####################################################
+import pickle
+from pathlib import Path
+
+
+def pickle_save(obj, path):
+ file_path = Path(path)
+ file_dir = file_path.parent
+ file_dir.mkdir(parents=True, exist_ok=True)
+ with file_path.open("wb") as f:
+ pickle.dump(obj, f)
+
+
+def pickle_load(path):
+ if not Path(path).exists():
+ raise ValueError("{:} does not exists".format(path))
+ with Path(path).open("rb") as f:
+ data = pickle.load(f)
+ return data
diff --git a/AutoDL-Projects/xautodl/log_utils/time_utils.py b/AutoDL-Projects/xautodl/log_utils/time_utils.py
new file mode 100644
index 0000000..dc1ff29
--- /dev/null
+++ b/AutoDL-Projects/xautodl/log_utils/time_utils.py
@@ -0,0 +1,49 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.01 #
+#####################################################
+import time, sys
+import numpy as np
+
+
+def time_for_file():
+ ISOTIMEFORMAT = "%d-%h-at-%H-%M-%S"
+ return "{:}".format(time.strftime(ISOTIMEFORMAT, time.gmtime(time.time())))
+
+
+def time_string():
+ ISOTIMEFORMAT = "%Y-%m-%d %X"
+ string = "[{:}]".format(time.strftime(ISOTIMEFORMAT, time.gmtime(time.time())))
+ return string
+
+
+def time_string_short():
+ ISOTIMEFORMAT = "%Y%m%d"
+ string = "{:}".format(time.strftime(ISOTIMEFORMAT, time.gmtime(time.time())))
+ return string
+
+
+def time_print(string, is_print=True):
+ if is_print:
+ print("{} : {}".format(time_string(), string))
+
+
+def convert_secs2time(epoch_time, return_str=False):
+ need_hour = int(epoch_time / 3600)
+ need_mins = int((epoch_time - 3600 * need_hour) / 60)
+ need_secs = int(epoch_time - 3600 * need_hour - 60 * need_mins)
+ if return_str:
+ str = "[{:02d}:{:02d}:{:02d}]".format(need_hour, need_mins, need_secs)
+ return str
+ else:
+ return need_hour, need_mins, need_secs
+
+
+def print_log(print_string, log):
+ # if isinstance(log, Logger): log.log('{:}'.format(print_string))
+ if hasattr(log, "log"):
+ log.log("{:}".format(print_string))
+ else:
+ print("{:}".format(print_string))
+ if log is not None:
+ log.write("{:}\n".format(print_string))
+ log.flush()
diff --git a/AutoDL-Projects/xautodl/models/CifarDenseNet.py b/AutoDL-Projects/xautodl/models/CifarDenseNet.py
new file mode 100644
index 0000000..eaf8e98
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/CifarDenseNet.py
@@ -0,0 +1,117 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019 #
+##################################################
+import math, torch
+import torch.nn as nn
+import torch.nn.functional as F
+from .initialization import initialize_resnet
+
+
+class Bottleneck(nn.Module):
+ def __init__(self, nChannels, growthRate):
+ super(Bottleneck, self).__init__()
+ interChannels = 4 * growthRate
+ self.bn1 = nn.BatchNorm2d(nChannels)
+ self.conv1 = nn.Conv2d(nChannels, interChannels, kernel_size=1, bias=False)
+ self.bn2 = nn.BatchNorm2d(interChannels)
+ self.conv2 = nn.Conv2d(
+ interChannels, growthRate, kernel_size=3, padding=1, bias=False
+ )
+
+ def forward(self, x):
+ out = self.conv1(F.relu(self.bn1(x)))
+ out = self.conv2(F.relu(self.bn2(out)))
+ out = torch.cat((x, out), 1)
+ return out
+
+
+class SingleLayer(nn.Module):
+ def __init__(self, nChannels, growthRate):
+ super(SingleLayer, self).__init__()
+ self.bn1 = nn.BatchNorm2d(nChannels)
+ self.conv1 = nn.Conv2d(
+ nChannels, growthRate, kernel_size=3, padding=1, bias=False
+ )
+
+ def forward(self, x):
+ out = self.conv1(F.relu(self.bn1(x)))
+ out = torch.cat((x, out), 1)
+ return out
+
+
+class Transition(nn.Module):
+ def __init__(self, nChannels, nOutChannels):
+ super(Transition, self).__init__()
+ self.bn1 = nn.BatchNorm2d(nChannels)
+ self.conv1 = nn.Conv2d(nChannels, nOutChannels, kernel_size=1, bias=False)
+
+ def forward(self, x):
+ out = self.conv1(F.relu(self.bn1(x)))
+ out = F.avg_pool2d(out, 2)
+ return out
+
+
+class DenseNet(nn.Module):
+ def __init__(self, growthRate, depth, reduction, nClasses, bottleneck):
+ super(DenseNet, self).__init__()
+
+ if bottleneck:
+ nDenseBlocks = int((depth - 4) / 6)
+ else:
+ nDenseBlocks = int((depth - 4) / 3)
+
+ self.message = "CifarDenseNet : block : {:}, depth : {:}, reduction : {:}, growth-rate = {:}, class = {:}".format(
+ "bottleneck" if bottleneck else "basic",
+ depth,
+ reduction,
+ growthRate,
+ nClasses,
+ )
+
+ nChannels = 2 * growthRate
+ self.conv1 = nn.Conv2d(3, nChannels, kernel_size=3, padding=1, bias=False)
+
+ self.dense1 = self._make_dense(nChannels, growthRate, nDenseBlocks, bottleneck)
+ nChannels += nDenseBlocks * growthRate
+ nOutChannels = int(math.floor(nChannels * reduction))
+ self.trans1 = Transition(nChannels, nOutChannels)
+
+ nChannels = nOutChannels
+ self.dense2 = self._make_dense(nChannels, growthRate, nDenseBlocks, bottleneck)
+ nChannels += nDenseBlocks * growthRate
+ nOutChannels = int(math.floor(nChannels * reduction))
+ self.trans2 = Transition(nChannels, nOutChannels)
+
+ nChannels = nOutChannels
+ self.dense3 = self._make_dense(nChannels, growthRate, nDenseBlocks, bottleneck)
+ nChannels += nDenseBlocks * growthRate
+
+ self.act = nn.Sequential(
+ nn.BatchNorm2d(nChannels), nn.ReLU(inplace=True), nn.AvgPool2d(8)
+ )
+ self.fc = nn.Linear(nChannels, nClasses)
+
+ self.apply(initialize_resnet)
+
+ def get_message(self):
+ return self.message
+
+ def _make_dense(self, nChannels, growthRate, nDenseBlocks, bottleneck):
+ layers = []
+ for i in range(int(nDenseBlocks)):
+ if bottleneck:
+ layers.append(Bottleneck(nChannels, growthRate))
+ else:
+ layers.append(SingleLayer(nChannels, growthRate))
+ nChannels += growthRate
+ return nn.Sequential(*layers)
+
+ def forward(self, inputs):
+ out = self.conv1(inputs)
+ out = self.trans1(self.dense1(out))
+ out = self.trans2(self.dense2(out))
+ out = self.dense3(out)
+ features = self.act(out)
+ features = features.view(features.size(0), -1)
+ out = self.fc(features)
+ return features, out
diff --git a/AutoDL-Projects/xautodl/models/CifarResNet.py b/AutoDL-Projects/xautodl/models/CifarResNet.py
new file mode 100644
index 0000000..7ab777f
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/CifarResNet.py
@@ -0,0 +1,180 @@
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+from .initialization import initialize_resnet
+from .SharedUtils import additive_func
+
+
+class Downsample(nn.Module):
+ def __init__(self, nIn, nOut, stride):
+ super(Downsample, self).__init__()
+ assert stride == 2 and nOut == 2 * nIn, "stride:{} IO:{},{}".format(
+ stride, nIn, nOut
+ )
+ self.in_dim = nIn
+ self.out_dim = nOut
+ self.avg = nn.AvgPool2d(kernel_size=2, stride=2, padding=0)
+ self.conv = nn.Conv2d(nIn, nOut, kernel_size=1, stride=1, padding=0, bias=False)
+
+ def forward(self, x):
+ x = self.avg(x)
+ out = self.conv(x)
+ return out
+
+
+class ConvBNReLU(nn.Module):
+ def __init__(self, nIn, nOut, kernel, stride, padding, bias, relu):
+ super(ConvBNReLU, self).__init__()
+ self.conv = nn.Conv2d(
+ nIn, nOut, kernel_size=kernel, stride=stride, padding=padding, bias=bias
+ )
+ self.bn = nn.BatchNorm2d(nOut)
+ if relu:
+ self.relu = nn.ReLU(inplace=True)
+ else:
+ self.relu = None
+ self.out_dim = nOut
+ self.num_conv = 1
+
+ def forward(self, x):
+ conv = self.conv(x)
+ bn = self.bn(conv)
+ if self.relu:
+ return self.relu(bn)
+ else:
+ return bn
+
+
+class ResNetBasicblock(nn.Module):
+ expansion = 1
+
+ def __init__(self, inplanes, planes, stride):
+ super(ResNetBasicblock, self).__init__()
+ assert stride == 1 or stride == 2, "invalid stride {:}".format(stride)
+ self.conv_a = ConvBNReLU(inplanes, planes, 3, stride, 1, False, True)
+ self.conv_b = ConvBNReLU(planes, planes, 3, 1, 1, False, False)
+ if stride == 2:
+ self.downsample = Downsample(inplanes, planes, stride)
+ elif inplanes != planes:
+ self.downsample = ConvBNReLU(inplanes, planes, 1, 1, 0, False, False)
+ else:
+ self.downsample = None
+ self.out_dim = planes
+ self.num_conv = 2
+
+ def forward(self, inputs):
+
+ basicblock = self.conv_a(inputs)
+ basicblock = self.conv_b(basicblock)
+
+ if self.downsample is not None:
+ residual = self.downsample(inputs)
+ else:
+ residual = inputs
+ out = additive_func(residual, basicblock)
+ return F.relu(out, inplace=True)
+
+
+class ResNetBottleneck(nn.Module):
+ expansion = 4
+
+ def __init__(self, inplanes, planes, stride):
+ super(ResNetBottleneck, self).__init__()
+ assert stride == 1 or stride == 2, "invalid stride {:}".format(stride)
+ self.conv_1x1 = ConvBNReLU(inplanes, planes, 1, 1, 0, False, True)
+ self.conv_3x3 = ConvBNReLU(planes, planes, 3, stride, 1, False, True)
+ self.conv_1x4 = ConvBNReLU(
+ planes, planes * self.expansion, 1, 1, 0, False, False
+ )
+ if stride == 2:
+ self.downsample = Downsample(inplanes, planes * self.expansion, stride)
+ elif inplanes != planes * self.expansion:
+ self.downsample = ConvBNReLU(
+ inplanes, planes * self.expansion, 1, 1, 0, False, False
+ )
+ else:
+ self.downsample = None
+ self.out_dim = planes * self.expansion
+ self.num_conv = 3
+
+ def forward(self, inputs):
+
+ bottleneck = self.conv_1x1(inputs)
+ bottleneck = self.conv_3x3(bottleneck)
+ bottleneck = self.conv_1x4(bottleneck)
+
+ if self.downsample is not None:
+ residual = self.downsample(inputs)
+ else:
+ residual = inputs
+ out = additive_func(residual, bottleneck)
+ return F.relu(out, inplace=True)
+
+
+class CifarResNet(nn.Module):
+ def __init__(self, block_name, depth, num_classes, zero_init_residual):
+ super(CifarResNet, self).__init__()
+
+ # Model type specifies number of layers for CIFAR-10 and CIFAR-100 model
+ if block_name == "ResNetBasicblock":
+ block = ResNetBasicblock
+ assert (depth - 2) % 6 == 0, "depth should be one of 20, 32, 44, 56, 110"
+ layer_blocks = (depth - 2) // 6
+ elif block_name == "ResNetBottleneck":
+ block = ResNetBottleneck
+ assert (depth - 2) % 9 == 0, "depth should be one of 164"
+ layer_blocks = (depth - 2) // 9
+ else:
+ raise ValueError("invalid block : {:}".format(block_name))
+
+ self.message = "CifarResNet : Block : {:}, Depth : {:}, Layers for each block : {:}".format(
+ block_name, depth, layer_blocks
+ )
+ self.num_classes = num_classes
+ self.channels = [16]
+ self.layers = nn.ModuleList([ConvBNReLU(3, 16, 3, 1, 1, False, True)])
+ for stage in range(3):
+ for iL in range(layer_blocks):
+ iC = self.channels[-1]
+ planes = 16 * (2 ** stage)
+ stride = 2 if stage > 0 and iL == 0 else 1
+ module = block(iC, planes, stride)
+ self.channels.append(module.out_dim)
+ self.layers.append(module)
+ self.message += "\nstage={:}, ilayer={:02d}/{:02d}, block={:03d}, iC={:3d}, oC={:3d}, stride={:}".format(
+ stage,
+ iL,
+ layer_blocks,
+ len(self.layers) - 1,
+ iC,
+ module.out_dim,
+ stride,
+ )
+
+ self.avgpool = nn.AvgPool2d(8)
+ self.classifier = nn.Linear(module.out_dim, num_classes)
+ assert (
+ sum(x.num_conv for x in self.layers) + 1 == depth
+ ), "invalid depth check {:} vs {:}".format(
+ sum(x.num_conv for x in self.layers) + 1, depth
+ )
+
+ self.apply(initialize_resnet)
+ if zero_init_residual:
+ for m in self.modules():
+ if isinstance(m, ResNetBasicblock):
+ nn.init.constant_(m.conv_b.bn.weight, 0)
+ elif isinstance(m, ResNetBottleneck):
+ nn.init.constant_(m.conv_1x4.bn.weight, 0)
+
+ def get_message(self):
+ return self.message
+
+ def forward(self, inputs):
+ x = inputs
+ for i, layer in enumerate(self.layers):
+ x = layer(x)
+ features = self.avgpool(x)
+ features = features.view(features.size(0), -1)
+ logits = self.classifier(features)
+ return features, logits
diff --git a/AutoDL-Projects/xautodl/models/CifarWideResNet.py b/AutoDL-Projects/xautodl/models/CifarWideResNet.py
new file mode 100644
index 0000000..62e97c3
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/CifarWideResNet.py
@@ -0,0 +1,115 @@
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+from .initialization import initialize_resnet
+
+
+class WideBasicblock(nn.Module):
+ def __init__(self, inplanes, planes, stride, dropout=False):
+ super(WideBasicblock, self).__init__()
+
+ self.bn_a = nn.BatchNorm2d(inplanes)
+ self.conv_a = nn.Conv2d(
+ inplanes, planes, kernel_size=3, stride=stride, padding=1, bias=False
+ )
+
+ self.bn_b = nn.BatchNorm2d(planes)
+ if dropout:
+ self.dropout = nn.Dropout2d(p=0.5, inplace=True)
+ else:
+ self.dropout = None
+ self.conv_b = nn.Conv2d(
+ planes, planes, kernel_size=3, stride=1, padding=1, bias=False
+ )
+
+ if inplanes != planes:
+ self.downsample = nn.Conv2d(
+ inplanes, planes, kernel_size=1, stride=stride, padding=0, bias=False
+ )
+ else:
+ self.downsample = None
+
+ def forward(self, x):
+
+ basicblock = self.bn_a(x)
+ basicblock = F.relu(basicblock)
+ basicblock = self.conv_a(basicblock)
+
+ basicblock = self.bn_b(basicblock)
+ basicblock = F.relu(basicblock)
+ if self.dropout is not None:
+ basicblock = self.dropout(basicblock)
+ basicblock = self.conv_b(basicblock)
+
+ if self.downsample is not None:
+ x = self.downsample(x)
+
+ return x + basicblock
+
+
+class CifarWideResNet(nn.Module):
+ """
+ ResNet optimized for the Cifar dataset, as specified in
+ https://arxiv.org/abs/1512.03385.pdf
+ """
+
+ def __init__(self, depth, widen_factor, num_classes, dropout):
+ super(CifarWideResNet, self).__init__()
+
+ # Model type specifies number of layers for CIFAR-10 and CIFAR-100 model
+ assert (depth - 4) % 6 == 0, "depth should be one of 20, 32, 44, 56, 110"
+ layer_blocks = (depth - 4) // 6
+ print(
+ "CifarPreResNet : Depth : {} , Layers for each block : {}".format(
+ depth, layer_blocks
+ )
+ )
+
+ self.num_classes = num_classes
+ self.dropout = dropout
+ self.conv_3x3 = nn.Conv2d(3, 16, kernel_size=3, stride=1, padding=1, bias=False)
+
+ self.message = "Wide ResNet : depth={:}, widen_factor={:}, class={:}".format(
+ depth, widen_factor, num_classes
+ )
+ self.inplanes = 16
+ self.stage_1 = self._make_layer(
+ WideBasicblock, 16 * widen_factor, layer_blocks, 1
+ )
+ self.stage_2 = self._make_layer(
+ WideBasicblock, 32 * widen_factor, layer_blocks, 2
+ )
+ self.stage_3 = self._make_layer(
+ WideBasicblock, 64 * widen_factor, layer_blocks, 2
+ )
+ self.lastact = nn.Sequential(
+ nn.BatchNorm2d(64 * widen_factor), nn.ReLU(inplace=True)
+ )
+ self.avgpool = nn.AvgPool2d(8)
+ self.classifier = nn.Linear(64 * widen_factor, num_classes)
+
+ self.apply(initialize_resnet)
+
+ def get_message(self):
+ return self.message
+
+ def _make_layer(self, block, planes, blocks, stride):
+
+ layers = []
+ layers.append(block(self.inplanes, planes, stride, self.dropout))
+ self.inplanes = planes
+ for i in range(1, blocks):
+ layers.append(block(self.inplanes, planes, 1, self.dropout))
+
+ return nn.Sequential(*layers)
+
+ def forward(self, x):
+ x = self.conv_3x3(x)
+ x = self.stage_1(x)
+ x = self.stage_2(x)
+ x = self.stage_3(x)
+ x = self.lastact(x)
+ x = self.avgpool(x)
+ features = x.view(x.size(0), -1)
+ outs = self.classifier(features)
+ return features, outs
diff --git a/AutoDL-Projects/xautodl/models/ImageNet_MobileNetV2.py b/AutoDL-Projects/xautodl/models/ImageNet_MobileNetV2.py
new file mode 100644
index 0000000..814ab39
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/ImageNet_MobileNetV2.py
@@ -0,0 +1,117 @@
+# MobileNetV2: Inverted Residuals and Linear Bottlenecks, CVPR 2018
+from torch import nn
+from .initialization import initialize_resnet
+
+
+class ConvBNReLU(nn.Module):
+ def __init__(self, in_planes, out_planes, kernel_size=3, stride=1, groups=1):
+ super(ConvBNReLU, self).__init__()
+ padding = (kernel_size - 1) // 2
+ self.conv = nn.Conv2d(
+ in_planes,
+ out_planes,
+ kernel_size,
+ stride,
+ padding,
+ groups=groups,
+ bias=False,
+ )
+ self.bn = nn.BatchNorm2d(out_planes)
+ self.relu = nn.ReLU6(inplace=True)
+
+ def forward(self, x):
+ out = self.conv(x)
+ out = self.bn(out)
+ out = self.relu(out)
+ return out
+
+
+class InvertedResidual(nn.Module):
+ def __init__(self, inp, oup, stride, expand_ratio):
+ super(InvertedResidual, self).__init__()
+ self.stride = stride
+ assert stride in [1, 2]
+
+ hidden_dim = int(round(inp * expand_ratio))
+ self.use_res_connect = self.stride == 1 and inp == oup
+
+ layers = []
+ if expand_ratio != 1:
+ # pw
+ layers.append(ConvBNReLU(inp, hidden_dim, kernel_size=1))
+ layers.extend(
+ [
+ # dw
+ ConvBNReLU(hidden_dim, hidden_dim, stride=stride, groups=hidden_dim),
+ # pw-linear
+ nn.Conv2d(hidden_dim, oup, 1, 1, 0, bias=False),
+ nn.BatchNorm2d(oup),
+ ]
+ )
+ self.conv = nn.Sequential(*layers)
+
+ def forward(self, x):
+ if self.use_res_connect:
+ return x + self.conv(x)
+ else:
+ return self.conv(x)
+
+
+class MobileNetV2(nn.Module):
+ def __init__(
+ self, num_classes, width_mult, input_channel, last_channel, block_name, dropout
+ ):
+ super(MobileNetV2, self).__init__()
+ if block_name == "InvertedResidual":
+ block = InvertedResidual
+ else:
+ raise ValueError("invalid block name : {:}".format(block_name))
+ inverted_residual_setting = [
+ # t, c, n, s
+ [1, 16, 1, 1],
+ [6, 24, 2, 2],
+ [6, 32, 3, 2],
+ [6, 64, 4, 2],
+ [6, 96, 3, 1],
+ [6, 160, 3, 2],
+ [6, 320, 1, 1],
+ ]
+
+ # building first layer
+ input_channel = int(input_channel * width_mult)
+ self.last_channel = int(last_channel * max(1.0, width_mult))
+ features = [ConvBNReLU(3, input_channel, stride=2)]
+ # building inverted residual blocks
+ for t, c, n, s in inverted_residual_setting:
+ output_channel = int(c * width_mult)
+ for i in range(n):
+ stride = s if i == 0 else 1
+ features.append(
+ block(input_channel, output_channel, stride, expand_ratio=t)
+ )
+ input_channel = output_channel
+ # building last several layers
+ features.append(ConvBNReLU(input_channel, self.last_channel, kernel_size=1))
+ # make it nn.Sequential
+ self.features = nn.Sequential(*features)
+
+ # building classifier
+ self.classifier = nn.Sequential(
+ nn.Dropout(dropout),
+ nn.Linear(self.last_channel, num_classes),
+ )
+ self.message = "MobileNetV2 : width_mult={:}, in-C={:}, last-C={:}, block={:}, dropout={:}".format(
+ width_mult, input_channel, last_channel, block_name, dropout
+ )
+
+ # weight initialization
+ self.apply(initialize_resnet)
+
+ def get_message(self):
+ return self.message
+
+ def forward(self, inputs):
+ features = self.features(inputs)
+ vectors = features.mean([2, 3])
+ predicts = self.classifier(vectors)
+ return features, predicts
diff --git a/AutoDL-Projects/xautodl/models/ImageNet_ResNet.py b/AutoDL-Projects/xautodl/models/ImageNet_ResNet.py
new file mode 100644
index 0000000..66d830a
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/ImageNet_ResNet.py
@@ -0,0 +1,217 @@
+# Deep Residual Learning for Image Recognition, CVPR 2016
+import torch.nn as nn
+from .initialization import initialize_resnet
+
+
+def conv3x3(in_planes, out_planes, stride=1, groups=1):
+ return nn.Conv2d(
+ in_planes,
+ out_planes,
+ kernel_size=3,
+ stride=stride,
+ padding=1,
+ groups=groups,
+ bias=False,
+ )
+
+
+def conv1x1(in_planes, out_planes, stride=1):
+ return nn.Conv2d(in_planes, out_planes, kernel_size=1, stride=stride, bias=False)
+
+
+class BasicBlock(nn.Module):
+ expansion = 1
+
+ def __init__(
+ self, inplanes, planes, stride=1, downsample=None, groups=1, base_width=64
+ ):
+ super(BasicBlock, self).__init__()
+ if groups != 1 or base_width != 64:
+ raise ValueError("BasicBlock only supports groups=1 and base_width=64")
+ # Both self.conv1 and self.downsample layers downsample the input when stride != 1
+ self.conv1 = conv3x3(inplanes, planes, stride)
+ self.bn1 = nn.BatchNorm2d(planes)
+ self.relu = nn.ReLU(inplace=True)
+ self.conv2 = conv3x3(planes, planes)
+ self.bn2 = nn.BatchNorm2d(planes)
+ self.downsample = downsample
+ self.stride = stride
+
+ def forward(self, x):
+ identity = x
+
+ out = self.conv1(x)
+ out = self.bn1(out)
+ out = self.relu(out)
+
+ out = self.conv2(out)
+ out = self.bn2(out)
+
+ if self.downsample is not None:
+ identity = self.downsample(x)
+
+ out += identity
+ out = self.relu(out)
+
+ return out
+
+
+class Bottleneck(nn.Module):
+ expansion = 4
+
+ def __init__(
+ self, inplanes, planes, stride=1, downsample=None, groups=1, base_width=64
+ ):
+ super(Bottleneck, self).__init__()
+ width = int(planes * (base_width / 64.0)) * groups
+ # Both self.conv2 and self.downsample layers downsample the input when stride != 1
+ self.conv1 = conv1x1(inplanes, width)
+ self.bn1 = nn.BatchNorm2d(width)
+ self.conv2 = conv3x3(width, width, stride, groups)
+ self.bn2 = nn.BatchNorm2d(width)
+ self.conv3 = conv1x1(width, planes * self.expansion)
+ self.bn3 = nn.BatchNorm2d(planes * self.expansion)
+ self.relu = nn.ReLU(inplace=True)
+ self.downsample = downsample
+ self.stride = stride
+
+ def forward(self, x):
+ identity = x
+
+ out = self.conv1(x)
+ out = self.bn1(out)
+ out = self.relu(out)
+
+ out = self.conv2(out)
+ out = self.bn2(out)
+ out = self.relu(out)
+
+ out = self.conv3(out)
+ out = self.bn3(out)
+
+ if self.downsample is not None:
+ identity = self.downsample(x)
+
+ out += identity
+ out = self.relu(out)
+
+ return out
+
+
+class ResNet(nn.Module):
+ def __init__(
+ self,
+ block_name,
+ layers,
+ deep_stem,
+ num_classes,
+ zero_init_residual,
+ groups,
+ width_per_group,
+ ):
+ super(ResNet, self).__init__()
+
+ # planes = [int(width_per_group * groups * 2 ** i) for i in range(4)]
+ if block_name == "BasicBlock":
+ block = BasicBlock
+ elif block_name == "Bottleneck":
+ block = Bottleneck
+ else:
+ raise ValueError("invalid block-name : {:}".format(block_name))
+
+ if not deep_stem:
+ self.conv = nn.Sequential(
+ nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, bias=False),
+ nn.BatchNorm2d(64),
+ nn.ReLU(inplace=True),
+ )
+ else:
+ self.conv = nn.Sequential(
+ nn.Conv2d(3, 32, kernel_size=3, stride=2, padding=1, bias=False),
+ nn.BatchNorm2d(32),
+ nn.ReLU(inplace=True),
+ nn.Conv2d(32, 32, kernel_size=3, stride=1, padding=1, bias=False),
+ nn.BatchNorm2d(32),
+ nn.ReLU(inplace=True),
+ nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1, bias=False),
+ nn.BatchNorm2d(64),
+ nn.ReLU(inplace=True),
+ )
+ self.inplanes = 64
+ self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
+ self.layer1 = self._make_layer(
+ block, 64, layers[0], stride=1, groups=groups, base_width=width_per_group
+ )
+ self.layer2 = self._make_layer(
+ block, 128, layers[1], stride=2, groups=groups, base_width=width_per_group
+ )
+ self.layer3 = self._make_layer(
+ block, 256, layers[2], stride=2, groups=groups, base_width=width_per_group
+ )
+ self.layer4 = self._make_layer(
+ block, 512, layers[3], stride=2, groups=groups, base_width=width_per_group
+ )
+ self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
+ self.fc = nn.Linear(512 * block.expansion, num_classes)
+ self.message = (
+ "block = {:}, layers = {:}, deep_stem = {:}, num_classes = {:}".format(
+ block, layers, deep_stem, num_classes
+ )
+ )
+
+ self.apply(initialize_resnet)
+
+ # Zero-initialize the last BN in each residual branch,
+ # so that the residual branch starts with zeros, and each residual block behaves like an identity.
+ # This improves the model by 0.2~0.3% according to https://arxiv.org/abs/1706.02677
+ if zero_init_residual:
+ for m in self.modules():
+ if isinstance(m, Bottleneck):
+ nn.init.constant_(m.bn3.weight, 0)
+ elif isinstance(m, BasicBlock):
+ nn.init.constant_(m.bn2.weight, 0)
+
+ def _make_layer(self, block, planes, blocks, stride, groups, base_width):
+ downsample = None
+ if stride != 1 or self.inplanes != planes * block.expansion:
+ if stride == 2:
+ downsample = nn.Sequential(
+ nn.AvgPool2d(kernel_size=2, stride=2, padding=0),
+ conv1x1(self.inplanes, planes * block.expansion, 1),
+ nn.BatchNorm2d(planes * block.expansion),
+ )
+ elif stride == 1:
+ downsample = nn.Sequential(
+ conv1x1(self.inplanes, planes * block.expansion, stride),
+ nn.BatchNorm2d(planes * block.expansion),
+ )
+ else:
+ raise ValueError("invalid stride [{:}] for downsample".format(stride))
+
+ layers = []
+ layers.append(
+ block(self.inplanes, planes, stride, downsample, groups, base_width)
+ )
+ self.inplanes = planes * block.expansion
+ for _ in range(1, blocks):
+ layers.append(block(self.inplanes, planes, 1, None, groups, base_width))
+
+ return nn.Sequential(*layers)
+
+ def get_message(self):
+ return self.message
+
+ def forward(self, x):
+ x = self.conv(x)
+ x = self.maxpool(x)
+
+ x = self.layer1(x)
+ x = self.layer2(x)
+ x = self.layer3(x)
+ x = self.layer4(x)
+
+ features = self.avgpool(x)
+ features = features.view(features.size(0), -1)
+ logits = self.fc(features)
+
+ return features, logits
diff --git a/AutoDL-Projects/xautodl/models/SharedUtils.py b/AutoDL-Projects/xautodl/models/SharedUtils.py
new file mode 100644
index 0000000..adcdf8b
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/SharedUtils.py
@@ -0,0 +1,37 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.01 #
+#####################################################
+import torch
+import torch.nn as nn
+
+
+def additive_func(A, B):
+ assert A.dim() == B.dim() and A.size(0) == B.size(0), "{:} vs {:}".format(
+ A.size(), B.size()
+ )
+ C = min(A.size(1), B.size(1))
+ if A.size(1) == B.size(1):
+ return A + B
+ elif A.size(1) < B.size(1):
+ out = B.clone()
+ out[:, :C] += A
+ return out
+ else:
+ out = A.clone()
+ out[:, :C] += B
+ return out
+
+
+def change_key(key, value):
+ def func(m):
+ if hasattr(m, key):
+ setattr(m, key, value)
+
+ return func
+
+
+def parse_channel_info(xstring):
+ blocks = xstring.split(" ")
+ blocks = [x.split("-") for x in blocks]
+ blocks = [[int(_) for _ in x] for x in blocks]
+ return blocks
diff --git a/AutoDL-Projects/xautodl/models/__init__.py b/AutoDL-Projects/xautodl/models/__init__.py
new file mode 100644
index 0000000..5f57daf
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/__init__.py
@@ -0,0 +1,326 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019 #
+##################################################
+from os import path as osp
+from typing import List, Text
+import torch
+
+__all__ = [
+ "change_key",
+ "get_cell_based_tiny_net",
+ "get_search_spaces",
+ "get_cifar_models",
+ "get_imagenet_models",
+ "obtain_model",
+ "obtain_search_model",
+ "load_net_from_checkpoint",
+ "CellStructure",
+ "CellArchitectures",
+]
+
+# useful modules
+from xautodl.config_utils import dict2config
+from .SharedUtils import change_key
+from .cell_searchs import CellStructure, CellArchitectures
+
+
+# Cell-based NAS Models
+def get_cell_based_tiny_net(config):
+ if isinstance(config, dict):
+ config = dict2config(config, None) # to support the argument being a dict
+ super_type = getattr(config, "super_type", "basic")
+ group_names = ["DARTS-V1", "DARTS-V2", "GDAS", "SETN", "ENAS", "RANDOM", "generic"]
+ if super_type == "basic" and config.name in group_names:
+ from .cell_searchs import nas201_super_nets as nas_super_nets
+
+ try:
+ return nas_super_nets[config.name](
+ config.C,
+ config.N,
+ config.max_nodes,
+ config.num_classes,
+ config.space,
+ config.affine,
+ config.track_running_stats,
+ )
+ except:
+ return nas_super_nets[config.name](
+ config.C, config.N, config.max_nodes, config.num_classes, config.space
+ )
+ elif super_type == "search-shape":
+ from .shape_searchs import GenericNAS301Model
+
+ genotype = CellStructure.str2structure(config.genotype)
+ return GenericNAS301Model(
+ config.candidate_Cs,
+ config.max_num_Cs,
+ genotype,
+ config.num_classes,
+ config.affine,
+ config.track_running_stats,
+ )
+ elif super_type == "nasnet-super":
+ from .cell_searchs import nasnet_super_nets as nas_super_nets
+
+ return nas_super_nets[config.name](
+ config.C,
+ config.N,
+ config.steps,
+ config.multiplier,
+ config.stem_multiplier,
+ config.num_classes,
+ config.space,
+ config.affine,
+ config.track_running_stats,
+ )
+ elif config.name == "infer.tiny":
+ from .cell_infers import TinyNetwork
+
+ if hasattr(config, "genotype"):
+ genotype = config.genotype
+ elif hasattr(config, "arch_str"):
+ genotype = CellStructure.str2structure(config.arch_str)
+ else:
+ raise ValueError(
+ "Can not find genotype from this config : {:}".format(config)
+ )
+ return TinyNetwork(config.C, config.N, genotype, config.num_classes)
+ elif config.name == "infer.shape.tiny":
+ from .shape_infers import DynamicShapeTinyNet
+
+ if isinstance(config.channels, str):
+ channels = tuple([int(x) for x in config.channels.split(":")])
+ else:
+ channels = config.channels
+ genotype = CellStructure.str2structure(config.genotype)
+ return DynamicShapeTinyNet(channels, genotype, config.num_classes)
+ elif config.name == "infer.nasnet-cifar":
+ from .cell_infers import NASNetonCIFAR
+
+ raise NotImplementedError
+ else:
+ raise ValueError("invalid network name : {:}".format(config.name))
+
+
+# obtain the search space, i.e., a dict mapping the operation name into a python-function for this op
+def get_search_spaces(xtype, name) -> List[Text]:
+ if xtype == "cell" or xtype == "tss": # The topology search space.
+ from .cell_operations import SearchSpaceNames
+
+ assert name in SearchSpaceNames, "invalid name [{:}] in {:}".format(
+ name, SearchSpaceNames.keys()
+ )
+ return SearchSpaceNames[name]
+ elif xtype == "sss": # The size search space.
+ if name in ["nats-bench", "nats-bench-size"]:
+ return {"candidates": [8, 16, 24, 32, 40, 48, 56, 64], "numbers": 5}
+ else:
+ raise ValueError("Invalid name : {:}".format(name))
+ else:
+ raise ValueError("invalid search-space type is {:}".format(xtype))
+
+
+def get_cifar_models(config, extra_path=None):
+ super_type = getattr(config, "super_type", "basic")
+ if super_type == "basic":
+ from .CifarResNet import CifarResNet
+ from .CifarDenseNet import DenseNet
+ from .CifarWideResNet import CifarWideResNet
+
+ if config.arch == "resnet":
+ return CifarResNet(
+ config.module, config.depth, config.class_num, config.zero_init_residual
+ )
+ elif config.arch == "densenet":
+ return DenseNet(
+ config.growthRate,
+ config.depth,
+ config.reduction,
+ config.class_num,
+ config.bottleneck,
+ )
+ elif config.arch == "wideresnet":
+ return CifarWideResNet(
+ config.depth, config.wide_factor, config.class_num, config.dropout
+ )
+ else:
+ raise ValueError("invalid module type : {:}".format(config.arch))
+ elif super_type.startswith("infer"):
+ from .shape_infers import InferWidthCifarResNet
+ from .shape_infers import InferDepthCifarResNet
+ from .shape_infers import InferCifarResNet
+ from .cell_infers import NASNetonCIFAR
+
+ assert len(super_type.split("-")) == 2, "invalid super_type : {:}".format(
+ super_type
+ )
+ infer_mode = super_type.split("-")[1]
+ if infer_mode == "width":
+ return InferWidthCifarResNet(
+ config.module,
+ config.depth,
+ config.xchannels,
+ config.class_num,
+ config.zero_init_residual,
+ )
+ elif infer_mode == "depth":
+ return InferDepthCifarResNet(
+ config.module,
+ config.depth,
+ config.xblocks,
+ config.class_num,
+ config.zero_init_residual,
+ )
+ elif infer_mode == "shape":
+ return InferCifarResNet(
+ config.module,
+ config.depth,
+ config.xblocks,
+ config.xchannels,
+ config.class_num,
+ config.zero_init_residual,
+ )
+ elif infer_mode == "nasnet.cifar":
+ genotype = config.genotype
+ if extra_path is not None: # reload genotype by extra_path
+ if not osp.isfile(extra_path):
+ raise ValueError("invalid extra_path : {:}".format(extra_path))
+ xdata = torch.load(extra_path)
+ current_epoch = xdata["epoch"]
+ genotype = xdata["genotypes"][current_epoch - 1]
+ C = config.C if hasattr(config, "C") else config.ichannel
+ N = config.N if hasattr(config, "N") else config.layers
+ return NASNetonCIFAR(
+ C, N, config.stem_multi, config.class_num, genotype, config.auxiliary
+ )
+ else:
+ raise ValueError("invalid infer-mode : {:}".format(infer_mode))
+ else:
+ raise ValueError("invalid super-type : {:}".format(super_type))
+
+
+def get_imagenet_models(config):
+ super_type = getattr(config, "super_type", "basic")
+ if super_type == "basic":
+ from .ImageNet_ResNet import ResNet
+ from .ImageNet_MobileNetV2 import MobileNetV2
+
+ if config.arch == "resnet":
+ return ResNet(
+ config.block_name,
+ config.layers,
+ config.deep_stem,
+ config.class_num,
+ config.zero_init_residual,
+ config.groups,
+ config.width_per_group,
+ )
+ elif config.arch == "mobilenet_v2":
+ return MobileNetV2(
+ config.class_num,
+ config.width_multi,
+ config.input_channel,
+ config.last_channel,
+ "InvertedResidual",
+ config.dropout,
+ )
+ else:
+ raise ValueError("invalid arch : {:}".format(config.arch))
+ elif super_type.startswith("infer"): # NAS searched architecture
+ assert len(super_type.split("-")) == 2, "invalid super_type : {:}".format(
+ super_type
+ )
+ infer_mode = super_type.split("-")[1]
+ if infer_mode == "shape":
+ from .shape_infers import InferImagenetResNet
+ from .shape_infers import InferMobileNetV2
+
+ if config.arch == "resnet":
+ return InferImagenetResNet(
+ config.block_name,
+ config.layers,
+ config.xblocks,
+ config.xchannels,
+ config.deep_stem,
+ config.class_num,
+ config.zero_init_residual,
+ )
+ elif config.arch == "MobileNetV2":
+ return InferMobileNetV2(
+ config.class_num, config.xchannels, config.xblocks, config.dropout
+ )
+ else:
+ raise ValueError("invalid arch-mode : {:}".format(config.arch))
+ else:
+ raise ValueError("invalid infer-mode : {:}".format(infer_mode))
+ else:
+ raise ValueError("invalid super-type : {:}".format(super_type))
+
+
+# Try to obtain the network by config.
+def obtain_model(config, extra_path=None):
+ if config.dataset == "cifar":
+ return get_cifar_models(config, extra_path)
+ elif config.dataset == "imagenet":
+ return get_imagenet_models(config)
+ else:
+ raise ValueError("invalid dataset in the model config : {:}".format(config))
+
+
+def obtain_search_model(config):
+ if config.dataset == "cifar":
+ if config.arch == "resnet":
+ from .shape_searchs import SearchWidthCifarResNet
+ from .shape_searchs import SearchDepthCifarResNet
+ from .shape_searchs import SearchShapeCifarResNet
+
+ if config.search_mode == "width":
+ return SearchWidthCifarResNet(
+ config.module, config.depth, config.class_num
+ )
+ elif config.search_mode == "depth":
+ return SearchDepthCifarResNet(
+ config.module, config.depth, config.class_num
+ )
+ elif config.search_mode == "shape":
+ return SearchShapeCifarResNet(
+ config.module, config.depth, config.class_num
+ )
+ else:
+ raise ValueError("invalid search mode : {:}".format(config.search_mode))
+ elif config.arch == "simres":
+ from .shape_searchs import SearchWidthSimResNet
+
+ if config.search_mode == "width":
+ return SearchWidthSimResNet(config.depth, config.class_num)
+ else:
+ raise ValueError("invalid search mode : {:}".format(config.search_mode))
+ else:
+ raise ValueError(
+ "invalid arch : {:} for dataset [{:}]".format(
+ config.arch, config.dataset
+ )
+ )
+ elif config.dataset == "imagenet":
+ from .shape_searchs import SearchShapeImagenetResNet
+
+ assert config.search_mode == "shape", "invalid search-mode : {:}".format(
+ config.search_mode
+ )
+ if config.arch == "resnet":
+ return SearchShapeImagenetResNet(
+ config.block_name, config.layers, config.deep_stem, config.class_num
+ )
+ else:
+ raise ValueError("invalid model config : {:}".format(config))
+ else:
+ raise ValueError("invalid dataset in the model config : {:}".format(config))
+
+
+def load_net_from_checkpoint(checkpoint):
+ assert osp.isfile(checkpoint), "checkpoint {:} does not exist".format(checkpoint)
+ checkpoint = torch.load(checkpoint)
+ model_config = dict2config(checkpoint["model-config"], None)
+ model = obtain_model(model_config)
+ model.load_state_dict(checkpoint["base-model"])
+ return model
diff --git a/AutoDL-Projects/xautodl/models/cell_infers/__init__.py b/AutoDL-Projects/xautodl/models/cell_infers/__init__.py
new file mode 100644
index 0000000..ac1a183
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/cell_infers/__init__.py
@@ -0,0 +1,5 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.01 #
+#####################################################
+from .tiny_network import TinyNetwork
+from .nasnet_cifar import NASNetonCIFAR
diff --git a/AutoDL-Projects/xautodl/models/cell_infers/cells.py b/AutoDL-Projects/xautodl/models/cell_infers/cells.py
new file mode 100644
index 0000000..1fa2e98
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/cell_infers/cells.py
@@ -0,0 +1,155 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.01 #
+#####################################################
+
+import torch
+import torch.nn as nn
+from copy import deepcopy
+
+from xautodl.models.cell_operations import OPS
+
+
+# Cell for NAS-Bench-201
+class InferCell(nn.Module):
+ def __init__(
+ self, genotype, C_in, C_out, stride, affine=True, track_running_stats=True
+ ):
+ super(InferCell, self).__init__()
+
+ self.layers = nn.ModuleList()
+ self.node_IN = []
+ self.node_IX = []
+ self.genotype = deepcopy(genotype)
+ for i in range(1, len(genotype)):
+ node_info = genotype[i - 1]
+ cur_index = []
+ cur_innod = []
+ for (op_name, op_in) in node_info:
+ if op_in == 0:
+ layer = OPS[op_name](
+ C_in, C_out, stride, affine, track_running_stats
+ )
+ else:
+ layer = OPS[op_name](C_out, C_out, 1, affine, track_running_stats)
+ cur_index.append(len(self.layers))
+ cur_innod.append(op_in)
+ self.layers.append(layer)
+ self.node_IX.append(cur_index)
+ self.node_IN.append(cur_innod)
+ self.nodes = len(genotype)
+ self.in_dim = C_in
+ self.out_dim = C_out
+
+ def extra_repr(self):
+ string = "info :: nodes={nodes}, inC={in_dim}, outC={out_dim}".format(
+ **self.__dict__
+ )
+ laystr = []
+ for i, (node_layers, node_innods) in enumerate(zip(self.node_IX, self.node_IN)):
+ y = [
+ "I{:}-L{:}".format(_ii, _il)
+ for _il, _ii in zip(node_layers, node_innods)
+ ]
+ x = "{:}<-({:})".format(i + 1, ",".join(y))
+ laystr.append(x)
+ return (
+ string
+ + ", [{:}]".format(" | ".join(laystr))
+ + ", {:}".format(self.genotype.tostr())
+ )
+
+ def forward(self, inputs):
+ nodes = [inputs]
+ for i, (node_layers, node_innods) in enumerate(zip(self.node_IX, self.node_IN)):
+ node_feature = sum(
+ self.layers[_il](nodes[_ii])
+ for _il, _ii in zip(node_layers, node_innods)
+ )
+ nodes.append(node_feature)
+ return nodes[-1]
+
+
+# Learning Transferable Architectures for Scalable Image Recognition, CVPR 2018
+class NASNetInferCell(nn.Module):
+ def __init__(
+ self,
+ genotype,
+ C_prev_prev,
+ C_prev,
+ C,
+ reduction,
+ reduction_prev,
+ affine,
+ track_running_stats,
+ ):
+ super(NASNetInferCell, self).__init__()
+ self.reduction = reduction
+ if reduction_prev:
+ self.preprocess0 = OPS["skip_connect"](
+ C_prev_prev, C, 2, affine, track_running_stats
+ )
+ else:
+ self.preprocess0 = OPS["nor_conv_1x1"](
+ C_prev_prev, C, 1, affine, track_running_stats
+ )
+ self.preprocess1 = OPS["nor_conv_1x1"](
+ C_prev, C, 1, affine, track_running_stats
+ )
+
+ if not reduction:
+ nodes, concats = genotype["normal"], genotype["normal_concat"]
+ else:
+ nodes, concats = genotype["reduce"], genotype["reduce_concat"]
+ self._multiplier = len(concats)
+ self._concats = concats
+ self._steps = len(nodes)
+ self._nodes = nodes
+ self.edges = nn.ModuleDict()
+ for i, node in enumerate(nodes):
+ for in_node in node:
+ name, j = in_node[0], in_node[1]
+ stride = 2 if reduction and j < 2 else 1
+ node_str = "{:}<-{:}".format(i + 2, j)
+ self.edges[node_str] = OPS[name](
+ C, C, stride, affine, track_running_stats
+ )
+
+ # [TODO] to support drop_prob in this function..
+ def forward(self, s0, s1, unused_drop_prob):
+ s0 = self.preprocess0(s0)
+ s1 = self.preprocess1(s1)
+
+ states = [s0, s1]
+ for i, node in enumerate(self._nodes):
+ clist = []
+ for in_node in node:
+ name, j = in_node[0], in_node[1]
+ node_str = "{:}<-{:}".format(i + 2, j)
+ op = self.edges[node_str]
+ clist.append(op(states[j]))
+ states.append(sum(clist))
+ return torch.cat([states[x] for x in self._concats], dim=1)
+
+
+class AuxiliaryHeadCIFAR(nn.Module):
+ def __init__(self, C, num_classes):
+ """assuming input size 8x8"""
+ super(AuxiliaryHeadCIFAR, self).__init__()
+ self.features = nn.Sequential(
+ nn.ReLU(inplace=True),
+ nn.AvgPool2d(
+ 5, stride=3, padding=0, count_include_pad=False
+ ), # image size = 2 x 2
+ nn.Conv2d(C, 128, 1, bias=False),
+ nn.BatchNorm2d(128),
+ nn.ReLU(inplace=True),
+ nn.Conv2d(128, 768, 2, bias=False),
+ nn.BatchNorm2d(768),
+ nn.ReLU(inplace=True),
+ )
+ self.classifier = nn.Linear(768, num_classes)
+
+ def forward(self, x):
+ x = self.features(x)
+ x = self.classifier(x.view(x.size(0), -1))
+ return x
diff --git a/AutoDL-Projects/xautodl/models/cell_infers/nasnet_cifar.py b/AutoDL-Projects/xautodl/models/cell_infers/nasnet_cifar.py
new file mode 100644
index 0000000..2109477
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/cell_infers/nasnet_cifar.py
@@ -0,0 +1,118 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.01 #
+#####################################################
+import torch
+import torch.nn as nn
+from copy import deepcopy
+
+from .cells import NASNetInferCell as InferCell, AuxiliaryHeadCIFAR
+
+
+# The macro structure is based on NASNet
+class NASNetonCIFAR(nn.Module):
+ def __init__(
+ self,
+ C,
+ N,
+ stem_multiplier,
+ num_classes,
+ genotype,
+ auxiliary,
+ affine=True,
+ track_running_stats=True,
+ ):
+ super(NASNetonCIFAR, self).__init__()
+ self._C = C
+ self._layerN = N
+ self.stem = nn.Sequential(
+ nn.Conv2d(3, C * stem_multiplier, kernel_size=3, padding=1, bias=False),
+ nn.BatchNorm2d(C * stem_multiplier),
+ )
+
+ # config for each layer
+ layer_channels = (
+ [C] * N + [C * 2] + [C * 2] * (N - 1) + [C * 4] + [C * 4] * (N - 1)
+ )
+ layer_reductions = (
+ [False] * N + [True] + [False] * (N - 1) + [True] + [False] * (N - 1)
+ )
+
+ C_prev_prev, C_prev, C_curr, reduction_prev = (
+ C * stem_multiplier,
+ C * stem_multiplier,
+ C,
+ False,
+ )
+ self.auxiliary_index = None
+ self.auxiliary_head = None
+ self.cells = nn.ModuleList()
+ for index, (C_curr, reduction) in enumerate(
+ zip(layer_channels, layer_reductions)
+ ):
+ cell = InferCell(
+ genotype,
+ C_prev_prev,
+ C_prev,
+ C_curr,
+ reduction,
+ reduction_prev,
+ affine,
+ track_running_stats,
+ )
+ self.cells.append(cell)
+ C_prev_prev, C_prev, reduction_prev = (
+ C_prev,
+ cell._multiplier * C_curr,
+ reduction,
+ )
+ if reduction and C_curr == C * 4 and auxiliary:
+ self.auxiliary_head = AuxiliaryHeadCIFAR(C_prev, num_classes)
+ self.auxiliary_index = index
+ self._Layer = len(self.cells)
+ self.lastact = nn.Sequential(nn.BatchNorm2d(C_prev), nn.ReLU(inplace=True))
+ self.global_pooling = nn.AdaptiveAvgPool2d(1)
+ self.classifier = nn.Linear(C_prev, num_classes)
+ self.drop_path_prob = -1
+
+ def update_drop_path(self, drop_path_prob):
+ self.drop_path_prob = drop_path_prob
+
+ def auxiliary_param(self):
+ if self.auxiliary_head is None:
+ return []
+ else:
+ return list(self.auxiliary_head.parameters())
+
+ def get_message(self):
+ string = self.extra_repr()
+ for i, cell in enumerate(self.cells):
+ string += "\n {:02d}/{:02d} :: {:}".format(
+ i, len(self.cells), cell.extra_repr()
+ )
+ return string
+
+ def extra_repr(self):
+ return "{name}(C={_C}, N={_layerN}, L={_Layer})".format(
+ name=self.__class__.__name__, **self.__dict__
+ )
+
+ def forward(self, inputs):
+ stem_feature, logits_aux = self.stem(inputs), None
+ cell_results = [stem_feature, stem_feature]
+ for i, cell in enumerate(self.cells):
+ cell_feature = cell(cell_results[-2], cell_results[-1], self.drop_path_prob)
+ cell_results.append(cell_feature)
+ if (
+ self.auxiliary_index is not None
+ and i == self.auxiliary_index
+ and self.training
+ ):
+ logits_aux = self.auxiliary_head(cell_results[-1])
+ out = self.lastact(cell_results[-1])
+ out = self.global_pooling(out)
+ out = out.view(out.size(0), -1)
+ logits = self.classifier(out)
+ if logits_aux is None:
+ return out, logits
+ else:
+ return out, [logits, logits_aux]
diff --git a/AutoDL-Projects/xautodl/models/cell_infers/tiny_network.py b/AutoDL-Projects/xautodl/models/cell_infers/tiny_network.py
new file mode 100644
index 0000000..e8da1e4
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/cell_infers/tiny_network.py
@@ -0,0 +1,63 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.01 #
+#####################################################
+import torch.nn as nn
+from ..cell_operations import ResNetBasicblock
+from .cells import InferCell
+
+
+# The macro structure for architectures in NAS-Bench-201
+class TinyNetwork(nn.Module):
+ def __init__(self, C, N, genotype, num_classes):
+ super(TinyNetwork, self).__init__()
+ self._C = C
+ self._layerN = N
+
+ self.stem = nn.Sequential(
+ nn.Conv2d(3, C, kernel_size=3, padding=1, bias=False), nn.BatchNorm2d(C)
+ )
+
+ layer_channels = [C] * N + [C * 2] + [C * 2] * N + [C * 4] + [C * 4] * N
+ layer_reductions = [False] * N + [True] + [False] * N + [True] + [False] * N
+
+ C_prev = C
+ self.cells = nn.ModuleList()
+ for index, (C_curr, reduction) in enumerate(
+ zip(layer_channels, layer_reductions)
+ ):
+ if reduction:
+ cell = ResNetBasicblock(C_prev, C_curr, 2, True)
+ else:
+ cell = InferCell(genotype, C_prev, C_curr, 1)
+ self.cells.append(cell)
+ C_prev = cell.out_dim
+ self._Layer = len(self.cells)
+
+ self.lastact = nn.Sequential(nn.BatchNorm2d(C_prev), nn.ReLU(inplace=True))
+ self.global_pooling = nn.AdaptiveAvgPool2d(1)
+ self.classifier = nn.Linear(C_prev, num_classes)
+
+ def get_message(self):
+ string = self.extra_repr()
+ for i, cell in enumerate(self.cells):
+ string += "\n {:02d}/{:02d} :: {:}".format(
+ i, len(self.cells), cell.extra_repr()
+ )
+ return string
+
+ def extra_repr(self):
+ return "{name}(C={_C}, N={_layerN}, L={_Layer})".format(
+ name=self.__class__.__name__, **self.__dict__
+ )
+
+ def forward(self, inputs):
+ feature = self.stem(inputs)
+ for i, cell in enumerate(self.cells):
+ feature = cell(feature)
+
+ out = self.lastact(feature)
+ out = self.global_pooling(out)
+ out = out.view(out.size(0), -1)
+ logits = self.classifier(out)
+
+ return out, logits
diff --git a/AutoDL-Projects/xautodl/models/cell_operations.py b/AutoDL-Projects/xautodl/models/cell_operations.py
new file mode 100644
index 0000000..051539c
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/cell_operations.py
@@ -0,0 +1,553 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019 #
+##################################################
+import torch
+import torch.nn as nn
+
+__all__ = ["OPS", "RAW_OP_CLASSES", "ResNetBasicblock", "SearchSpaceNames"]
+
+OPS = {
+ "none": lambda C_in, C_out, stride, affine, track_running_stats: Zero(
+ C_in, C_out, stride
+ ),
+ "avg_pool_3x3": lambda C_in, C_out, stride, affine, track_running_stats: POOLING(
+ C_in, C_out, stride, "avg", affine, track_running_stats
+ ),
+ "max_pool_3x3": lambda C_in, C_out, stride, affine, track_running_stats: POOLING(
+ C_in, C_out, stride, "max", affine, track_running_stats
+ ),
+ "nor_conv_7x7": lambda C_in, C_out, stride, affine, track_running_stats: ReLUConvBN(
+ C_in,
+ C_out,
+ (7, 7),
+ (stride, stride),
+ (3, 3),
+ (1, 1),
+ affine,
+ track_running_stats,
+ ),
+ "nor_conv_3x3": lambda C_in, C_out, stride, affine, track_running_stats: ReLUConvBN(
+ C_in,
+ C_out,
+ (3, 3),
+ (stride, stride),
+ (1, 1),
+ (1, 1),
+ affine,
+ track_running_stats,
+ ),
+ "nor_conv_1x1": lambda C_in, C_out, stride, affine, track_running_stats: ReLUConvBN(
+ C_in,
+ C_out,
+ (1, 1),
+ (stride, stride),
+ (0, 0),
+ (1, 1),
+ affine,
+ track_running_stats,
+ ),
+ "dua_sepc_3x3": lambda C_in, C_out, stride, affine, track_running_stats: DualSepConv(
+ C_in,
+ C_out,
+ (3, 3),
+ (stride, stride),
+ (1, 1),
+ (1, 1),
+ affine,
+ track_running_stats,
+ ),
+ "dua_sepc_5x5": lambda C_in, C_out, stride, affine, track_running_stats: DualSepConv(
+ C_in,
+ C_out,
+ (5, 5),
+ (stride, stride),
+ (2, 2),
+ (1, 1),
+ affine,
+ track_running_stats,
+ ),
+ "dil_sepc_3x3": lambda C_in, C_out, stride, affine, track_running_stats: SepConv(
+ C_in,
+ C_out,
+ (3, 3),
+ (stride, stride),
+ (2, 2),
+ (2, 2),
+ affine,
+ track_running_stats,
+ ),
+ "dil_sepc_5x5": lambda C_in, C_out, stride, affine, track_running_stats: SepConv(
+ C_in,
+ C_out,
+ (5, 5),
+ (stride, stride),
+ (4, 4),
+ (2, 2),
+ affine,
+ track_running_stats,
+ ),
+ "skip_connect": lambda C_in, C_out, stride, affine, track_running_stats: Identity()
+ if stride == 1 and C_in == C_out
+ else FactorizedReduce(C_in, C_out, stride, affine, track_running_stats),
+}
+
+CONNECT_NAS_BENCHMARK = ["none", "skip_connect", "nor_conv_3x3"]
+NAS_BENCH_201 = ["none", "skip_connect", "nor_conv_1x1", "nor_conv_3x3", "avg_pool_3x3"]
+DARTS_SPACE = [
+ "none",
+ "skip_connect",
+ "dua_sepc_3x3",
+ "dua_sepc_5x5",
+ "dil_sepc_3x3",
+ "dil_sepc_5x5",
+ "avg_pool_3x3",
+ "max_pool_3x3",
+]
+
+SearchSpaceNames = {
+ "connect-nas": CONNECT_NAS_BENCHMARK,
+ "nats-bench": NAS_BENCH_201,
+ "nas-bench-201": NAS_BENCH_201,
+ "darts": DARTS_SPACE,
+}
+
+
+class ReLUConvBN(nn.Module):
+ def __init__(
+ self,
+ C_in,
+ C_out,
+ kernel_size,
+ stride,
+ padding,
+ dilation,
+ affine,
+ track_running_stats=True,
+ ):
+ super(ReLUConvBN, self).__init__()
+ self.op = nn.Sequential(
+ nn.ReLU(inplace=False),
+ nn.Conv2d(
+ C_in,
+ C_out,
+ kernel_size,
+ stride=stride,
+ padding=padding,
+ dilation=dilation,
+ bias=not affine,
+ ),
+ nn.BatchNorm2d(
+ C_out, affine=affine, track_running_stats=track_running_stats
+ ),
+ )
+
+ def forward(self, x):
+ return self.op(x)
+
+
+class SepConv(nn.Module):
+ def __init__(
+ self,
+ C_in,
+ C_out,
+ kernel_size,
+ stride,
+ padding,
+ dilation,
+ affine,
+ track_running_stats=True,
+ ):
+ super(SepConv, self).__init__()
+ self.op = nn.Sequential(
+ nn.ReLU(inplace=False),
+ nn.Conv2d(
+ C_in,
+ C_in,
+ kernel_size=kernel_size,
+ stride=stride,
+ padding=padding,
+ dilation=dilation,
+ groups=C_in,
+ bias=False,
+ ),
+ nn.Conv2d(C_in, C_out, kernel_size=1, padding=0, bias=not affine),
+ nn.BatchNorm2d(
+ C_out, affine=affine, track_running_stats=track_running_stats
+ ),
+ )
+
+ def forward(self, x):
+ return self.op(x)
+
+
+class DualSepConv(nn.Module):
+ def __init__(
+ self,
+ C_in,
+ C_out,
+ kernel_size,
+ stride,
+ padding,
+ dilation,
+ affine,
+ track_running_stats=True,
+ ):
+ super(DualSepConv, self).__init__()
+ self.op_a = SepConv(
+ C_in,
+ C_in,
+ kernel_size,
+ stride,
+ padding,
+ dilation,
+ affine,
+ track_running_stats,
+ )
+ self.op_b = SepConv(
+ C_in, C_out, kernel_size, 1, padding, dilation, affine, track_running_stats
+ )
+
+ def forward(self, x):
+ x = self.op_a(x)
+ x = self.op_b(x)
+ return x
+
+
+class ResNetBasicblock(nn.Module):
+ def __init__(self, inplanes, planes, stride, affine=True, track_running_stats=True):
+ super(ResNetBasicblock, self).__init__()
+ assert stride == 1 or stride == 2, "invalid stride {:}".format(stride)
+ self.conv_a = ReLUConvBN(
+ inplanes, planes, 3, stride, 1, 1, affine, track_running_stats
+ )
+ self.conv_b = ReLUConvBN(
+ planes, planes, 3, 1, 1, 1, affine, track_running_stats
+ )
+ if stride == 2:
+ self.downsample = nn.Sequential(
+ nn.AvgPool2d(kernel_size=2, stride=2, padding=0),
+ nn.Conv2d(
+ inplanes, planes, kernel_size=1, stride=1, padding=0, bias=False
+ ),
+ )
+ elif inplanes != planes:
+ self.downsample = ReLUConvBN(
+ inplanes, planes, 1, 1, 0, 1, affine, track_running_stats
+ )
+ else:
+ self.downsample = None
+ self.in_dim = inplanes
+ self.out_dim = planes
+ self.stride = stride
+ self.num_conv = 2
+
+ def extra_repr(self):
+ string = "{name}(inC={in_dim}, outC={out_dim}, stride={stride})".format(
+ name=self.__class__.__name__, **self.__dict__
+ )
+ return string
+
+ def forward(self, inputs):
+
+ basicblock = self.conv_a(inputs)
+ basicblock = self.conv_b(basicblock)
+
+ if self.downsample is not None:
+ residual = self.downsample(inputs)
+ else:
+ residual = inputs
+ return residual + basicblock
+
+
+class POOLING(nn.Module):
+ def __init__(
+ self, C_in, C_out, stride, mode, affine=True, track_running_stats=True
+ ):
+ super(POOLING, self).__init__()
+ if C_in == C_out:
+ self.preprocess = None
+ else:
+ self.preprocess = ReLUConvBN(
+ C_in, C_out, 1, 1, 0, 1, affine, track_running_stats
+ )
+ if mode == "avg":
+ self.op = nn.AvgPool2d(3, stride=stride, padding=1, count_include_pad=False)
+ elif mode == "max":
+ self.op = nn.MaxPool2d(3, stride=stride, padding=1)
+ else:
+ raise ValueError("Invalid mode={:} in POOLING".format(mode))
+
+ def forward(self, inputs):
+ if self.preprocess:
+ x = self.preprocess(inputs)
+ else:
+ x = inputs
+ return self.op(x)
+
+
+class Identity(nn.Module):
+ def __init__(self):
+ super(Identity, self).__init__()
+
+ def forward(self, x):
+ return x
+
+
+class Zero(nn.Module):
+ def __init__(self, C_in, C_out, stride):
+ super(Zero, self).__init__()
+ self.C_in = C_in
+ self.C_out = C_out
+ self.stride = stride
+ self.is_zero = True
+
+ def forward(self, x):
+ if self.C_in == self.C_out:
+ if self.stride == 1:
+ return x.mul(0.0)
+ else:
+ return x[:, :, :: self.stride, :: self.stride].mul(0.0)
+ else:
+ shape = list(x.shape)
+ shape[1] = self.C_out
+ zeros = x.new_zeros(shape, dtype=x.dtype, device=x.device)
+ return zeros
+
+ def extra_repr(self):
+ return "C_in={C_in}, C_out={C_out}, stride={stride}".format(**self.__dict__)
+
+
+class FactorizedReduce(nn.Module):
+ def __init__(self, C_in, C_out, stride, affine, track_running_stats):
+ super(FactorizedReduce, self).__init__()
+ self.stride = stride
+ self.C_in = C_in
+ self.C_out = C_out
+ self.relu = nn.ReLU(inplace=False)
+ if stride == 2:
+ # assert C_out % 2 == 0, 'C_out : {:}'.format(C_out)
+ C_outs = [C_out // 2, C_out - C_out // 2]
+ self.convs = nn.ModuleList()
+ for i in range(2):
+ self.convs.append(
+ nn.Conv2d(
+ C_in, C_outs[i], 1, stride=stride, padding=0, bias=not affine
+ )
+ )
+ self.pad = nn.ConstantPad2d((0, 1, 0, 1), 0)
+ elif stride == 1:
+ self.conv = nn.Conv2d(
+ C_in, C_out, 1, stride=stride, padding=0, bias=not affine
+ )
+ else:
+ raise ValueError("Invalid stride : {:}".format(stride))
+ self.bn = nn.BatchNorm2d(
+ C_out, affine=affine, track_running_stats=track_running_stats
+ )
+
+ def forward(self, x):
+ if self.stride == 2:
+ x = self.relu(x)
+ y = self.pad(x)
+ out = torch.cat([self.convs[0](x), self.convs[1](y[:, :, 1:, 1:])], dim=1)
+ else:
+ out = self.conv(x)
+ out = self.bn(out)
+ return out
+
+ def extra_repr(self):
+ return "C_in={C_in}, C_out={C_out}, stride={stride}".format(**self.__dict__)
+
+
+# Auto-ReID: Searching for a Part-Aware ConvNet for Person Re-Identification, ICCV 2019
+class PartAwareOp(nn.Module):
+ def __init__(self, C_in, C_out, stride, part=4):
+ super().__init__()
+ self.part = 4
+ self.hidden = C_in // 3
+ self.avg_pool = nn.AdaptiveAvgPool2d(1)
+ self.local_conv_list = nn.ModuleList()
+ for i in range(self.part):
+ self.local_conv_list.append(
+ nn.Sequential(
+ nn.ReLU(),
+ nn.Conv2d(C_in, self.hidden, 1),
+ nn.BatchNorm2d(self.hidden, affine=True),
+ )
+ )
+ self.W_K = nn.Linear(self.hidden, self.hidden)
+ self.W_Q = nn.Linear(self.hidden, self.hidden)
+
+ if stride == 2:
+ self.last = FactorizedReduce(C_in + self.hidden, C_out, 2)
+ elif stride == 1:
+ self.last = FactorizedReduce(C_in + self.hidden, C_out, 1)
+ else:
+ raise ValueError("Invalid Stride : {:}".format(stride))
+
+ def forward(self, x):
+ batch, C, H, W = x.size()
+ assert H >= self.part, "input size too small : {:} vs {:}".format(
+ x.shape, self.part
+ )
+ IHs = [0]
+ for i in range(self.part):
+ IHs.append(min(H, int((i + 1) * (float(H) / self.part))))
+ local_feat_list = []
+ for i in range(self.part):
+ feature = x[:, :, IHs[i] : IHs[i + 1], :]
+ xfeax = self.avg_pool(feature)
+ xfea = self.local_conv_list[i](xfeax)
+ local_feat_list.append(xfea)
+ part_feature = torch.cat(local_feat_list, dim=2).view(batch, -1, self.part)
+ part_feature = part_feature.transpose(1, 2).contiguous()
+ part_K = self.W_K(part_feature)
+ part_Q = self.W_Q(part_feature).transpose(1, 2).contiguous()
+ weight_att = torch.bmm(part_K, part_Q)
+ attention = torch.softmax(weight_att, dim=2)
+ aggreateF = torch.bmm(attention, part_feature).transpose(1, 2).contiguous()
+ features = []
+ for i in range(self.part):
+ feature = aggreateF[:, :, i : i + 1].expand(
+ batch, self.hidden, IHs[i + 1] - IHs[i]
+ )
+ feature = feature.view(batch, self.hidden, IHs[i + 1] - IHs[i], 1)
+ features.append(feature)
+ features = torch.cat(features, dim=2).expand(batch, self.hidden, H, W)
+ final_fea = torch.cat((x, features), dim=1)
+ outputs = self.last(final_fea)
+ return outputs
+
+
+def drop_path(x, drop_prob):
+ if drop_prob > 0.0:
+ keep_prob = 1.0 - drop_prob
+ mask = x.new_zeros(x.size(0), 1, 1, 1)
+ mask = mask.bernoulli_(keep_prob)
+ x = torch.div(x, keep_prob)
+ x.mul_(mask)
+ return x
+
+
+# Searching for A Robust Neural Architecture in Four GPU Hours
+class GDAS_Reduction_Cell(nn.Module):
+ def __init__(
+ self, C_prev_prev, C_prev, C, reduction_prev, affine, track_running_stats
+ ):
+ super(GDAS_Reduction_Cell, self).__init__()
+ if reduction_prev:
+ self.preprocess0 = FactorizedReduce(
+ C_prev_prev, C, 2, affine, track_running_stats
+ )
+ else:
+ self.preprocess0 = ReLUConvBN(
+ C_prev_prev, C, 1, 1, 0, 1, affine, track_running_stats
+ )
+ self.preprocess1 = ReLUConvBN(
+ C_prev, C, 1, 1, 0, 1, affine, track_running_stats
+ )
+
+ self.reduction = True
+ self.ops1 = nn.ModuleList(
+ [
+ nn.Sequential(
+ nn.ReLU(inplace=False),
+ nn.Conv2d(
+ C,
+ C,
+ (1, 3),
+ stride=(1, 2),
+ padding=(0, 1),
+ groups=8,
+ bias=not affine,
+ ),
+ nn.Conv2d(
+ C,
+ C,
+ (3, 1),
+ stride=(2, 1),
+ padding=(1, 0),
+ groups=8,
+ bias=not affine,
+ ),
+ nn.BatchNorm2d(
+ C, affine=affine, track_running_stats=track_running_stats
+ ),
+ nn.ReLU(inplace=False),
+ nn.Conv2d(C, C, 1, stride=1, padding=0, bias=not affine),
+ nn.BatchNorm2d(
+ C, affine=affine, track_running_stats=track_running_stats
+ ),
+ ),
+ nn.Sequential(
+ nn.ReLU(inplace=False),
+ nn.Conv2d(
+ C,
+ C,
+ (1, 3),
+ stride=(1, 2),
+ padding=(0, 1),
+ groups=8,
+ bias=not affine,
+ ),
+ nn.Conv2d(
+ C,
+ C,
+ (3, 1),
+ stride=(2, 1),
+ padding=(1, 0),
+ groups=8,
+ bias=not affine,
+ ),
+ nn.BatchNorm2d(
+ C, affine=affine, track_running_stats=track_running_stats
+ ),
+ nn.ReLU(inplace=False),
+ nn.Conv2d(C, C, 1, stride=1, padding=0, bias=not affine),
+ nn.BatchNorm2d(
+ C, affine=affine, track_running_stats=track_running_stats
+ ),
+ ),
+ ]
+ )
+
+ self.ops2 = nn.ModuleList(
+ [
+ nn.Sequential(
+ nn.MaxPool2d(3, stride=2, padding=1),
+ nn.BatchNorm2d(
+ C, affine=affine, track_running_stats=track_running_stats
+ ),
+ ),
+ nn.Sequential(
+ nn.MaxPool2d(3, stride=2, padding=1),
+ nn.BatchNorm2d(
+ C, affine=affine, track_running_stats=track_running_stats
+ ),
+ ),
+ ]
+ )
+
+ @property
+ def multiplier(self):
+ return 4
+
+ def forward(self, s0, s1, drop_prob=-1):
+ s0 = self.preprocess0(s0)
+ s1 = self.preprocess1(s1)
+
+ X0 = self.ops1[0](s0)
+ X1 = self.ops1[1](s1)
+ if self.training and drop_prob > 0.0:
+ X0, X1 = drop_path(X0, drop_prob), drop_path(X1, drop_prob)
+
+ # X2 = self.ops2[0] (X0+X1)
+ X2 = self.ops2[0](s0)
+ X3 = self.ops2[1](s1)
+ if self.training and drop_prob > 0.0:
+ X2, X3 = drop_path(X2, drop_prob), drop_path(X3, drop_prob)
+ return torch.cat([X0, X1, X2, X3], dim=1)
+
+
+# To manage the useful classes in this file.
+RAW_OP_CLASSES = {"gdas_reduction": GDAS_Reduction_Cell}
diff --git a/AutoDL-Projects/xautodl/models/cell_searchs/__init__.py b/AutoDL-Projects/xautodl/models/cell_searchs/__init__.py
new file mode 100644
index 0000000..0d770cb
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/cell_searchs/__init__.py
@@ -0,0 +1,33 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019 #
+##################################################
+# The macro structure is defined in NAS-Bench-201
+from .search_model_darts import TinyNetworkDarts
+from .search_model_gdas import TinyNetworkGDAS
+from .search_model_setn import TinyNetworkSETN
+from .search_model_enas import TinyNetworkENAS
+from .search_model_random import TinyNetworkRANDOM
+from .generic_model import GenericNAS201Model
+from .genotypes import Structure as CellStructure, architectures as CellArchitectures
+
+# NASNet-based macro structure
+from .search_model_gdas_nasnet import NASNetworkGDAS
+from .search_model_gdas_frc_nasnet import NASNetworkGDAS_FRC
+from .search_model_darts_nasnet import NASNetworkDARTS
+
+
+nas201_super_nets = {
+ "DARTS-V1": TinyNetworkDarts,
+ "DARTS-V2": TinyNetworkDarts,
+ "GDAS": TinyNetworkGDAS,
+ "SETN": TinyNetworkSETN,
+ "ENAS": TinyNetworkENAS,
+ "RANDOM": TinyNetworkRANDOM,
+ "generic": GenericNAS201Model,
+}
+
+nasnet_super_nets = {
+ "GDAS": NASNetworkGDAS,
+ "GDAS_FRC": NASNetworkGDAS_FRC,
+ "DARTS": NASNetworkDARTS,
+}
diff --git a/AutoDL-Projects/xautodl/models/cell_searchs/_test_module.py b/AutoDL-Projects/xautodl/models/cell_searchs/_test_module.py
new file mode 100644
index 0000000..cd6fbfb
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/cell_searchs/_test_module.py
@@ -0,0 +1,14 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019 #
+##################################################
+import torch
+from search_model_enas_utils import Controller
+
+
+def main():
+ controller = Controller(6, 4)
+ predictions = controller()
+
+
+if __name__ == "__main__":
+ main()
diff --git a/AutoDL-Projects/xautodl/models/cell_searchs/generic_model.py b/AutoDL-Projects/xautodl/models/cell_searchs/generic_model.py
new file mode 100644
index 0000000..bbbbb1f
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/cell_searchs/generic_model.py
@@ -0,0 +1,366 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020.07 #
+#####################################################
+import torch, random
+import torch.nn as nn
+from copy import deepcopy
+from typing import Text
+from torch.distributions.categorical import Categorical
+
+from ..cell_operations import ResNetBasicblock, drop_path
+from .search_cells import NAS201SearchCell as SearchCell
+from .genotypes import Structure
+
+
+class Controller(nn.Module):
+ # we refer to https://github.com/TDeVries/enas_pytorch/blob/master/models/controller.py
+ def __init__(
+ self,
+ edge2index,
+ op_names,
+ max_nodes,
+ lstm_size=32,
+ lstm_num_layers=2,
+ tanh_constant=2.5,
+ temperature=5.0,
+ ):
+ super(Controller, self).__init__()
+ # assign the attributes
+ self.max_nodes = max_nodes
+ self.num_edge = len(edge2index)
+ self.edge2index = edge2index
+ self.num_ops = len(op_names)
+ self.op_names = op_names
+ self.lstm_size = lstm_size
+ self.lstm_N = lstm_num_layers
+ self.tanh_constant = tanh_constant
+ self.temperature = temperature
+ # create parameters
+ self.register_parameter(
+ "input_vars", nn.Parameter(torch.Tensor(1, 1, lstm_size))
+ )
+ self.w_lstm = nn.LSTM(
+ input_size=self.lstm_size,
+ hidden_size=self.lstm_size,
+ num_layers=self.lstm_N,
+ )
+ self.w_embd = nn.Embedding(self.num_ops, self.lstm_size)
+ self.w_pred = nn.Linear(self.lstm_size, self.num_ops)
+
+ nn.init.uniform_(self.input_vars, -0.1, 0.1)
+ nn.init.uniform_(self.w_lstm.weight_hh_l0, -0.1, 0.1)
+ nn.init.uniform_(self.w_lstm.weight_ih_l0, -0.1, 0.1)
+ nn.init.uniform_(self.w_embd.weight, -0.1, 0.1)
+ nn.init.uniform_(self.w_pred.weight, -0.1, 0.1)
+
+ def convert_structure(self, _arch):
+ genotypes = []
+ for i in range(1, self.max_nodes):
+ xlist = []
+ for j in range(i):
+ node_str = "{:}<-{:}".format(i, j)
+ op_index = _arch[self.edge2index[node_str]]
+ op_name = self.op_names[op_index]
+ xlist.append((op_name, j))
+ genotypes.append(tuple(xlist))
+ return Structure(genotypes)
+
+ def forward(self):
+
+ inputs, h0 = self.input_vars, None
+ log_probs, entropys, sampled_arch = [], [], []
+ for iedge in range(self.num_edge):
+ outputs, h0 = self.w_lstm(inputs, h0)
+
+ logits = self.w_pred(outputs)
+ logits = logits / self.temperature
+ logits = self.tanh_constant * torch.tanh(logits)
+ # distribution
+ op_distribution = Categorical(logits=logits)
+ op_index = op_distribution.sample()
+ sampled_arch.append(op_index.item())
+
+ op_log_prob = op_distribution.log_prob(op_index)
+ log_probs.append(op_log_prob.view(-1))
+ op_entropy = op_distribution.entropy()
+ entropys.append(op_entropy.view(-1))
+
+ # obtain the input embedding for the next step
+ inputs = self.w_embd(op_index)
+ return (
+ torch.sum(torch.cat(log_probs)),
+ torch.sum(torch.cat(entropys)),
+ self.convert_structure(sampled_arch),
+ )
+
+
+class GenericNAS201Model(nn.Module):
+ def __init__(
+ self, C, N, max_nodes, num_classes, search_space, affine, track_running_stats
+ ):
+ super(GenericNAS201Model, self).__init__()
+ self._C = C
+ self._layerN = N
+ self._max_nodes = max_nodes
+ self._stem = nn.Sequential(
+ nn.Conv2d(3, C, kernel_size=3, padding=1, bias=False), nn.BatchNorm2d(C)
+ )
+ layer_channels = [C] * N + [C * 2] + [C * 2] * N + [C * 4] + [C * 4] * N
+ layer_reductions = [False] * N + [True] + [False] * N + [True] + [False] * N
+ C_prev, num_edge, edge2index = C, None, None
+ self._cells = nn.ModuleList()
+ for index, (C_curr, reduction) in enumerate(
+ zip(layer_channels, layer_reductions)
+ ):
+ if reduction:
+ cell = ResNetBasicblock(C_prev, C_curr, 2)
+ else:
+ cell = SearchCell(
+ C_prev,
+ C_curr,
+ 1,
+ max_nodes,
+ search_space,
+ affine,
+ track_running_stats,
+ )
+ if num_edge is None:
+ num_edge, edge2index = cell.num_edges, cell.edge2index
+ else:
+ assert (
+ num_edge == cell.num_edges and edge2index == cell.edge2index
+ ), "invalid {:} vs. {:}.".format(num_edge, cell.num_edges)
+ self._cells.append(cell)
+ C_prev = cell.out_dim
+ self._op_names = deepcopy(search_space)
+ self._Layer = len(self._cells)
+ self.edge2index = edge2index
+ self.lastact = nn.Sequential(
+ nn.BatchNorm2d(
+ C_prev, affine=affine, track_running_stats=track_running_stats
+ ),
+ nn.ReLU(inplace=True),
+ )
+ self.global_pooling = nn.AdaptiveAvgPool2d(1)
+ self.classifier = nn.Linear(C_prev, num_classes)
+ self._num_edge = num_edge
+ # algorithm related
+ self.arch_parameters = nn.Parameter(
+ 1e-3 * torch.randn(num_edge, len(search_space))
+ )
+ self._mode = None
+ self.dynamic_cell = None
+ self._tau = None
+ self._algo = None
+ self._drop_path = None
+ self.verbose = False
+
+ def set_algo(self, algo: Text):
+ # used for searching
+ assert self._algo is None, "This functioin can only be called once."
+ self._algo = algo
+ if algo == "enas":
+ self.controller = Controller(
+ self.edge2index, self._op_names, self._max_nodes
+ )
+ else:
+ self.arch_parameters = nn.Parameter(
+ 1e-3 * torch.randn(self._num_edge, len(self._op_names))
+ )
+ if algo == "gdas":
+ self._tau = 10
+
+ def set_cal_mode(self, mode, dynamic_cell=None):
+ assert mode in ["gdas", "enas", "urs", "joint", "select", "dynamic"]
+ self._mode = mode
+ if mode == "dynamic":
+ self.dynamic_cell = deepcopy(dynamic_cell)
+ else:
+ self.dynamic_cell = None
+
+ def set_drop_path(self, progress, drop_path_rate):
+ if drop_path_rate is None:
+ self._drop_path = None
+ elif progress is None:
+ self._drop_path = drop_path_rate
+ else:
+ self._drop_path = progress * drop_path_rate
+
+ @property
+ def mode(self):
+ return self._mode
+
+ @property
+ def drop_path(self):
+ return self._drop_path
+
+ @property
+ def weights(self):
+ xlist = list(self._stem.parameters())
+ xlist += list(self._cells.parameters())
+ xlist += list(self.lastact.parameters())
+ xlist += list(self.global_pooling.parameters())
+ xlist += list(self.classifier.parameters())
+ return xlist
+
+ def set_tau(self, tau):
+ self._tau = tau
+
+ @property
+ def tau(self):
+ return self._tau
+
+ @property
+ def alphas(self):
+ if self._algo == "enas":
+ return list(self.controller.parameters())
+ else:
+ return [self.arch_parameters]
+
+ @property
+ def message(self):
+ string = self.extra_repr()
+ for i, cell in enumerate(self._cells):
+ string += "\n {:02d}/{:02d} :: {:}".format(
+ i, len(self._cells), cell.extra_repr()
+ )
+ return string
+
+ def show_alphas(self):
+ with torch.no_grad():
+ if self._algo == "enas":
+ return "w_pred :\n{:}".format(self.controller.w_pred.weight)
+ else:
+ return "arch-parameters :\n{:}".format(
+ nn.functional.softmax(self.arch_parameters, dim=-1).cpu()
+ )
+
+ def extra_repr(self):
+ return "{name}(C={_C}, Max-Nodes={_max_nodes}, N={_layerN}, L={_Layer}, alg={_algo})".format(
+ name=self.__class__.__name__, **self.__dict__
+ )
+
+ @property
+ def genotype(self):
+ genotypes = []
+ for i in range(1, self._max_nodes):
+ xlist = []
+ for j in range(i):
+ node_str = "{:}<-{:}".format(i, j)
+ with torch.no_grad():
+ weights = self.arch_parameters[self.edge2index[node_str]]
+ op_name = self._op_names[weights.argmax().item()]
+ xlist.append((op_name, j))
+ genotypes.append(tuple(xlist))
+ return Structure(genotypes)
+
+ def dync_genotype(self, use_random=False):
+ genotypes = []
+ with torch.no_grad():
+ alphas_cpu = nn.functional.softmax(self.arch_parameters, dim=-1)
+ for i in range(1, self._max_nodes):
+ xlist = []
+ for j in range(i):
+ node_str = "{:}<-{:}".format(i, j)
+ if use_random:
+ op_name = random.choice(self._op_names)
+ else:
+ weights = alphas_cpu[self.edge2index[node_str]]
+ op_index = torch.multinomial(weights, 1).item()
+ op_name = self._op_names[op_index]
+ xlist.append((op_name, j))
+ genotypes.append(tuple(xlist))
+ return Structure(genotypes)
+
+ def get_log_prob(self, arch):
+ with torch.no_grad():
+ logits = nn.functional.log_softmax(self.arch_parameters, dim=-1)
+ select_logits = []
+ for i, node_info in enumerate(arch.nodes):
+ for op, xin in node_info:
+ node_str = "{:}<-{:}".format(i + 1, xin)
+ op_index = self._op_names.index(op)
+ select_logits.append(logits[self.edge2index[node_str], op_index])
+ return sum(select_logits).item()
+
+ def return_topK(self, K, use_random=False):
+ archs = Structure.gen_all(self._op_names, self._max_nodes, False)
+ pairs = [(self.get_log_prob(arch), arch) for arch in archs]
+ if K < 0 or K >= len(archs):
+ K = len(archs)
+ if use_random:
+ return random.sample(archs, K)
+ else:
+ sorted_pairs = sorted(pairs, key=lambda x: -x[0])
+ return_pairs = [sorted_pairs[_][1] for _ in range(K)]
+ return return_pairs
+
+ def normalize_archp(self):
+ if self.mode == "gdas":
+ while True:
+ gumbels = -torch.empty_like(self.arch_parameters).exponential_().log()
+ logits = (self.arch_parameters.log_softmax(dim=1) + gumbels) / self.tau
+ probs = nn.functional.softmax(logits, dim=1)
+ index = probs.max(-1, keepdim=True)[1]
+ one_h = torch.zeros_like(logits).scatter_(-1, index, 1.0)
+ hardwts = one_h - probs.detach() + probs
+ if (
+ (torch.isinf(gumbels).any())
+ or (torch.isinf(probs).any())
+ or (torch.isnan(probs).any())
+ ):
+ continue
+ else:
+ break
+ with torch.no_grad():
+ hardwts_cpu = hardwts.detach().cpu()
+ return hardwts, hardwts_cpu, index, "GUMBEL"
+ else:
+ alphas = nn.functional.softmax(self.arch_parameters, dim=-1)
+ index = alphas.max(-1, keepdim=True)[1]
+ with torch.no_grad():
+ alphas_cpu = alphas.detach().cpu()
+ return alphas, alphas_cpu, index, "SOFTMAX"
+
+ def forward(self, inputs):
+ alphas, alphas_cpu, index, verbose_str = self.normalize_archp()
+ feature = self._stem(inputs)
+ for i, cell in enumerate(self._cells):
+ if isinstance(cell, SearchCell):
+ if self.mode == "urs":
+ feature = cell.forward_urs(feature)
+ if self.verbose:
+ verbose_str += "-forward_urs"
+ elif self.mode == "select":
+ feature = cell.forward_select(feature, alphas_cpu)
+ if self.verbose:
+ verbose_str += "-forward_select"
+ elif self.mode == "joint":
+ feature = cell.forward_joint(feature, alphas)
+ if self.verbose:
+ verbose_str += "-forward_joint"
+ elif self.mode == "dynamic":
+ feature = cell.forward_dynamic(feature, self.dynamic_cell)
+ if self.verbose:
+ verbose_str += "-forward_dynamic"
+ elif self.mode == "gdas":
+ feature = cell.forward_gdas(feature, alphas, index)
+ if self.verbose:
+ verbose_str += "-forward_gdas"
+ elif self.mode == "gdas_v1":
+ feature = cell.forward_gdas_v1(feature, alphas, index)
+ if self.verbose:
+ verbose_str += "-forward_gdas_v1"
+ else:
+ raise ValueError("invalid mode={:}".format(self.mode))
+ else:
+ feature = cell(feature)
+ if self.drop_path is not None:
+ feature = drop_path(feature, self.drop_path)
+ if self.verbose and random.random() < 0.001:
+ print(verbose_str)
+ out = self.lastact(feature)
+ out = self.global_pooling(out)
+ out = out.view(out.size(0), -1)
+ logits = self.classifier(out)
+ return out, logits
diff --git a/AutoDL-Projects/xautodl/models/cell_searchs/genotypes.py b/AutoDL-Projects/xautodl/models/cell_searchs/genotypes.py
new file mode 100644
index 0000000..f0ec8f2
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/cell_searchs/genotypes.py
@@ -0,0 +1,274 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019 #
+##################################################
+from copy import deepcopy
+
+
+def get_combination(space, num):
+ combs = []
+ for i in range(num):
+ if i == 0:
+ for func in space:
+ combs.append([(func, i)])
+ else:
+ new_combs = []
+ for string in combs:
+ for func in space:
+ xstring = string + [(func, i)]
+ new_combs.append(xstring)
+ combs = new_combs
+ return combs
+
+
+class Structure:
+ def __init__(self, genotype):
+ assert isinstance(genotype, list) or isinstance(
+ genotype, tuple
+ ), "invalid class of genotype : {:}".format(type(genotype))
+ self.node_num = len(genotype) + 1
+ self.nodes = []
+ self.node_N = []
+ for idx, node_info in enumerate(genotype):
+ assert isinstance(node_info, list) or isinstance(
+ node_info, tuple
+ ), "invalid class of node_info : {:}".format(type(node_info))
+ assert len(node_info) >= 1, "invalid length : {:}".format(len(node_info))
+ for node_in in node_info:
+ assert isinstance(node_in, list) or isinstance(
+ node_in, tuple
+ ), "invalid class of in-node : {:}".format(type(node_in))
+ assert (
+ len(node_in) == 2 and node_in[1] <= idx
+ ), "invalid in-node : {:}".format(node_in)
+ self.node_N.append(len(node_info))
+ self.nodes.append(tuple(deepcopy(node_info)))
+
+ def tolist(self, remove_str):
+ # convert this class to the list, if remove_str is 'none', then remove the 'none' operation.
+ # note that we re-order the input node in this function
+ # return the-genotype-list and success [if unsuccess, it is not a connectivity]
+ genotypes = []
+ for node_info in self.nodes:
+ node_info = list(node_info)
+ node_info = sorted(node_info, key=lambda x: (x[1], x[0]))
+ node_info = tuple(filter(lambda x: x[0] != remove_str, node_info))
+ if len(node_info) == 0:
+ return None, False
+ genotypes.append(node_info)
+ return genotypes, True
+
+ def node(self, index):
+ assert index > 0 and index <= len(self), "invalid index={:} < {:}".format(
+ index, len(self)
+ )
+ return self.nodes[index]
+
+ def tostr(self):
+ strings = []
+ for node_info in self.nodes:
+ string = "|".join([x[0] + "~{:}".format(x[1]) for x in node_info])
+ string = "|{:}|".format(string)
+ strings.append(string)
+ return "+".join(strings)
+
+ def check_valid(self):
+ nodes = {0: True}
+ for i, node_info in enumerate(self.nodes):
+ sums = []
+ for op, xin in node_info:
+ if op == "none" or nodes[xin] is False:
+ x = False
+ else:
+ x = True
+ sums.append(x)
+ nodes[i + 1] = sum(sums) > 0
+ return nodes[len(self.nodes)]
+
+ def to_unique_str(self, consider_zero=False):
+ # this is used to identify the isomorphic cell, which rerquires the prior knowledge of operation
+ # two operations are special, i.e., none and skip_connect
+ nodes = {0: "0"}
+ for i_node, node_info in enumerate(self.nodes):
+ cur_node = []
+ for op, xin in node_info:
+ if consider_zero is None:
+ x = "(" + nodes[xin] + ")" + "@{:}".format(op)
+ elif consider_zero:
+ if op == "none" or nodes[xin] == "#":
+ x = "#" # zero
+ elif op == "skip_connect":
+ x = nodes[xin]
+ else:
+ x = "(" + nodes[xin] + ")" + "@{:}".format(op)
+ else:
+ if op == "skip_connect":
+ x = nodes[xin]
+ else:
+ x = "(" + nodes[xin] + ")" + "@{:}".format(op)
+ cur_node.append(x)
+ nodes[i_node + 1] = "+".join(sorted(cur_node))
+ return nodes[len(self.nodes)]
+
+ def check_valid_op(self, op_names):
+ for node_info in self.nodes:
+ for inode_edge in node_info:
+ # assert inode_edge[0] in op_names, 'invalid op-name : {:}'.format(inode_edge[0])
+ if inode_edge[0] not in op_names:
+ return False
+ return True
+
+ def __repr__(self):
+ return "{name}({node_num} nodes with {node_info})".format(
+ name=self.__class__.__name__, node_info=self.tostr(), **self.__dict__
+ )
+
+ def __len__(self):
+ return len(self.nodes) + 1
+
+ def __getitem__(self, index):
+ return self.nodes[index]
+
+ @staticmethod
+ def str2structure(xstr):
+ if isinstance(xstr, Structure):
+ return xstr
+ assert isinstance(xstr, str), "must take string (not {:}) as input".format(
+ type(xstr)
+ )
+ nodestrs = xstr.split("+")
+ genotypes = []
+ for i, node_str in enumerate(nodestrs):
+ inputs = list(filter(lambda x: x != "", node_str.split("|")))
+ for xinput in inputs:
+ assert len(xinput.split("~")) == 2, "invalid input length : {:}".format(
+ xinput
+ )
+ inputs = (xi.split("~") for xi in inputs)
+ input_infos = tuple((op, int(IDX)) for (op, IDX) in inputs)
+ genotypes.append(input_infos)
+ return Structure(genotypes)
+
+ @staticmethod
+ def str2fullstructure(xstr, default_name="none"):
+ assert isinstance(xstr, str), "must take string (not {:}) as input".format(
+ type(xstr)
+ )
+ nodestrs = xstr.split("+")
+ genotypes = []
+ for i, node_str in enumerate(nodestrs):
+ inputs = list(filter(lambda x: x != "", node_str.split("|")))
+ for xinput in inputs:
+ assert len(xinput.split("~")) == 2, "invalid input length : {:}".format(
+ xinput
+ )
+ inputs = (xi.split("~") for xi in inputs)
+ input_infos = list((op, int(IDX)) for (op, IDX) in inputs)
+ all_in_nodes = list(x[1] for x in input_infos)
+ for j in range(i):
+ if j not in all_in_nodes:
+ input_infos.append((default_name, j))
+ node_info = sorted(input_infos, key=lambda x: (x[1], x[0]))
+ genotypes.append(tuple(node_info))
+ return Structure(genotypes)
+
+ @staticmethod
+ def gen_all(search_space, num, return_ori):
+ assert isinstance(search_space, list) or isinstance(
+ search_space, tuple
+ ), "invalid class of search-space : {:}".format(type(search_space))
+ assert (
+ num >= 2
+ ), "There should be at least two nodes in a neural cell instead of {:}".format(
+ num
+ )
+ all_archs = get_combination(search_space, 1)
+ for i, arch in enumerate(all_archs):
+ all_archs[i] = [tuple(arch)]
+
+ for inode in range(2, num):
+ cur_nodes = get_combination(search_space, inode)
+ new_all_archs = []
+ for previous_arch in all_archs:
+ for cur_node in cur_nodes:
+ new_all_archs.append(previous_arch + [tuple(cur_node)])
+ all_archs = new_all_archs
+ if return_ori:
+ return all_archs
+ else:
+ return [Structure(x) for x in all_archs]
+
+
+ResNet_CODE = Structure(
+ [
+ (("nor_conv_3x3", 0),), # node-1
+ (("nor_conv_3x3", 1),), # node-2
+ (("skip_connect", 0), ("skip_connect", 2)),
+ ] # node-3
+)
+
+AllConv3x3_CODE = Structure(
+ [
+ (("nor_conv_3x3", 0),), # node-1
+ (("nor_conv_3x3", 0), ("nor_conv_3x3", 1)), # node-2
+ (("nor_conv_3x3", 0), ("nor_conv_3x3", 1), ("nor_conv_3x3", 2)),
+ ] # node-3
+)
+
+AllFull_CODE = Structure(
+ [
+ (
+ ("skip_connect", 0),
+ ("nor_conv_1x1", 0),
+ ("nor_conv_3x3", 0),
+ ("avg_pool_3x3", 0),
+ ), # node-1
+ (
+ ("skip_connect", 0),
+ ("nor_conv_1x1", 0),
+ ("nor_conv_3x3", 0),
+ ("avg_pool_3x3", 0),
+ ("skip_connect", 1),
+ ("nor_conv_1x1", 1),
+ ("nor_conv_3x3", 1),
+ ("avg_pool_3x3", 1),
+ ), # node-2
+ (
+ ("skip_connect", 0),
+ ("nor_conv_1x1", 0),
+ ("nor_conv_3x3", 0),
+ ("avg_pool_3x3", 0),
+ ("skip_connect", 1),
+ ("nor_conv_1x1", 1),
+ ("nor_conv_3x3", 1),
+ ("avg_pool_3x3", 1),
+ ("skip_connect", 2),
+ ("nor_conv_1x1", 2),
+ ("nor_conv_3x3", 2),
+ ("avg_pool_3x3", 2),
+ ),
+ ] # node-3
+)
+
+AllConv1x1_CODE = Structure(
+ [
+ (("nor_conv_1x1", 0),), # node-1
+ (("nor_conv_1x1", 0), ("nor_conv_1x1", 1)), # node-2
+ (("nor_conv_1x1", 0), ("nor_conv_1x1", 1), ("nor_conv_1x1", 2)),
+ ] # node-3
+)
+
+AllIdentity_CODE = Structure(
+ [
+ (("skip_connect", 0),), # node-1
+ (("skip_connect", 0), ("skip_connect", 1)), # node-2
+ (("skip_connect", 0), ("skip_connect", 1), ("skip_connect", 2)),
+ ] # node-3
+)
+
+architectures = {
+ "resnet": ResNet_CODE,
+ "all_c3x3": AllConv3x3_CODE,
+ "all_c1x1": AllConv1x1_CODE,
+ "all_idnt": AllIdentity_CODE,
+ "all_full": AllFull_CODE,
+}
diff --git a/AutoDL-Projects/xautodl/models/cell_searchs/search_cells.py b/AutoDL-Projects/xautodl/models/cell_searchs/search_cells.py
new file mode 100644
index 0000000..6be7c52
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/cell_searchs/search_cells.py
@@ -0,0 +1,267 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019 #
+##################################################
+import math, random, torch
+import warnings
+import torch.nn as nn
+import torch.nn.functional as F
+from copy import deepcopy
+from ..cell_operations import OPS
+
+
+# This module is used for NAS-Bench-201, represents a small search space with a complete DAG
+class NAS201SearchCell(nn.Module):
+ def __init__(
+ self,
+ C_in,
+ C_out,
+ stride,
+ max_nodes,
+ op_names,
+ affine=False,
+ track_running_stats=True,
+ ):
+ super(NAS201SearchCell, self).__init__()
+
+ self.op_names = deepcopy(op_names)
+ self.edges = nn.ModuleDict()
+ self.max_nodes = max_nodes
+ self.in_dim = C_in
+ self.out_dim = C_out
+ for i in range(1, max_nodes):
+ for j in range(i):
+ node_str = "{:}<-{:}".format(i, j)
+ if j == 0:
+ xlists = [
+ OPS[op_name](C_in, C_out, stride, affine, track_running_stats)
+ for op_name in op_names
+ ]
+ else:
+ xlists = [
+ OPS[op_name](C_in, C_out, 1, affine, track_running_stats)
+ for op_name in op_names
+ ]
+ self.edges[node_str] = nn.ModuleList(xlists)
+ self.edge_keys = sorted(list(self.edges.keys()))
+ self.edge2index = {key: i for i, key in enumerate(self.edge_keys)}
+ self.num_edges = len(self.edges)
+
+ def extra_repr(self):
+ string = "info :: {max_nodes} nodes, inC={in_dim}, outC={out_dim}".format(
+ **self.__dict__
+ )
+ return string
+
+ def forward(self, inputs, weightss):
+ nodes = [inputs]
+ for i in range(1, self.max_nodes):
+ inter_nodes = []
+ for j in range(i):
+ node_str = "{:}<-{:}".format(i, j)
+ weights = weightss[self.edge2index[node_str]]
+ inter_nodes.append(
+ sum(
+ layer(nodes[j]) * w
+ for layer, w in zip(self.edges[node_str], weights)
+ )
+ )
+ nodes.append(sum(inter_nodes))
+ return nodes[-1]
+
+ # GDAS
+ def forward_gdas(self, inputs, hardwts, index):
+ nodes = [inputs]
+ for i in range(1, self.max_nodes):
+ inter_nodes = []
+ for j in range(i):
+ node_str = "{:}<-{:}".format(i, j)
+ weights = hardwts[self.edge2index[node_str]]
+ argmaxs = index[self.edge2index[node_str]].item()
+ weigsum = sum(
+ weights[_ie] * edge(nodes[j]) if _ie == argmaxs else weights[_ie]
+ for _ie, edge in enumerate(self.edges[node_str])
+ )
+ inter_nodes.append(weigsum)
+ nodes.append(sum(inter_nodes))
+ return nodes[-1]
+
+ # GDAS Variant: https://github.com/D-X-Y/AutoDL-Projects/issues/119
+ def forward_gdas_v1(self, inputs, hardwts, index):
+ nodes = [inputs]
+ for i in range(1, self.max_nodes):
+ inter_nodes = []
+ for j in range(i):
+ node_str = "{:}<-{:}".format(i, j)
+ weights = hardwts[self.edge2index[node_str]]
+ argmaxs = index[self.edge2index[node_str]].item()
+ weigsum = weights[argmaxs] * self.edges[node_str](nodes[j])
+ inter_nodes.append(weigsum)
+ nodes.append(sum(inter_nodes))
+ return nodes[-1]
+
+ # joint
+ def forward_joint(self, inputs, weightss):
+ nodes = [inputs]
+ for i in range(1, self.max_nodes):
+ inter_nodes = []
+ for j in range(i):
+ node_str = "{:}<-{:}".format(i, j)
+ weights = weightss[self.edge2index[node_str]]
+ # aggregation = sum( layer(nodes[j]) * w for layer, w in zip(self.edges[node_str], weights) ) / weights.numel()
+ aggregation = sum(
+ layer(nodes[j]) * w
+ for layer, w in zip(self.edges[node_str], weights)
+ )
+ inter_nodes.append(aggregation)
+ nodes.append(sum(inter_nodes))
+ return nodes[-1]
+
+ # uniform random sampling per iteration, SETN
+ def forward_urs(self, inputs):
+ nodes = [inputs]
+ for i in range(1, self.max_nodes):
+ while True: # to avoid select zero for all ops
+ sops, has_non_zero = [], False
+ for j in range(i):
+ node_str = "{:}<-{:}".format(i, j)
+ candidates = self.edges[node_str]
+ select_op = random.choice(candidates)
+ sops.append(select_op)
+ if not hasattr(select_op, "is_zero") or select_op.is_zero is False:
+ has_non_zero = True
+ if has_non_zero:
+ break
+ inter_nodes = []
+ for j, select_op in enumerate(sops):
+ inter_nodes.append(select_op(nodes[j]))
+ nodes.append(sum(inter_nodes))
+ return nodes[-1]
+
+ # select the argmax
+ def forward_select(self, inputs, weightss):
+ nodes = [inputs]
+ for i in range(1, self.max_nodes):
+ inter_nodes = []
+ for j in range(i):
+ node_str = "{:}<-{:}".format(i, j)
+ weights = weightss[self.edge2index[node_str]]
+ inter_nodes.append(
+ self.edges[node_str][weights.argmax().item()](nodes[j])
+ )
+ # inter_nodes.append( sum( layer(nodes[j]) * w for layer, w in zip(self.edges[node_str], weights) ) )
+ nodes.append(sum(inter_nodes))
+ return nodes[-1]
+
+ # forward with a specific structure
+ def forward_dynamic(self, inputs, structure):
+ nodes = [inputs]
+ for i in range(1, self.max_nodes):
+ cur_op_node = structure.nodes[i - 1]
+ inter_nodes = []
+ for op_name, j in cur_op_node:
+ node_str = "{:}<-{:}".format(i, j)
+ op_index = self.op_names.index(op_name)
+ inter_nodes.append(self.edges[node_str][op_index](nodes[j]))
+ nodes.append(sum(inter_nodes))
+ return nodes[-1]
+
+
+# Learning Transferable Architectures for Scalable Image Recognition, CVPR 2018
+
+
+class MixedOp(nn.Module):
+ def __init__(self, space, C, stride, affine, track_running_stats):
+ super(MixedOp, self).__init__()
+ self._ops = nn.ModuleList()
+ for primitive in space:
+ op = OPS[primitive](C, C, stride, affine, track_running_stats)
+ self._ops.append(op)
+
+ def forward_gdas(self, x, weights, index):
+ return self._ops[index](x) * weights[index]
+
+ def forward_darts(self, x, weights):
+ return sum(w * op(x) for w, op in zip(weights, self._ops))
+
+
+class NASNetSearchCell(nn.Module):
+ def __init__(
+ self,
+ space,
+ steps,
+ multiplier,
+ C_prev_prev,
+ C_prev,
+ C,
+ reduction,
+ reduction_prev,
+ affine,
+ track_running_stats,
+ ):
+ super(NASNetSearchCell, self).__init__()
+ self.reduction = reduction
+ self.op_names = deepcopy(space)
+ if reduction_prev:
+ self.preprocess0 = OPS["skip_connect"](
+ C_prev_prev, C, 2, affine, track_running_stats
+ )
+ else:
+ self.preprocess0 = OPS["nor_conv_1x1"](
+ C_prev_prev, C, 1, affine, track_running_stats
+ )
+ self.preprocess1 = OPS["nor_conv_1x1"](
+ C_prev, C, 1, affine, track_running_stats
+ )
+ self._steps = steps
+ self._multiplier = multiplier
+
+ self._ops = nn.ModuleList()
+ self.edges = nn.ModuleDict()
+ for i in range(self._steps):
+ for j in range(2 + i):
+ node_str = "{:}<-{:}".format(
+ i, j
+ ) # indicate the edge from node-(j) to node-(i+2)
+ stride = 2 if reduction and j < 2 else 1
+ op = MixedOp(space, C, stride, affine, track_running_stats)
+ self.edges[node_str] = op
+ self.edge_keys = sorted(list(self.edges.keys()))
+ self.edge2index = {key: i for i, key in enumerate(self.edge_keys)}
+ self.num_edges = len(self.edges)
+
+ @property
+ def multiplier(self):
+ return self._multiplier
+
+ def forward_gdas(self, s0, s1, weightss, indexs):
+ s0 = self.preprocess0(s0)
+ s1 = self.preprocess1(s1)
+
+ states = [s0, s1]
+ for i in range(self._steps):
+ clist = []
+ for j, h in enumerate(states):
+ node_str = "{:}<-{:}".format(i, j)
+ op = self.edges[node_str]
+ weights = weightss[self.edge2index[node_str]]
+ index = indexs[self.edge2index[node_str]].item()
+ clist.append(op.forward_gdas(h, weights, index))
+ states.append(sum(clist))
+
+ return torch.cat(states[-self._multiplier :], dim=1)
+
+ def forward_darts(self, s0, s1, weightss):
+ s0 = self.preprocess0(s0)
+ s1 = self.preprocess1(s1)
+
+ states = [s0, s1]
+ for i in range(self._steps):
+ clist = []
+ for j, h in enumerate(states):
+ node_str = "{:}<-{:}".format(i, j)
+ op = self.edges[node_str]
+ weights = weightss[self.edge2index[node_str]]
+ clist.append(op.forward_darts(h, weights))
+ states.append(sum(clist))
+
+ return torch.cat(states[-self._multiplier :], dim=1)
diff --git a/AutoDL-Projects/xautodl/models/cell_searchs/search_model_darts.py b/AutoDL-Projects/xautodl/models/cell_searchs/search_model_darts.py
new file mode 100644
index 0000000..31041b6
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/cell_searchs/search_model_darts.py
@@ -0,0 +1,122 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019 #
+########################################################
+# DARTS: Differentiable Architecture Search, ICLR 2019 #
+########################################################
+import torch
+import torch.nn as nn
+from copy import deepcopy
+from ..cell_operations import ResNetBasicblock
+from .search_cells import NAS201SearchCell as SearchCell
+from .genotypes import Structure
+
+
+class TinyNetworkDarts(nn.Module):
+ def __init__(
+ self, C, N, max_nodes, num_classes, search_space, affine, track_running_stats
+ ):
+ super(TinyNetworkDarts, self).__init__()
+ self._C = C
+ self._layerN = N
+ self.max_nodes = max_nodes
+ self.stem = nn.Sequential(
+ nn.Conv2d(3, C, kernel_size=3, padding=1, bias=False), nn.BatchNorm2d(C)
+ )
+
+ layer_channels = [C] * N + [C * 2] + [C * 2] * N + [C * 4] + [C * 4] * N
+ layer_reductions = [False] * N + [True] + [False] * N + [True] + [False] * N
+
+ C_prev, num_edge, edge2index = C, None, None
+ self.cells = nn.ModuleList()
+ for index, (C_curr, reduction) in enumerate(
+ zip(layer_channels, layer_reductions)
+ ):
+ if reduction:
+ cell = ResNetBasicblock(C_prev, C_curr, 2)
+ else:
+ cell = SearchCell(
+ C_prev,
+ C_curr,
+ 1,
+ max_nodes,
+ search_space,
+ affine,
+ track_running_stats,
+ )
+ if num_edge is None:
+ num_edge, edge2index = cell.num_edges, cell.edge2index
+ else:
+ assert (
+ num_edge == cell.num_edges and edge2index == cell.edge2index
+ ), "invalid {:} vs. {:}.".format(num_edge, cell.num_edges)
+ self.cells.append(cell)
+ C_prev = cell.out_dim
+ self.op_names = deepcopy(search_space)
+ self._Layer = len(self.cells)
+ self.edge2index = edge2index
+ self.lastact = nn.Sequential(nn.BatchNorm2d(C_prev), nn.ReLU(inplace=True))
+ self.global_pooling = nn.AdaptiveAvgPool2d(1)
+ self.classifier = nn.Linear(C_prev, num_classes)
+ self.arch_parameters = nn.Parameter(
+ 1e-3 * torch.randn(num_edge, len(search_space))
+ )
+
+ def get_weights(self):
+ xlist = list(self.stem.parameters()) + list(self.cells.parameters())
+ xlist += list(self.lastact.parameters()) + list(
+ self.global_pooling.parameters()
+ )
+ xlist += list(self.classifier.parameters())
+ return xlist
+
+ def get_alphas(self):
+ return [self.arch_parameters]
+
+ def show_alphas(self):
+ with torch.no_grad():
+ return "arch-parameters :\n{:}".format(
+ nn.functional.softmax(self.arch_parameters, dim=-1).cpu()
+ )
+
+ def get_message(self):
+ string = self.extra_repr()
+ for i, cell in enumerate(self.cells):
+ string += "\n {:02d}/{:02d} :: {:}".format(
+ i, len(self.cells), cell.extra_repr()
+ )
+ return string
+
+ def extra_repr(self):
+ return "{name}(C={_C}, Max-Nodes={max_nodes}, N={_layerN}, L={_Layer})".format(
+ name=self.__class__.__name__, **self.__dict__
+ )
+
+ def genotype(self):
+ genotypes = []
+ for i in range(1, self.max_nodes):
+ xlist = []
+ for j in range(i):
+ node_str = "{:}<-{:}".format(i, j)
+ with torch.no_grad():
+ weights = self.arch_parameters[self.edge2index[node_str]]
+ op_name = self.op_names[weights.argmax().item()]
+ xlist.append((op_name, j))
+ genotypes.append(tuple(xlist))
+ return Structure(genotypes)
+
+ def forward(self, inputs):
+ alphas = nn.functional.softmax(self.arch_parameters, dim=-1)
+
+ feature = self.stem(inputs)
+ for i, cell in enumerate(self.cells):
+ if isinstance(cell, SearchCell):
+ feature = cell(feature, alphas)
+ else:
+ feature = cell(feature)
+
+ out = self.lastact(feature)
+ out = self.global_pooling(out)
+ out = out.view(out.size(0), -1)
+ logits = self.classifier(out)
+
+ return out, logits
diff --git a/AutoDL-Projects/xautodl/models/cell_searchs/search_model_darts_nasnet.py b/AutoDL-Projects/xautodl/models/cell_searchs/search_model_darts_nasnet.py
new file mode 100644
index 0000000..7cfdb47
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/cell_searchs/search_model_darts_nasnet.py
@@ -0,0 +1,178 @@
+####################
+# DARTS, ICLR 2019 #
+####################
+import torch
+import torch.nn as nn
+from copy import deepcopy
+from typing import List, Text, Dict
+from .search_cells import NASNetSearchCell as SearchCell
+
+
+# The macro structure is based on NASNet
+class NASNetworkDARTS(nn.Module):
+ def __init__(
+ self,
+ C: int,
+ N: int,
+ steps: int,
+ multiplier: int,
+ stem_multiplier: int,
+ num_classes: int,
+ search_space: List[Text],
+ affine: bool,
+ track_running_stats: bool,
+ ):
+ super(NASNetworkDARTS, self).__init__()
+ self._C = C
+ self._layerN = N
+ self._steps = steps
+ self._multiplier = multiplier
+ self.stem = nn.Sequential(
+ nn.Conv2d(3, C * stem_multiplier, kernel_size=3, padding=1, bias=False),
+ nn.BatchNorm2d(C * stem_multiplier),
+ )
+
+ # config for each layer
+ layer_channels = (
+ [C] * N + [C * 2] + [C * 2] * (N - 1) + [C * 4] + [C * 4] * (N - 1)
+ )
+ layer_reductions = (
+ [False] * N + [True] + [False] * (N - 1) + [True] + [False] * (N - 1)
+ )
+
+ num_edge, edge2index = None, None
+ C_prev_prev, C_prev, C_curr, reduction_prev = (
+ C * stem_multiplier,
+ C * stem_multiplier,
+ C,
+ False,
+ )
+
+ self.cells = nn.ModuleList()
+ for index, (C_curr, reduction) in enumerate(
+ zip(layer_channels, layer_reductions)
+ ):
+ cell = SearchCell(
+ search_space,
+ steps,
+ multiplier,
+ C_prev_prev,
+ C_prev,
+ C_curr,
+ reduction,
+ reduction_prev,
+ affine,
+ track_running_stats,
+ )
+ if num_edge is None:
+ num_edge, edge2index = cell.num_edges, cell.edge2index
+ else:
+ assert (
+ num_edge == cell.num_edges and edge2index == cell.edge2index
+ ), "invalid {:} vs. {:}.".format(num_edge, cell.num_edges)
+ self.cells.append(cell)
+ C_prev_prev, C_prev, reduction_prev = C_prev, multiplier * C_curr, reduction
+ self.op_names = deepcopy(search_space)
+ self._Layer = len(self.cells)
+ self.edge2index = edge2index
+ self.lastact = nn.Sequential(nn.BatchNorm2d(C_prev), nn.ReLU(inplace=True))
+ self.global_pooling = nn.AdaptiveAvgPool2d(1)
+ self.classifier = nn.Linear(C_prev, num_classes)
+ self.arch_normal_parameters = nn.Parameter(
+ 1e-3 * torch.randn(num_edge, len(search_space))
+ )
+ self.arch_reduce_parameters = nn.Parameter(
+ 1e-3 * torch.randn(num_edge, len(search_space))
+ )
+
+ def get_weights(self) -> List[torch.nn.Parameter]:
+ xlist = list(self.stem.parameters()) + list(self.cells.parameters())
+ xlist += list(self.lastact.parameters()) + list(
+ self.global_pooling.parameters()
+ )
+ xlist += list(self.classifier.parameters())
+ return xlist
+
+ def get_alphas(self) -> List[torch.nn.Parameter]:
+ return [self.arch_normal_parameters, self.arch_reduce_parameters]
+
+ def show_alphas(self) -> Text:
+ with torch.no_grad():
+ A = "arch-normal-parameters :\n{:}".format(
+ nn.functional.softmax(self.arch_normal_parameters, dim=-1).cpu()
+ )
+ B = "arch-reduce-parameters :\n{:}".format(
+ nn.functional.softmax(self.arch_reduce_parameters, dim=-1).cpu()
+ )
+ return "{:}\n{:}".format(A, B)
+
+ def get_message(self) -> Text:
+ string = self.extra_repr()
+ for i, cell in enumerate(self.cells):
+ string += "\n {:02d}/{:02d} :: {:}".format(
+ i, len(self.cells), cell.extra_repr()
+ )
+ return string
+
+ def extra_repr(self) -> Text:
+ return "{name}(C={_C}, N={_layerN}, steps={_steps}, multiplier={_multiplier}, L={_Layer})".format(
+ name=self.__class__.__name__, **self.__dict__
+ )
+
+ def genotype(self) -> Dict[Text, List]:
+ def _parse(weights):
+ gene = []
+ for i in range(self._steps):
+ edges = []
+ for j in range(2 + i):
+ node_str = "{:}<-{:}".format(i, j)
+ ws = weights[self.edge2index[node_str]]
+ for k, op_name in enumerate(self.op_names):
+ if op_name == "none":
+ continue
+ edges.append((op_name, j, ws[k]))
+ # (TODO) xuanyidong:
+ # Here the selected two edges might come from the same input node.
+ # And this case could be a problem that two edges will collapse into a single one
+ # due to our assumption -- at most one edge from an input node during evaluation.
+ edges = sorted(edges, key=lambda x: -x[-1])
+ selected_edges = edges[:2]
+ gene.append(tuple(selected_edges))
+ return gene
+
+ with torch.no_grad():
+ gene_normal = _parse(
+ torch.softmax(self.arch_normal_parameters, dim=-1).cpu().numpy()
+ )
+ gene_reduce = _parse(
+ torch.softmax(self.arch_reduce_parameters, dim=-1).cpu().numpy()
+ )
+ return {
+ "normal": gene_normal,
+ "normal_concat": list(
+ range(2 + self._steps - self._multiplier, self._steps + 2)
+ ),
+ "reduce": gene_reduce,
+ "reduce_concat": list(
+ range(2 + self._steps - self._multiplier, self._steps + 2)
+ ),
+ }
+
+ def forward(self, inputs):
+
+ normal_w = nn.functional.softmax(self.arch_normal_parameters, dim=1)
+ reduce_w = nn.functional.softmax(self.arch_reduce_parameters, dim=1)
+
+ s0 = s1 = self.stem(inputs)
+ for i, cell in enumerate(self.cells):
+ if cell.reduction:
+ ww = reduce_w
+ else:
+ ww = normal_w
+ s0, s1 = s1, cell.forward_darts(s0, s1, ww)
+ out = self.lastact(s1)
+ out = self.global_pooling(out)
+ out = out.view(out.size(0), -1)
+ logits = self.classifier(out)
+
+ return out, logits
diff --git a/AutoDL-Projects/xautodl/models/cell_searchs/search_model_enas.py b/AutoDL-Projects/xautodl/models/cell_searchs/search_model_enas.py
new file mode 100644
index 0000000..7ba91d4
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/cell_searchs/search_model_enas.py
@@ -0,0 +1,114 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019 #
+##########################################################################
+# Efficient Neural Architecture Search via Parameters Sharing, ICML 2018 #
+##########################################################################
+import torch
+import torch.nn as nn
+from copy import deepcopy
+from ..cell_operations import ResNetBasicblock
+from .search_cells import NAS201SearchCell as SearchCell
+from .genotypes import Structure
+from .search_model_enas_utils import Controller
+
+
+class TinyNetworkENAS(nn.Module):
+ def __init__(
+ self, C, N, max_nodes, num_classes, search_space, affine, track_running_stats
+ ):
+ super(TinyNetworkENAS, self).__init__()
+ self._C = C
+ self._layerN = N
+ self.max_nodes = max_nodes
+ self.stem = nn.Sequential(
+ nn.Conv2d(3, C, kernel_size=3, padding=1, bias=False), nn.BatchNorm2d(C)
+ )
+
+ layer_channels = [C] * N + [C * 2] + [C * 2] * N + [C * 4] + [C * 4] * N
+ layer_reductions = [False] * N + [True] + [False] * N + [True] + [False] * N
+
+ C_prev, num_edge, edge2index = C, None, None
+ self.cells = nn.ModuleList()
+ for index, (C_curr, reduction) in enumerate(
+ zip(layer_channels, layer_reductions)
+ ):
+ if reduction:
+ cell = ResNetBasicblock(C_prev, C_curr, 2)
+ else:
+ cell = SearchCell(
+ C_prev,
+ C_curr,
+ 1,
+ max_nodes,
+ search_space,
+ affine,
+ track_running_stats,
+ )
+ if num_edge is None:
+ num_edge, edge2index = cell.num_edges, cell.edge2index
+ else:
+ assert (
+ num_edge == cell.num_edges and edge2index == cell.edge2index
+ ), "invalid {:} vs. {:}.".format(num_edge, cell.num_edges)
+ self.cells.append(cell)
+ C_prev = cell.out_dim
+ self.op_names = deepcopy(search_space)
+ self._Layer = len(self.cells)
+ self.edge2index = edge2index
+ self.lastact = nn.Sequential(nn.BatchNorm2d(C_prev), nn.ReLU(inplace=True))
+ self.global_pooling = nn.AdaptiveAvgPool2d(1)
+ self.classifier = nn.Linear(C_prev, num_classes)
+ # to maintain the sampled architecture
+ self.sampled_arch = None
+
+ def update_arch(self, _arch):
+ if _arch is None:
+ self.sampled_arch = None
+ elif isinstance(_arch, Structure):
+ self.sampled_arch = _arch
+ elif isinstance(_arch, (list, tuple)):
+ genotypes = []
+ for i in range(1, self.max_nodes):
+ xlist = []
+ for j in range(i):
+ node_str = "{:}<-{:}".format(i, j)
+ op_index = _arch[self.edge2index[node_str]]
+ op_name = self.op_names[op_index]
+ xlist.append((op_name, j))
+ genotypes.append(tuple(xlist))
+ self.sampled_arch = Structure(genotypes)
+ else:
+ raise ValueError("invalid type of input architecture : {:}".format(_arch))
+ return self.sampled_arch
+
+ def create_controller(self):
+ return Controller(len(self.edge2index), len(self.op_names))
+
+ def get_message(self):
+ string = self.extra_repr()
+ for i, cell in enumerate(self.cells):
+ string += "\n {:02d}/{:02d} :: {:}".format(
+ i, len(self.cells), cell.extra_repr()
+ )
+ return string
+
+ def extra_repr(self):
+ return "{name}(C={_C}, Max-Nodes={max_nodes}, N={_layerN}, L={_Layer})".format(
+ name=self.__class__.__name__, **self.__dict__
+ )
+
+ def forward(self, inputs):
+
+ feature = self.stem(inputs)
+ for i, cell in enumerate(self.cells):
+ if isinstance(cell, SearchCell):
+ feature = cell.forward_dynamic(feature, self.sampled_arch)
+ else:
+ feature = cell(feature)
+
+ out = self.lastact(feature)
+ out = self.global_pooling(out)
+ out = out.view(out.size(0), -1)
+ logits = self.classifier(out)
+
+ return out, logits
diff --git a/AutoDL-Projects/xautodl/models/cell_searchs/search_model_enas_utils.py b/AutoDL-Projects/xautodl/models/cell_searchs/search_model_enas_utils.py
new file mode 100644
index 0000000..71d5d0f
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/cell_searchs/search_model_enas_utils.py
@@ -0,0 +1,74 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019 #
+##########################################################################
+# Efficient Neural Architecture Search via Parameters Sharing, ICML 2018 #
+##########################################################################
+import torch
+import torch.nn as nn
+from torch.distributions.categorical import Categorical
+
+
+class Controller(nn.Module):
+ # we refer to https://github.com/TDeVries/enas_pytorch/blob/master/models/controller.py
+ def __init__(
+ self,
+ num_edge,
+ num_ops,
+ lstm_size=32,
+ lstm_num_layers=2,
+ tanh_constant=2.5,
+ temperature=5.0,
+ ):
+ super(Controller, self).__init__()
+ # assign the attributes
+ self.num_edge = num_edge
+ self.num_ops = num_ops
+ self.lstm_size = lstm_size
+ self.lstm_N = lstm_num_layers
+ self.tanh_constant = tanh_constant
+ self.temperature = temperature
+ # create parameters
+ self.register_parameter(
+ "input_vars", nn.Parameter(torch.Tensor(1, 1, lstm_size))
+ )
+ self.w_lstm = nn.LSTM(
+ input_size=self.lstm_size,
+ hidden_size=self.lstm_size,
+ num_layers=self.lstm_N,
+ )
+ self.w_embd = nn.Embedding(self.num_ops, self.lstm_size)
+ self.w_pred = nn.Linear(self.lstm_size, self.num_ops)
+
+ nn.init.uniform_(self.input_vars, -0.1, 0.1)
+ nn.init.uniform_(self.w_lstm.weight_hh_l0, -0.1, 0.1)
+ nn.init.uniform_(self.w_lstm.weight_ih_l0, -0.1, 0.1)
+ nn.init.uniform_(self.w_embd.weight, -0.1, 0.1)
+ nn.init.uniform_(self.w_pred.weight, -0.1, 0.1)
+
+ def forward(self):
+
+ inputs, h0 = self.input_vars, None
+ log_probs, entropys, sampled_arch = [], [], []
+ for iedge in range(self.num_edge):
+ outputs, h0 = self.w_lstm(inputs, h0)
+
+ logits = self.w_pred(outputs)
+ logits = logits / self.temperature
+ logits = self.tanh_constant * torch.tanh(logits)
+ # distribution
+ op_distribution = Categorical(logits=logits)
+ op_index = op_distribution.sample()
+ sampled_arch.append(op_index.item())
+
+ op_log_prob = op_distribution.log_prob(op_index)
+ log_probs.append(op_log_prob.view(-1))
+ op_entropy = op_distribution.entropy()
+ entropys.append(op_entropy.view(-1))
+
+ # obtain the input embedding for the next step
+ inputs = self.w_embd(op_index)
+ return (
+ torch.sum(torch.cat(log_probs)),
+ torch.sum(torch.cat(entropys)),
+ sampled_arch,
+ )
diff --git a/AutoDL-Projects/xautodl/models/cell_searchs/search_model_gdas.py b/AutoDL-Projects/xautodl/models/cell_searchs/search_model_gdas.py
new file mode 100644
index 0000000..82f7b9a
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/cell_searchs/search_model_gdas.py
@@ -0,0 +1,142 @@
+###########################################################################
+# Searching for A Robust Neural Architecture in Four GPU Hours, CVPR 2019 #
+###########################################################################
+import torch
+import torch.nn as nn
+from copy import deepcopy
+from ..cell_operations import ResNetBasicblock
+from .search_cells import NAS201SearchCell as SearchCell
+from .genotypes import Structure
+
+
+class TinyNetworkGDAS(nn.Module):
+
+ # def __init__(self, C, N, max_nodes, num_classes, search_space, affine=False, track_running_stats=True):
+ def __init__(
+ self, C, N, max_nodes, num_classes, search_space, affine, track_running_stats
+ ):
+ super(TinyNetworkGDAS, self).__init__()
+ self._C = C
+ self._layerN = N
+ self.max_nodes = max_nodes
+ self.stem = nn.Sequential(
+ nn.Conv2d(3, C, kernel_size=3, padding=1, bias=False), nn.BatchNorm2d(C)
+ )
+
+ layer_channels = [C] * N + [C * 2] + [C * 2] * N + [C * 4] + [C * 4] * N
+ layer_reductions = [False] * N + [True] + [False] * N + [True] + [False] * N
+
+ C_prev, num_edge, edge2index = C, None, None
+ self.cells = nn.ModuleList()
+ for index, (C_curr, reduction) in enumerate(
+ zip(layer_channels, layer_reductions)
+ ):
+ if reduction:
+ cell = ResNetBasicblock(C_prev, C_curr, 2)
+ else:
+ cell = SearchCell(
+ C_prev,
+ C_curr,
+ 1,
+ max_nodes,
+ search_space,
+ affine,
+ track_running_stats,
+ )
+ if num_edge is None:
+ num_edge, edge2index = cell.num_edges, cell.edge2index
+ else:
+ assert (
+ num_edge == cell.num_edges and edge2index == cell.edge2index
+ ), "invalid {:} vs. {:}.".format(num_edge, cell.num_edges)
+ self.cells.append(cell)
+ C_prev = cell.out_dim
+ self.op_names = deepcopy(search_space)
+ self._Layer = len(self.cells)
+ self.edge2index = edge2index
+ self.lastact = nn.Sequential(nn.BatchNorm2d(C_prev), nn.ReLU(inplace=True))
+ self.global_pooling = nn.AdaptiveAvgPool2d(1)
+ self.classifier = nn.Linear(C_prev, num_classes)
+ self.arch_parameters = nn.Parameter(
+ 1e-3 * torch.randn(num_edge, len(search_space))
+ )
+ self.tau = 10
+
+ def get_weights(self):
+ xlist = list(self.stem.parameters()) + list(self.cells.parameters())
+ xlist += list(self.lastact.parameters()) + list(
+ self.global_pooling.parameters()
+ )
+ xlist += list(self.classifier.parameters())
+ return xlist
+
+ def set_tau(self, tau):
+ self.tau = tau
+
+ def get_tau(self):
+ return self.tau
+
+ def get_alphas(self):
+ return [self.arch_parameters]
+
+ def show_alphas(self):
+ with torch.no_grad():
+ return "arch-parameters :\n{:}".format(
+ nn.functional.softmax(self.arch_parameters, dim=-1).cpu()
+ )
+
+ def get_message(self):
+ string = self.extra_repr()
+ for i, cell in enumerate(self.cells):
+ string += "\n {:02d}/{:02d} :: {:}".format(
+ i, len(self.cells), cell.extra_repr()
+ )
+ return string
+
+ def extra_repr(self):
+ return "{name}(C={_C}, Max-Nodes={max_nodes}, N={_layerN}, L={_Layer})".format(
+ name=self.__class__.__name__, **self.__dict__
+ )
+
+ def genotype(self):
+ genotypes = []
+ for i in range(1, self.max_nodes):
+ xlist = []
+ for j in range(i):
+ node_str = "{:}<-{:}".format(i, j)
+ with torch.no_grad():
+ weights = self.arch_parameters[self.edge2index[node_str]]
+ op_name = self.op_names[weights.argmax().item()]
+ xlist.append((op_name, j))
+ genotypes.append(tuple(xlist))
+ return Structure(genotypes)
+
+ def forward(self, inputs):
+ while True:
+ gumbels = -torch.empty_like(self.arch_parameters).exponential_().log()
+ logits = (self.arch_parameters.log_softmax(dim=1) + gumbels) / self.tau
+ probs = nn.functional.softmax(logits, dim=1)
+ index = probs.max(-1, keepdim=True)[1]
+ one_h = torch.zeros_like(logits).scatter_(-1, index, 1.0)
+ hardwts = one_h - probs.detach() + probs
+ if (
+ (torch.isinf(gumbels).any())
+ or (torch.isinf(probs).any())
+ or (torch.isnan(probs).any())
+ ):
+ continue
+ else:
+ break
+
+ feature = self.stem(inputs)
+ for i, cell in enumerate(self.cells):
+ if isinstance(cell, SearchCell):
+ feature = cell.forward_gdas(feature, hardwts, index)
+ else:
+ feature = cell(feature)
+ out = self.lastact(feature)
+ out = self.global_pooling(out)
+ out = out.view(out.size(0), -1)
+ logits = self.classifier(out)
+
+ return out, logits
diff --git a/AutoDL-Projects/xautodl/models/cell_searchs/search_model_gdas_frc_nasnet.py b/AutoDL-Projects/xautodl/models/cell_searchs/search_model_gdas_frc_nasnet.py
new file mode 100644
index 0000000..9ca5ce7
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/cell_searchs/search_model_gdas_frc_nasnet.py
@@ -0,0 +1,200 @@
+###########################################################################
+# Searching for A Robust Neural Architecture in Four GPU Hours, CVPR 2019 #
+###########################################################################
+import torch
+import torch.nn as nn
+from copy import deepcopy
+
+from .search_cells import NASNetSearchCell as SearchCell
+from ..cell_operations import RAW_OP_CLASSES
+
+
+# The macro structure is based on NASNet
+class NASNetworkGDAS_FRC(nn.Module):
+ def __init__(
+ self,
+ C,
+ N,
+ steps,
+ multiplier,
+ stem_multiplier,
+ num_classes,
+ search_space,
+ affine,
+ track_running_stats,
+ ):
+ super(NASNetworkGDAS_FRC, self).__init__()
+ self._C = C
+ self._layerN = N
+ self._steps = steps
+ self._multiplier = multiplier
+ self.stem = nn.Sequential(
+ nn.Conv2d(3, C * stem_multiplier, kernel_size=3, padding=1, bias=False),
+ nn.BatchNorm2d(C * stem_multiplier),
+ )
+
+ # config for each layer
+ layer_channels = (
+ [C] * N + [C * 2] + [C * 2] * (N - 1) + [C * 4] + [C * 4] * (N - 1)
+ )
+ layer_reductions = (
+ [False] * N + [True] + [False] * (N - 1) + [True] + [False] * (N - 1)
+ )
+
+ num_edge, edge2index = None, None
+ C_prev_prev, C_prev, C_curr, reduction_prev = (
+ C * stem_multiplier,
+ C * stem_multiplier,
+ C,
+ False,
+ )
+
+ self.cells = nn.ModuleList()
+ for index, (C_curr, reduction) in enumerate(
+ zip(layer_channels, layer_reductions)
+ ):
+ if reduction:
+ cell = RAW_OP_CLASSES["gdas_reduction"](
+ C_prev_prev,
+ C_prev,
+ C_curr,
+ reduction_prev,
+ affine,
+ track_running_stats,
+ )
+ else:
+ cell = SearchCell(
+ search_space,
+ steps,
+ multiplier,
+ C_prev_prev,
+ C_prev,
+ C_curr,
+ reduction,
+ reduction_prev,
+ affine,
+ track_running_stats,
+ )
+ if num_edge is None:
+ num_edge, edge2index = cell.num_edges, cell.edge2index
+ else:
+ assert (
+ reduction
+ or num_edge == cell.num_edges
+ and edge2index == cell.edge2index
+ ), "invalid {:} vs. {:}.".format(num_edge, cell.num_edges)
+ self.cells.append(cell)
+ C_prev_prev, C_prev, reduction_prev = (
+ C_prev,
+ cell.multiplier * C_curr,
+ reduction,
+ )
+ self.op_names = deepcopy(search_space)
+ self._Layer = len(self.cells)
+ self.edge2index = edge2index
+ self.lastact = nn.Sequential(nn.BatchNorm2d(C_prev), nn.ReLU(inplace=True))
+ self.global_pooling = nn.AdaptiveAvgPool2d(1)
+ self.classifier = nn.Linear(C_prev, num_classes)
+ self.arch_parameters = nn.Parameter(
+ 1e-3 * torch.randn(num_edge, len(search_space))
+ )
+ self.tau = 10
+
+ def get_weights(self):
+ xlist = list(self.stem.parameters()) + list(self.cells.parameters())
+ xlist += list(self.lastact.parameters()) + list(
+ self.global_pooling.parameters()
+ )
+ xlist += list(self.classifier.parameters())
+ return xlist
+
+ def set_tau(self, tau):
+ self.tau = tau
+
+ def get_tau(self):
+ return self.tau
+
+ def get_alphas(self):
+ return [self.arch_parameters]
+
+ def show_alphas(self):
+ with torch.no_grad():
+ A = "arch-normal-parameters :\n{:}".format(
+ nn.functional.softmax(self.arch_parameters, dim=-1).cpu()
+ )
+ return "{:}".format(A)
+
+ def get_message(self):
+ string = self.extra_repr()
+ for i, cell in enumerate(self.cells):
+ string += "\n {:02d}/{:02d} :: {:}".format(
+ i, len(self.cells), cell.extra_repr()
+ )
+ return string
+
+ def extra_repr(self):
+ return "{name}(C={_C}, N={_layerN}, steps={_steps}, multiplier={_multiplier}, L={_Layer})".format(
+ name=self.__class__.__name__, **self.__dict__
+ )
+
+ def genotype(self):
+ def _parse(weights):
+ gene = []
+ for i in range(self._steps):
+ edges = []
+ for j in range(2 + i):
+ node_str = "{:}<-{:}".format(i, j)
+ ws = weights[self.edge2index[node_str]]
+ for k, op_name in enumerate(self.op_names):
+ if op_name == "none":
+ continue
+ edges.append((op_name, j, ws[k]))
+ edges = sorted(edges, key=lambda x: -x[-1])
+ selected_edges = edges[:2]
+ gene.append(tuple(selected_edges))
+ return gene
+
+ with torch.no_grad():
+ gene_normal = _parse(
+ torch.softmax(self.arch_parameters, dim=-1).cpu().numpy()
+ )
+ return {
+ "normal": gene_normal,
+ "normal_concat": list(
+ range(2 + self._steps - self._multiplier, self._steps + 2)
+ ),
+ }
+
+ def forward(self, inputs):
+ def get_gumbel_prob(xins):
+ while True:
+ gumbels = -torch.empty_like(xins).exponential_().log()
+ logits = (xins.log_softmax(dim=1) + gumbels) / self.tau
+ probs = nn.functional.softmax(logits, dim=1)
+ index = probs.max(-1, keepdim=True)[1]
+ one_h = torch.zeros_like(logits).scatter_(-1, index, 1.0)
+ hardwts = one_h - probs.detach() + probs
+ if (
+ (torch.isinf(gumbels).any())
+ or (torch.isinf(probs).any())
+ or (torch.isnan(probs).any())
+ ):
+ continue
+ else:
+ break
+ return hardwts, index
+
+ hardwts, index = get_gumbel_prob(self.arch_parameters)
+
+ s0 = s1 = self.stem(inputs)
+ for i, cell in enumerate(self.cells):
+ if cell.reduction:
+ s0, s1 = s1, cell(s0, s1)
+ else:
+ s0, s1 = s1, cell.forward_gdas(s0, s1, hardwts, index)
+ out = self.lastact(s1)
+ out = self.global_pooling(out)
+ out = out.view(out.size(0), -1)
+ logits = self.classifier(out)
+
+ return out, logits
diff --git a/AutoDL-Projects/xautodl/models/cell_searchs/search_model_gdas_nasnet.py b/AutoDL-Projects/xautodl/models/cell_searchs/search_model_gdas_nasnet.py
new file mode 100644
index 0000000..5aff5d3
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/cell_searchs/search_model_gdas_nasnet.py
@@ -0,0 +1,197 @@
+###########################################################################
+# Searching for A Robust Neural Architecture in Four GPU Hours, CVPR 2019 #
+###########################################################################
+import torch
+import torch.nn as nn
+from copy import deepcopy
+from .search_cells import NASNetSearchCell as SearchCell
+
+
+# The macro structure is based on NASNet
+class NASNetworkGDAS(nn.Module):
+ def __init__(
+ self,
+ C,
+ N,
+ steps,
+ multiplier,
+ stem_multiplier,
+ num_classes,
+ search_space,
+ affine,
+ track_running_stats,
+ ):
+ super(NASNetworkGDAS, self).__init__()
+ self._C = C
+ self._layerN = N
+ self._steps = steps
+ self._multiplier = multiplier
+ self.stem = nn.Sequential(
+ nn.Conv2d(3, C * stem_multiplier, kernel_size=3, padding=1, bias=False),
+ nn.BatchNorm2d(C * stem_multiplier),
+ )
+
+ # config for each layer
+ layer_channels = (
+ [C] * N + [C * 2] + [C * 2] * (N - 1) + [C * 4] + [C * 4] * (N - 1)
+ )
+ layer_reductions = (
+ [False] * N + [True] + [False] * (N - 1) + [True] + [False] * (N - 1)
+ )
+
+ num_edge, edge2index = None, None
+ C_prev_prev, C_prev, C_curr, reduction_prev = (
+ C * stem_multiplier,
+ C * stem_multiplier,
+ C,
+ False,
+ )
+
+ self.cells = nn.ModuleList()
+ for index, (C_curr, reduction) in enumerate(
+ zip(layer_channels, layer_reductions)
+ ):
+ cell = SearchCell(
+ search_space,
+ steps,
+ multiplier,
+ C_prev_prev,
+ C_prev,
+ C_curr,
+ reduction,
+ reduction_prev,
+ affine,
+ track_running_stats,
+ )
+ if num_edge is None:
+ num_edge, edge2index = cell.num_edges, cell.edge2index
+ else:
+ assert (
+ num_edge == cell.num_edges and edge2index == cell.edge2index
+ ), "invalid {:} vs. {:}.".format(num_edge, cell.num_edges)
+ self.cells.append(cell)
+ C_prev_prev, C_prev, reduction_prev = C_prev, multiplier * C_curr, reduction
+ self.op_names = deepcopy(search_space)
+ self._Layer = len(self.cells)
+ self.edge2index = edge2index
+ self.lastact = nn.Sequential(nn.BatchNorm2d(C_prev), nn.ReLU(inplace=True))
+ self.global_pooling = nn.AdaptiveAvgPool2d(1)
+ self.classifier = nn.Linear(C_prev, num_classes)
+ self.arch_normal_parameters = nn.Parameter(
+ 1e-3 * torch.randn(num_edge, len(search_space))
+ )
+ self.arch_reduce_parameters = nn.Parameter(
+ 1e-3 * torch.randn(num_edge, len(search_space))
+ )
+ self.tau = 10
+
+ def get_weights(self):
+ xlist = list(self.stem.parameters()) + list(self.cells.parameters())
+ xlist += list(self.lastact.parameters()) + list(
+ self.global_pooling.parameters()
+ )
+ xlist += list(self.classifier.parameters())
+ return xlist
+
+ def set_tau(self, tau):
+ self.tau = tau
+
+ def get_tau(self):
+ return self.tau
+
+ def get_alphas(self):
+ return [self.arch_normal_parameters, self.arch_reduce_parameters]
+
+ def show_alphas(self):
+ with torch.no_grad():
+ A = "arch-normal-parameters :\n{:}".format(
+ nn.functional.softmax(self.arch_normal_parameters, dim=-1).cpu()
+ )
+ B = "arch-reduce-parameters :\n{:}".format(
+ nn.functional.softmax(self.arch_reduce_parameters, dim=-1).cpu()
+ )
+ return "{:}\n{:}".format(A, B)
+
+ def get_message(self):
+ string = self.extra_repr()
+ for i, cell in enumerate(self.cells):
+ string += "\n {:02d}/{:02d} :: {:}".format(
+ i, len(self.cells), cell.extra_repr()
+ )
+ return string
+
+ def extra_repr(self):
+ return "{name}(C={_C}, N={_layerN}, steps={_steps}, multiplier={_multiplier}, L={_Layer})".format(
+ name=self.__class__.__name__, **self.__dict__
+ )
+
+ def genotype(self):
+ def _parse(weights):
+ gene = []
+ for i in range(self._steps):
+ edges = []
+ for j in range(2 + i):
+ node_str = "{:}<-{:}".format(i, j)
+ ws = weights[self.edge2index[node_str]]
+ for k, op_name in enumerate(self.op_names):
+ if op_name == "none":
+ continue
+ edges.append((op_name, j, ws[k]))
+ edges = sorted(edges, key=lambda x: -x[-1])
+ selected_edges = edges[:2]
+ gene.append(tuple(selected_edges))
+ return gene
+
+ with torch.no_grad():
+ gene_normal = _parse(
+ torch.softmax(self.arch_normal_parameters, dim=-1).cpu().numpy()
+ )
+ gene_reduce = _parse(
+ torch.softmax(self.arch_reduce_parameters, dim=-1).cpu().numpy()
+ )
+ return {
+ "normal": gene_normal,
+ "normal_concat": list(
+ range(2 + self._steps - self._multiplier, self._steps + 2)
+ ),
+ "reduce": gene_reduce,
+ "reduce_concat": list(
+ range(2 + self._steps - self._multiplier, self._steps + 2)
+ ),
+ }
+
+ def forward(self, inputs):
+ def get_gumbel_prob(xins):
+ while True:
+ gumbels = -torch.empty_like(xins).exponential_().log()
+ logits = (xins.log_softmax(dim=1) + gumbels) / self.tau
+ probs = nn.functional.softmax(logits, dim=1)
+ index = probs.max(-1, keepdim=True)[1]
+ one_h = torch.zeros_like(logits).scatter_(-1, index, 1.0)
+ hardwts = one_h - probs.detach() + probs
+ if (
+ (torch.isinf(gumbels).any())
+ or (torch.isinf(probs).any())
+ or (torch.isnan(probs).any())
+ ):
+ continue
+ else:
+ break
+ return hardwts, index
+
+ normal_hardwts, normal_index = get_gumbel_prob(self.arch_normal_parameters)
+ reduce_hardwts, reduce_index = get_gumbel_prob(self.arch_reduce_parameters)
+
+ s0 = s1 = self.stem(inputs)
+ for i, cell in enumerate(self.cells):
+ if cell.reduction:
+ hardwts, index = reduce_hardwts, reduce_index
+ else:
+ hardwts, index = normal_hardwts, normal_index
+ s0, s1 = s1, cell.forward_gdas(s0, s1, hardwts, index)
+ out = self.lastact(s1)
+ out = self.global_pooling(out)
+ out = out.view(out.size(0), -1)
+ logits = self.classifier(out)
+
+ return out, logits
diff --git a/AutoDL-Projects/xautodl/models/cell_searchs/search_model_random.py b/AutoDL-Projects/xautodl/models/cell_searchs/search_model_random.py
new file mode 100644
index 0000000..611dc75
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/cell_searchs/search_model_random.py
@@ -0,0 +1,102 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019 #
+##############################################################################
+# Random Search and Reproducibility for Neural Architecture Search, UAI 2019 #
+##############################################################################
+import torch, random
+import torch.nn as nn
+from copy import deepcopy
+from ..cell_operations import ResNetBasicblock
+from .search_cells import NAS201SearchCell as SearchCell
+from .genotypes import Structure
+
+
+class TinyNetworkRANDOM(nn.Module):
+ def __init__(
+ self, C, N, max_nodes, num_classes, search_space, affine, track_running_stats
+ ):
+ super(TinyNetworkRANDOM, self).__init__()
+ self._C = C
+ self._layerN = N
+ self.max_nodes = max_nodes
+ self.stem = nn.Sequential(
+ nn.Conv2d(3, C, kernel_size=3, padding=1, bias=False), nn.BatchNorm2d(C)
+ )
+
+ layer_channels = [C] * N + [C * 2] + [C * 2] * N + [C * 4] + [C * 4] * N
+ layer_reductions = [False] * N + [True] + [False] * N + [True] + [False] * N
+
+ C_prev, num_edge, edge2index = C, None, None
+ self.cells = nn.ModuleList()
+ for index, (C_curr, reduction) in enumerate(
+ zip(layer_channels, layer_reductions)
+ ):
+ if reduction:
+ cell = ResNetBasicblock(C_prev, C_curr, 2)
+ else:
+ cell = SearchCell(
+ C_prev,
+ C_curr,
+ 1,
+ max_nodes,
+ search_space,
+ affine,
+ track_running_stats,
+ )
+ if num_edge is None:
+ num_edge, edge2index = cell.num_edges, cell.edge2index
+ else:
+ assert (
+ num_edge == cell.num_edges and edge2index == cell.edge2index
+ ), "invalid {:} vs. {:}.".format(num_edge, cell.num_edges)
+ self.cells.append(cell)
+ C_prev = cell.out_dim
+ self.op_names = deepcopy(search_space)
+ self._Layer = len(self.cells)
+ self.edge2index = edge2index
+ self.lastact = nn.Sequential(nn.BatchNorm2d(C_prev), nn.ReLU(inplace=True))
+ self.global_pooling = nn.AdaptiveAvgPool2d(1)
+ self.classifier = nn.Linear(C_prev, num_classes)
+ self.arch_cache = None
+
+ def get_message(self):
+ string = self.extra_repr()
+ for i, cell in enumerate(self.cells):
+ string += "\n {:02d}/{:02d} :: {:}".format(
+ i, len(self.cells), cell.extra_repr()
+ )
+ return string
+
+ def extra_repr(self):
+ return "{name}(C={_C}, Max-Nodes={max_nodes}, N={_layerN}, L={_Layer})".format(
+ name=self.__class__.__name__, **self.__dict__
+ )
+
+ def random_genotype(self, set_cache):
+ genotypes = []
+ for i in range(1, self.max_nodes):
+ xlist = []
+ for j in range(i):
+ node_str = "{:}<-{:}".format(i, j)
+ op_name = random.choice(self.op_names)
+ xlist.append((op_name, j))
+ genotypes.append(tuple(xlist))
+ arch = Structure(genotypes)
+ if set_cache:
+ self.arch_cache = arch
+ return arch
+
+ def forward(self, inputs):
+
+ feature = self.stem(inputs)
+ for i, cell in enumerate(self.cells):
+ if isinstance(cell, SearchCell):
+ feature = cell.forward_dynamic(feature, self.arch_cache)
+ else:
+ feature = cell(feature)
+
+ out = self.lastact(feature)
+ out = self.global_pooling(out)
+ out = out.view(out.size(0), -1)
+ logits = self.classifier(out)
+ return out, logits
diff --git a/AutoDL-Projects/xautodl/models/cell_searchs/search_model_setn.py b/AutoDL-Projects/xautodl/models/cell_searchs/search_model_setn.py
new file mode 100644
index 0000000..ce38be9
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/cell_searchs/search_model_setn.py
@@ -0,0 +1,178 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.01 #
+######################################################################################
+# One-Shot Neural Architecture Search via Self-Evaluated Template Network, ICCV 2019 #
+######################################################################################
+import torch, random
+import torch.nn as nn
+from copy import deepcopy
+from ..cell_operations import ResNetBasicblock
+from .search_cells import NAS201SearchCell as SearchCell
+from .genotypes import Structure
+
+
+class TinyNetworkSETN(nn.Module):
+ def __init__(
+ self, C, N, max_nodes, num_classes, search_space, affine, track_running_stats
+ ):
+ super(TinyNetworkSETN, self).__init__()
+ self._C = C
+ self._layerN = N
+ self.max_nodes = max_nodes
+ self.stem = nn.Sequential(
+ nn.Conv2d(3, C, kernel_size=3, padding=1, bias=False), nn.BatchNorm2d(C)
+ )
+
+ layer_channels = [C] * N + [C * 2] + [C * 2] * N + [C * 4] + [C * 4] * N
+ layer_reductions = [False] * N + [True] + [False] * N + [True] + [False] * N
+
+ C_prev, num_edge, edge2index = C, None, None
+ self.cells = nn.ModuleList()
+ for index, (C_curr, reduction) in enumerate(
+ zip(layer_channels, layer_reductions)
+ ):
+ if reduction:
+ cell = ResNetBasicblock(C_prev, C_curr, 2)
+ else:
+ cell = SearchCell(
+ C_prev,
+ C_curr,
+ 1,
+ max_nodes,
+ search_space,
+ affine,
+ track_running_stats,
+ )
+ if num_edge is None:
+ num_edge, edge2index = cell.num_edges, cell.edge2index
+ else:
+ assert (
+ num_edge == cell.num_edges and edge2index == cell.edge2index
+ ), "invalid {:} vs. {:}.".format(num_edge, cell.num_edges)
+ self.cells.append(cell)
+ C_prev = cell.out_dim
+ self.op_names = deepcopy(search_space)
+ self._Layer = len(self.cells)
+ self.edge2index = edge2index
+ self.lastact = nn.Sequential(nn.BatchNorm2d(C_prev), nn.ReLU(inplace=True))
+ self.global_pooling = nn.AdaptiveAvgPool2d(1)
+ self.classifier = nn.Linear(C_prev, num_classes)
+ self.arch_parameters = nn.Parameter(
+ 1e-3 * torch.randn(num_edge, len(search_space))
+ )
+ self.mode = "urs"
+ self.dynamic_cell = None
+
+ def set_cal_mode(self, mode, dynamic_cell=None):
+ assert mode in ["urs", "joint", "select", "dynamic"]
+ self.mode = mode
+ if mode == "dynamic":
+ self.dynamic_cell = deepcopy(dynamic_cell)
+ else:
+ self.dynamic_cell = None
+
+ def get_cal_mode(self):
+ return self.mode
+
+ def get_weights(self):
+ xlist = list(self.stem.parameters()) + list(self.cells.parameters())
+ xlist += list(self.lastact.parameters()) + list(
+ self.global_pooling.parameters()
+ )
+ xlist += list(self.classifier.parameters())
+ return xlist
+
+ def get_alphas(self):
+ return [self.arch_parameters]
+
+ def get_message(self):
+ string = self.extra_repr()
+ for i, cell in enumerate(self.cells):
+ string += "\n {:02d}/{:02d} :: {:}".format(
+ i, len(self.cells), cell.extra_repr()
+ )
+ return string
+
+ def extra_repr(self):
+ return "{name}(C={_C}, Max-Nodes={max_nodes}, N={_layerN}, L={_Layer})".format(
+ name=self.__class__.__name__, **self.__dict__
+ )
+
+ def genotype(self):
+ genotypes = []
+ for i in range(1, self.max_nodes):
+ xlist = []
+ for j in range(i):
+ node_str = "{:}<-{:}".format(i, j)
+ with torch.no_grad():
+ weights = self.arch_parameters[self.edge2index[node_str]]
+ op_name = self.op_names[weights.argmax().item()]
+ xlist.append((op_name, j))
+ genotypes.append(tuple(xlist))
+ return Structure(genotypes)
+
+ def dync_genotype(self, use_random=False):
+ genotypes = []
+ with torch.no_grad():
+ alphas_cpu = nn.functional.softmax(self.arch_parameters, dim=-1)
+ for i in range(1, self.max_nodes):
+ xlist = []
+ for j in range(i):
+ node_str = "{:}<-{:}".format(i, j)
+ if use_random:
+ op_name = random.choice(self.op_names)
+ else:
+ weights = alphas_cpu[self.edge2index[node_str]]
+ op_index = torch.multinomial(weights, 1).item()
+ op_name = self.op_names[op_index]
+ xlist.append((op_name, j))
+ genotypes.append(tuple(xlist))
+ return Structure(genotypes)
+
+ def get_log_prob(self, arch):
+ with torch.no_grad():
+ logits = nn.functional.log_softmax(self.arch_parameters, dim=-1)
+ select_logits = []
+ for i, node_info in enumerate(arch.nodes):
+ for op, xin in node_info:
+ node_str = "{:}<-{:}".format(i + 1, xin)
+ op_index = self.op_names.index(op)
+ select_logits.append(logits[self.edge2index[node_str], op_index])
+ return sum(select_logits).item()
+
+ def return_topK(self, K):
+ archs = Structure.gen_all(self.op_names, self.max_nodes, False)
+ pairs = [(self.get_log_prob(arch), arch) for arch in archs]
+ if K < 0 or K >= len(archs):
+ K = len(archs)
+ sorted_pairs = sorted(pairs, key=lambda x: -x[0])
+ return_pairs = [sorted_pairs[_][1] for _ in range(K)]
+ return return_pairs
+
+ def forward(self, inputs):
+ alphas = nn.functional.softmax(self.arch_parameters, dim=-1)
+ with torch.no_grad():
+ alphas_cpu = alphas.detach().cpu()
+
+ feature = self.stem(inputs)
+ for i, cell in enumerate(self.cells):
+ if isinstance(cell, SearchCell):
+ if self.mode == "urs":
+ feature = cell.forward_urs(feature)
+ elif self.mode == "select":
+ feature = cell.forward_select(feature, alphas_cpu)
+ elif self.mode == "joint":
+ feature = cell.forward_joint(feature, alphas)
+ elif self.mode == "dynamic":
+ feature = cell.forward_dynamic(feature, self.dynamic_cell)
+ else:
+ raise ValueError("invalid mode={:}".format(self.mode))
+ else:
+ feature = cell(feature)
+
+ out = self.lastact(feature)
+ out = self.global_pooling(out)
+ out = out.view(out.size(0), -1)
+ logits = self.classifier(out)
+
+ return out, logits
diff --git a/AutoDL-Projects/xautodl/models/cell_searchs/search_model_setn_nasnet.py b/AutoDL-Projects/xautodl/models/cell_searchs/search_model_setn_nasnet.py
new file mode 100644
index 0000000..c406fc3
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/cell_searchs/search_model_setn_nasnet.py
@@ -0,0 +1,205 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.01 #
+######################################################################################
+# One-Shot Neural Architecture Search via Self-Evaluated Template Network, ICCV 2019 #
+######################################################################################
+import torch
+import torch.nn as nn
+from copy import deepcopy
+from typing import List, Text, Dict
+from .search_cells import NASNetSearchCell as SearchCell
+
+
+# The macro structure is based on NASNet
+class NASNetworkSETN(nn.Module):
+ def __init__(
+ self,
+ C: int,
+ N: int,
+ steps: int,
+ multiplier: int,
+ stem_multiplier: int,
+ num_classes: int,
+ search_space: List[Text],
+ affine: bool,
+ track_running_stats: bool,
+ ):
+ super(NASNetworkSETN, self).__init__()
+ self._C = C
+ self._layerN = N
+ self._steps = steps
+ self._multiplier = multiplier
+ self.stem = nn.Sequential(
+ nn.Conv2d(3, C * stem_multiplier, kernel_size=3, padding=1, bias=False),
+ nn.BatchNorm2d(C * stem_multiplier),
+ )
+
+ # config for each layer
+ layer_channels = (
+ [C] * N + [C * 2] + [C * 2] * (N - 1) + [C * 4] + [C * 4] * (N - 1)
+ )
+ layer_reductions = (
+ [False] * N + [True] + [False] * (N - 1) + [True] + [False] * (N - 1)
+ )
+
+ num_edge, edge2index = None, None
+ C_prev_prev, C_prev, C_curr, reduction_prev = (
+ C * stem_multiplier,
+ C * stem_multiplier,
+ C,
+ False,
+ )
+
+ self.cells = nn.ModuleList()
+ for index, (C_curr, reduction) in enumerate(
+ zip(layer_channels, layer_reductions)
+ ):
+ cell = SearchCell(
+ search_space,
+ steps,
+ multiplier,
+ C_prev_prev,
+ C_prev,
+ C_curr,
+ reduction,
+ reduction_prev,
+ affine,
+ track_running_stats,
+ )
+ if num_edge is None:
+ num_edge, edge2index = cell.num_edges, cell.edge2index
+ else:
+ assert (
+ num_edge == cell.num_edges and edge2index == cell.edge2index
+ ), "invalid {:} vs. {:}.".format(num_edge, cell.num_edges)
+ self.cells.append(cell)
+ C_prev_prev, C_prev, reduction_prev = C_prev, multiplier * C_curr, reduction
+ self.op_names = deepcopy(search_space)
+ self._Layer = len(self.cells)
+ self.edge2index = edge2index
+ self.lastact = nn.Sequential(nn.BatchNorm2d(C_prev), nn.ReLU(inplace=True))
+ self.global_pooling = nn.AdaptiveAvgPool2d(1)
+ self.classifier = nn.Linear(C_prev, num_classes)
+ self.arch_normal_parameters = nn.Parameter(
+ 1e-3 * torch.randn(num_edge, len(search_space))
+ )
+ self.arch_reduce_parameters = nn.Parameter(
+ 1e-3 * torch.randn(num_edge, len(search_space))
+ )
+ self.mode = "urs"
+ self.dynamic_cell = None
+
+ def set_cal_mode(self, mode, dynamic_cell=None):
+ assert mode in ["urs", "joint", "select", "dynamic"]
+ self.mode = mode
+ if mode == "dynamic":
+ self.dynamic_cell = deepcopy(dynamic_cell)
+ else:
+ self.dynamic_cell = None
+
+ def get_weights(self):
+ xlist = list(self.stem.parameters()) + list(self.cells.parameters())
+ xlist += list(self.lastact.parameters()) + list(
+ self.global_pooling.parameters()
+ )
+ xlist += list(self.classifier.parameters())
+ return xlist
+
+ def get_alphas(self):
+ return [self.arch_normal_parameters, self.arch_reduce_parameters]
+
+ def show_alphas(self):
+ with torch.no_grad():
+ A = "arch-normal-parameters :\n{:}".format(
+ nn.functional.softmax(self.arch_normal_parameters, dim=-1).cpu()
+ )
+ B = "arch-reduce-parameters :\n{:}".format(
+ nn.functional.softmax(self.arch_reduce_parameters, dim=-1).cpu()
+ )
+ return "{:}\n{:}".format(A, B)
+
+ def get_message(self):
+ string = self.extra_repr()
+ for i, cell in enumerate(self.cells):
+ string += "\n {:02d}/{:02d} :: {:}".format(
+ i, len(self.cells), cell.extra_repr()
+ )
+ return string
+
+ def extra_repr(self):
+ return "{name}(C={_C}, N={_layerN}, steps={_steps}, multiplier={_multiplier}, L={_Layer})".format(
+ name=self.__class__.__name__, **self.__dict__
+ )
+
+ def dync_genotype(self, use_random=False):
+ genotypes = []
+ with torch.no_grad():
+ alphas_cpu = nn.functional.softmax(self.arch_parameters, dim=-1)
+ for i in range(1, self.max_nodes):
+ xlist = []
+ for j in range(i):
+ node_str = "{:}<-{:}".format(i, j)
+ if use_random:
+ op_name = random.choice(self.op_names)
+ else:
+ weights = alphas_cpu[self.edge2index[node_str]]
+ op_index = torch.multinomial(weights, 1).item()
+ op_name = self.op_names[op_index]
+ xlist.append((op_name, j))
+ genotypes.append(tuple(xlist))
+ return Structure(genotypes)
+
+ def genotype(self):
+ def _parse(weights):
+ gene = []
+ for i in range(self._steps):
+ edges = []
+ for j in range(2 + i):
+ node_str = "{:}<-{:}".format(i, j)
+ ws = weights[self.edge2index[node_str]]
+ for k, op_name in enumerate(self.op_names):
+ if op_name == "none":
+ continue
+ edges.append((op_name, j, ws[k]))
+ edges = sorted(edges, key=lambda x: -x[-1])
+ selected_edges = edges[:2]
+ gene.append(tuple(selected_edges))
+ return gene
+
+ with torch.no_grad():
+ gene_normal = _parse(
+ torch.softmax(self.arch_normal_parameters, dim=-1).cpu().numpy()
+ )
+ gene_reduce = _parse(
+ torch.softmax(self.arch_reduce_parameters, dim=-1).cpu().numpy()
+ )
+ return {
+ "normal": gene_normal,
+ "normal_concat": list(
+ range(2 + self._steps - self._multiplier, self._steps + 2)
+ ),
+ "reduce": gene_reduce,
+ "reduce_concat": list(
+ range(2 + self._steps - self._multiplier, self._steps + 2)
+ ),
+ }
+
+ def forward(self, inputs):
+ normal_hardwts = nn.functional.softmax(self.arch_normal_parameters, dim=-1)
+ reduce_hardwts = nn.functional.softmax(self.arch_reduce_parameters, dim=-1)
+
+ s0 = s1 = self.stem(inputs)
+ for i, cell in enumerate(self.cells):
+ # [TODO]
+ raise NotImplementedError
+ if cell.reduction:
+ hardwts, index = reduce_hardwts, reduce_index
+ else:
+ hardwts, index = normal_hardwts, normal_index
+ s0, s1 = s1, cell.forward_gdas(s0, s1, hardwts, index)
+ out = self.lastact(s1)
+ out = self.global_pooling(out)
+ out = out.view(out.size(0), -1)
+ logits = self.classifier(out)
+
+ return out, logits
diff --git a/AutoDL-Projects/xautodl/models/clone_weights.py b/AutoDL-Projects/xautodl/models/clone_weights.py
new file mode 100644
index 0000000..9e904ac
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/clone_weights.py
@@ -0,0 +1,74 @@
+import torch
+import torch.nn as nn
+
+
+def copy_conv(module, init):
+ assert isinstance(module, nn.Conv2d), "invalid module : {:}".format(module)
+ assert isinstance(init, nn.Conv2d), "invalid module : {:}".format(init)
+ new_i, new_o = module.in_channels, module.out_channels
+ module.weight.copy_(init.weight.detach()[:new_o, :new_i])
+ if module.bias is not None:
+ module.bias.copy_(init.bias.detach()[:new_o])
+
+
+def copy_bn(module, init):
+ assert isinstance(module, nn.BatchNorm2d), "invalid module : {:}".format(module)
+ assert isinstance(init, nn.BatchNorm2d), "invalid module : {:}".format(init)
+ num_features = module.num_features
+ if module.weight is not None:
+ module.weight.copy_(init.weight.detach()[:num_features])
+ if module.bias is not None:
+ module.bias.copy_(init.bias.detach()[:num_features])
+ if module.running_mean is not None:
+ module.running_mean.copy_(init.running_mean.detach()[:num_features])
+ if module.running_var is not None:
+ module.running_var.copy_(init.running_var.detach()[:num_features])
+
+
+def copy_fc(module, init):
+ assert isinstance(module, nn.Linear), "invalid module : {:}".format(module)
+ assert isinstance(init, nn.Linear), "invalid module : {:}".format(init)
+ new_i, new_o = module.in_features, module.out_features
+ module.weight.copy_(init.weight.detach()[:new_o, :new_i])
+ if module.bias is not None:
+ module.bias.copy_(init.bias.detach()[:new_o])
+
+
+def copy_base(module, init):
+ assert type(module).__name__ in [
+ "ConvBNReLU",
+ "Downsample",
+ ], "invalid module : {:}".format(module)
+ assert type(init).__name__ in [
+ "ConvBNReLU",
+ "Downsample",
+ ], "invalid module : {:}".format(init)
+ if module.conv is not None:
+ copy_conv(module.conv, init.conv)
+ if module.bn is not None:
+ copy_bn(module.bn, init.bn)
+
+
+def copy_basic(module, init):
+ copy_base(module.conv_a, init.conv_a)
+ copy_base(module.conv_b, init.conv_b)
+ if module.downsample is not None:
+ if init.downsample is not None:
+ copy_base(module.downsample, init.downsample)
+ # else:
+ # import pdb; pdb.set_trace()
+
+
+def init_from_model(network, init_model):
+ with torch.no_grad():
+ copy_fc(network.classifier, init_model.classifier)
+ for base, target in zip(init_model.layers, network.layers):
+ assert (
+ type(base).__name__ == type(target).__name__
+ ), "invalid type : {:} vs {:}".format(base, target)
+ if type(base).__name__ == "ConvBNReLU":
+ copy_base(target, base)
+ elif type(base).__name__ == "ResNetBasicblock":
+ copy_basic(target, base)
+ else:
+ raise ValueError("unknown type name : {:}".format(type(base).__name__))
diff --git a/AutoDL-Projects/xautodl/models/initialization.py b/AutoDL-Projects/xautodl/models/initialization.py
new file mode 100644
index 0000000..e82d723
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/initialization.py
@@ -0,0 +1,16 @@
+import torch
+import torch.nn as nn
+
+
+def initialize_resnet(m):
+ if isinstance(m, nn.Conv2d):
+ nn.init.kaiming_normal_(m.weight, mode="fan_out", nonlinearity="relu")
+ if m.bias is not None:
+ nn.init.constant_(m.bias, 0)
+ elif isinstance(m, nn.BatchNorm2d):
+ nn.init.constant_(m.weight, 1)
+ if m.bias is not None:
+ nn.init.constant_(m.bias, 0)
+ elif isinstance(m, nn.Linear):
+ nn.init.normal_(m.weight, 0, 0.01)
+ nn.init.constant_(m.bias, 0)
diff --git a/AutoDL-Projects/xautodl/models/shape_infers/InferCifarResNet.py b/AutoDL-Projects/xautodl/models/shape_infers/InferCifarResNet.py
new file mode 100644
index 0000000..1731392
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/shape_infers/InferCifarResNet.py
@@ -0,0 +1,287 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.01 #
+#####################################################
+import torch.nn as nn
+import torch.nn.functional as F
+
+from ..initialization import initialize_resnet
+
+
+class ConvBNReLU(nn.Module):
+ def __init__(
+ self, nIn, nOut, kernel, stride, padding, bias, has_avg, has_bn, has_relu
+ ):
+ super(ConvBNReLU, self).__init__()
+ if has_avg:
+ self.avg = nn.AvgPool2d(kernel_size=2, stride=2, padding=0)
+ else:
+ self.avg = None
+ self.conv = nn.Conv2d(
+ nIn,
+ nOut,
+ kernel_size=kernel,
+ stride=stride,
+ padding=padding,
+ dilation=1,
+ groups=1,
+ bias=bias,
+ )
+ if has_bn:
+ self.bn = nn.BatchNorm2d(nOut)
+ else:
+ self.bn = None
+ if has_relu:
+ self.relu = nn.ReLU(inplace=True)
+ else:
+ self.relu = None
+
+ def forward(self, inputs):
+ if self.avg:
+ out = self.avg(inputs)
+ else:
+ out = inputs
+ conv = self.conv(out)
+ if self.bn:
+ out = self.bn(conv)
+ else:
+ out = conv
+ if self.relu:
+ out = self.relu(out)
+ else:
+ out = out
+
+ return out
+
+
+class ResNetBasicblock(nn.Module):
+ num_conv = 2
+ expansion = 1
+
+ def __init__(self, iCs, stride):
+ super(ResNetBasicblock, self).__init__()
+ assert stride == 1 or stride == 2, "invalid stride {:}".format(stride)
+ assert isinstance(iCs, tuple) or isinstance(
+ iCs, list
+ ), "invalid type of iCs : {:}".format(iCs)
+ assert len(iCs) == 3, "invalid lengths of iCs : {:}".format(iCs)
+
+ self.conv_a = ConvBNReLU(
+ iCs[0],
+ iCs[1],
+ 3,
+ stride,
+ 1,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=True,
+ )
+ self.conv_b = ConvBNReLU(
+ iCs[1], iCs[2], 3, 1, 1, False, has_avg=False, has_bn=True, has_relu=False
+ )
+ residual_in = iCs[0]
+ if stride == 2:
+ self.downsample = ConvBNReLU(
+ iCs[0],
+ iCs[2],
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=True,
+ has_bn=False,
+ has_relu=False,
+ )
+ residual_in = iCs[2]
+ elif iCs[0] != iCs[2]:
+ self.downsample = ConvBNReLU(
+ iCs[0],
+ iCs[2],
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=False,
+ )
+ else:
+ self.downsample = None
+ # self.out_dim = max(residual_in, iCs[2])
+ self.out_dim = iCs[2]
+
+ def forward(self, inputs):
+ basicblock = self.conv_a(inputs)
+ basicblock = self.conv_b(basicblock)
+
+ if self.downsample is not None:
+ residual = self.downsample(inputs)
+ else:
+ residual = inputs
+ out = residual + basicblock
+ return F.relu(out, inplace=True)
+
+
+class ResNetBottleneck(nn.Module):
+ expansion = 4
+ num_conv = 3
+
+ def __init__(self, iCs, stride):
+ super(ResNetBottleneck, self).__init__()
+ assert stride == 1 or stride == 2, "invalid stride {:}".format(stride)
+ assert isinstance(iCs, tuple) or isinstance(
+ iCs, list
+ ), "invalid type of iCs : {:}".format(iCs)
+ assert len(iCs) == 4, "invalid lengths of iCs : {:}".format(iCs)
+ self.conv_1x1 = ConvBNReLU(
+ iCs[0], iCs[1], 1, 1, 0, False, has_avg=False, has_bn=True, has_relu=True
+ )
+ self.conv_3x3 = ConvBNReLU(
+ iCs[1],
+ iCs[2],
+ 3,
+ stride,
+ 1,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=True,
+ )
+ self.conv_1x4 = ConvBNReLU(
+ iCs[2], iCs[3], 1, 1, 0, False, has_avg=False, has_bn=True, has_relu=False
+ )
+ residual_in = iCs[0]
+ if stride == 2:
+ self.downsample = ConvBNReLU(
+ iCs[0],
+ iCs[3],
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=True,
+ has_bn=False,
+ has_relu=False,
+ )
+ residual_in = iCs[3]
+ elif iCs[0] != iCs[3]:
+ self.downsample = ConvBNReLU(
+ iCs[0],
+ iCs[3],
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=False,
+ has_bn=False,
+ has_relu=False,
+ )
+ residual_in = iCs[3]
+ else:
+ self.downsample = None
+ # self.out_dim = max(residual_in, iCs[3])
+ self.out_dim = iCs[3]
+
+ def forward(self, inputs):
+
+ bottleneck = self.conv_1x1(inputs)
+ bottleneck = self.conv_3x3(bottleneck)
+ bottleneck = self.conv_1x4(bottleneck)
+
+ if self.downsample is not None:
+ residual = self.downsample(inputs)
+ else:
+ residual = inputs
+ out = residual + bottleneck
+ return F.relu(out, inplace=True)
+
+
+class InferCifarResNet(nn.Module):
+ def __init__(
+ self, block_name, depth, xblocks, xchannels, num_classes, zero_init_residual
+ ):
+ super(InferCifarResNet, self).__init__()
+
+ # Model type specifies number of layers for CIFAR-10 and CIFAR-100 model
+ if block_name == "ResNetBasicblock":
+ block = ResNetBasicblock
+ assert (depth - 2) % 6 == 0, "depth should be one of 20, 32, 44, 56, 110"
+ layer_blocks = (depth - 2) // 6
+ elif block_name == "ResNetBottleneck":
+ block = ResNetBottleneck
+ assert (depth - 2) % 9 == 0, "depth should be one of 164"
+ layer_blocks = (depth - 2) // 9
+ else:
+ raise ValueError("invalid block : {:}".format(block_name))
+ assert len(xblocks) == 3, "invalid xblocks : {:}".format(xblocks)
+
+ self.message = (
+ "InferWidthCifarResNet : Depth : {:} , Layers for each block : {:}".format(
+ depth, layer_blocks
+ )
+ )
+ self.num_classes = num_classes
+ self.xchannels = xchannels
+ self.layers = nn.ModuleList(
+ [
+ ConvBNReLU(
+ xchannels[0],
+ xchannels[1],
+ 3,
+ 1,
+ 1,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=True,
+ )
+ ]
+ )
+ last_channel_idx = 1
+ for stage in range(3):
+ for iL in range(layer_blocks):
+ num_conv = block.num_conv
+ iCs = self.xchannels[last_channel_idx : last_channel_idx + num_conv + 1]
+ stride = 2 if stage > 0 and iL == 0 else 1
+ module = block(iCs, stride)
+ last_channel_idx += num_conv
+ self.xchannels[last_channel_idx] = module.out_dim
+ self.layers.append(module)
+ self.message += "\nstage={:}, ilayer={:02d}/{:02d}, block={:03d}, iCs={:}, oC={:3d}, stride={:}".format(
+ stage,
+ iL,
+ layer_blocks,
+ len(self.layers) - 1,
+ iCs,
+ module.out_dim,
+ stride,
+ )
+ if iL + 1 == xblocks[stage]: # reach the maximum depth
+ out_channel = module.out_dim
+ for iiL in range(iL + 1, layer_blocks):
+ last_channel_idx += num_conv
+ self.xchannels[last_channel_idx] = module.out_dim
+ break
+
+ self.avgpool = nn.AvgPool2d(8)
+ self.classifier = nn.Linear(self.xchannels[-1], num_classes)
+
+ self.apply(initialize_resnet)
+ if zero_init_residual:
+ for m in self.modules():
+ if isinstance(m, ResNetBasicblock):
+ nn.init.constant_(m.conv_b.bn.weight, 0)
+ elif isinstance(m, ResNetBottleneck):
+ nn.init.constant_(m.conv_1x4.bn.weight, 0)
+
+ def get_message(self):
+ return self.message
+
+ def forward(self, inputs):
+ x = inputs
+ for i, layer in enumerate(self.layers):
+ x = layer(x)
+ features = self.avgpool(x)
+ features = features.view(features.size(0), -1)
+ logits = self.classifier(features)
+ return features, logits
diff --git a/AutoDL-Projects/xautodl/models/shape_infers/InferCifarResNet_depth.py b/AutoDL-Projects/xautodl/models/shape_infers/InferCifarResNet_depth.py
new file mode 100644
index 0000000..c6f9bb3
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/shape_infers/InferCifarResNet_depth.py
@@ -0,0 +1,263 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.01 #
+#####################################################
+import torch.nn as nn
+import torch.nn.functional as F
+from ..initialization import initialize_resnet
+
+
+class ConvBNReLU(nn.Module):
+ def __init__(
+ self, nIn, nOut, kernel, stride, padding, bias, has_avg, has_bn, has_relu
+ ):
+ super(ConvBNReLU, self).__init__()
+ if has_avg:
+ self.avg = nn.AvgPool2d(kernel_size=2, stride=2, padding=0)
+ else:
+ self.avg = None
+ self.conv = nn.Conv2d(
+ nIn,
+ nOut,
+ kernel_size=kernel,
+ stride=stride,
+ padding=padding,
+ dilation=1,
+ groups=1,
+ bias=bias,
+ )
+ if has_bn:
+ self.bn = nn.BatchNorm2d(nOut)
+ else:
+ self.bn = None
+ if has_relu:
+ self.relu = nn.ReLU(inplace=True)
+ else:
+ self.relu = None
+
+ def forward(self, inputs):
+ if self.avg:
+ out = self.avg(inputs)
+ else:
+ out = inputs
+ conv = self.conv(out)
+ if self.bn:
+ out = self.bn(conv)
+ else:
+ out = conv
+ if self.relu:
+ out = self.relu(out)
+ else:
+ out = out
+
+ return out
+
+
+class ResNetBasicblock(nn.Module):
+ num_conv = 2
+ expansion = 1
+
+ def __init__(self, inplanes, planes, stride):
+ super(ResNetBasicblock, self).__init__()
+ assert stride == 1 or stride == 2, "invalid stride {:}".format(stride)
+
+ self.conv_a = ConvBNReLU(
+ inplanes,
+ planes,
+ 3,
+ stride,
+ 1,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=True,
+ )
+ self.conv_b = ConvBNReLU(
+ planes, planes, 3, 1, 1, False, has_avg=False, has_bn=True, has_relu=False
+ )
+ if stride == 2:
+ self.downsample = ConvBNReLU(
+ inplanes,
+ planes,
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=True,
+ has_bn=False,
+ has_relu=False,
+ )
+ elif inplanes != planes:
+ self.downsample = ConvBNReLU(
+ inplanes,
+ planes,
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=False,
+ )
+ else:
+ self.downsample = None
+ self.out_dim = planes
+
+ def forward(self, inputs):
+ basicblock = self.conv_a(inputs)
+ basicblock = self.conv_b(basicblock)
+
+ if self.downsample is not None:
+ residual = self.downsample(inputs)
+ else:
+ residual = inputs
+ out = residual + basicblock
+ return F.relu(out, inplace=True)
+
+
+class ResNetBottleneck(nn.Module):
+ expansion = 4
+ num_conv = 3
+
+ def __init__(self, inplanes, planes, stride):
+ super(ResNetBottleneck, self).__init__()
+ assert stride == 1 or stride == 2, "invalid stride {:}".format(stride)
+ self.conv_1x1 = ConvBNReLU(
+ inplanes, planes, 1, 1, 0, False, has_avg=False, has_bn=True, has_relu=True
+ )
+ self.conv_3x3 = ConvBNReLU(
+ planes,
+ planes,
+ 3,
+ stride,
+ 1,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=True,
+ )
+ self.conv_1x4 = ConvBNReLU(
+ planes,
+ planes * self.expansion,
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=False,
+ )
+ if stride == 2:
+ self.downsample = ConvBNReLU(
+ inplanes,
+ planes * self.expansion,
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=True,
+ has_bn=False,
+ has_relu=False,
+ )
+ elif inplanes != planes * self.expansion:
+ self.downsample = ConvBNReLU(
+ inplanes,
+ planes * self.expansion,
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=False,
+ has_bn=False,
+ has_relu=False,
+ )
+ else:
+ self.downsample = None
+ self.out_dim = planes * self.expansion
+
+ def forward(self, inputs):
+
+ bottleneck = self.conv_1x1(inputs)
+ bottleneck = self.conv_3x3(bottleneck)
+ bottleneck = self.conv_1x4(bottleneck)
+
+ if self.downsample is not None:
+ residual = self.downsample(inputs)
+ else:
+ residual = inputs
+ out = residual + bottleneck
+ return F.relu(out, inplace=True)
+
+
+class InferDepthCifarResNet(nn.Module):
+ def __init__(self, block_name, depth, xblocks, num_classes, zero_init_residual):
+ super(InferDepthCifarResNet, self).__init__()
+
+ # Model type specifies number of layers for CIFAR-10 and CIFAR-100 model
+ if block_name == "ResNetBasicblock":
+ block = ResNetBasicblock
+ assert (depth - 2) % 6 == 0, "depth should be one of 20, 32, 44, 56, 110"
+ layer_blocks = (depth - 2) // 6
+ elif block_name == "ResNetBottleneck":
+ block = ResNetBottleneck
+ assert (depth - 2) % 9 == 0, "depth should be one of 164"
+ layer_blocks = (depth - 2) // 9
+ else:
+ raise ValueError("invalid block : {:}".format(block_name))
+ assert len(xblocks) == 3, "invalid xblocks : {:}".format(xblocks)
+
+ self.message = (
+ "InferWidthCifarResNet : Depth : {:} , Layers for each block : {:}".format(
+ depth, layer_blocks
+ )
+ )
+ self.num_classes = num_classes
+ self.layers = nn.ModuleList(
+ [
+ ConvBNReLU(
+ 3, 16, 3, 1, 1, False, has_avg=False, has_bn=True, has_relu=True
+ )
+ ]
+ )
+ self.channels = [16]
+ for stage in range(3):
+ for iL in range(layer_blocks):
+ iC = self.channels[-1]
+ planes = 16 * (2 ** stage)
+ stride = 2 if stage > 0 and iL == 0 else 1
+ module = block(iC, planes, stride)
+ self.channels.append(module.out_dim)
+ self.layers.append(module)
+ self.message += "\nstage={:}, ilayer={:02d}/{:02d}, block={:03d}, iC={:}, oC={:3d}, stride={:}".format(
+ stage,
+ iL,
+ layer_blocks,
+ len(self.layers) - 1,
+ planes,
+ module.out_dim,
+ stride,
+ )
+ if iL + 1 == xblocks[stage]: # reach the maximum depth
+ break
+
+ self.avgpool = nn.AvgPool2d(8)
+ self.classifier = nn.Linear(self.channels[-1], num_classes)
+
+ self.apply(initialize_resnet)
+ if zero_init_residual:
+ for m in self.modules():
+ if isinstance(m, ResNetBasicblock):
+ nn.init.constant_(m.conv_b.bn.weight, 0)
+ elif isinstance(m, ResNetBottleneck):
+ nn.init.constant_(m.conv_1x4.bn.weight, 0)
+
+ def get_message(self):
+ return self.message
+
+ def forward(self, inputs):
+ x = inputs
+ for i, layer in enumerate(self.layers):
+ x = layer(x)
+ features = self.avgpool(x)
+ features = features.view(features.size(0), -1)
+ logits = self.classifier(features)
+ return features, logits
diff --git a/AutoDL-Projects/xautodl/models/shape_infers/InferCifarResNet_width.py b/AutoDL-Projects/xautodl/models/shape_infers/InferCifarResNet_width.py
new file mode 100644
index 0000000..9400f71
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/shape_infers/InferCifarResNet_width.py
@@ -0,0 +1,277 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.01 #
+#####################################################
+import torch.nn as nn
+import torch.nn.functional as F
+from ..initialization import initialize_resnet
+
+
+class ConvBNReLU(nn.Module):
+ def __init__(
+ self, nIn, nOut, kernel, stride, padding, bias, has_avg, has_bn, has_relu
+ ):
+ super(ConvBNReLU, self).__init__()
+ if has_avg:
+ self.avg = nn.AvgPool2d(kernel_size=2, stride=2, padding=0)
+ else:
+ self.avg = None
+ self.conv = nn.Conv2d(
+ nIn,
+ nOut,
+ kernel_size=kernel,
+ stride=stride,
+ padding=padding,
+ dilation=1,
+ groups=1,
+ bias=bias,
+ )
+ if has_bn:
+ self.bn = nn.BatchNorm2d(nOut)
+ else:
+ self.bn = None
+ if has_relu:
+ self.relu = nn.ReLU(inplace=True)
+ else:
+ self.relu = None
+
+ def forward(self, inputs):
+ if self.avg:
+ out = self.avg(inputs)
+ else:
+ out = inputs
+ conv = self.conv(out)
+ if self.bn:
+ out = self.bn(conv)
+ else:
+ out = conv
+ if self.relu:
+ out = self.relu(out)
+ else:
+ out = out
+
+ return out
+
+
+class ResNetBasicblock(nn.Module):
+ num_conv = 2
+ expansion = 1
+
+ def __init__(self, iCs, stride):
+ super(ResNetBasicblock, self).__init__()
+ assert stride == 1 or stride == 2, "invalid stride {:}".format(stride)
+ assert isinstance(iCs, tuple) or isinstance(
+ iCs, list
+ ), "invalid type of iCs : {:}".format(iCs)
+ assert len(iCs) == 3, "invalid lengths of iCs : {:}".format(iCs)
+
+ self.conv_a = ConvBNReLU(
+ iCs[0],
+ iCs[1],
+ 3,
+ stride,
+ 1,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=True,
+ )
+ self.conv_b = ConvBNReLU(
+ iCs[1], iCs[2], 3, 1, 1, False, has_avg=False, has_bn=True, has_relu=False
+ )
+ residual_in = iCs[0]
+ if stride == 2:
+ self.downsample = ConvBNReLU(
+ iCs[0],
+ iCs[2],
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=True,
+ has_bn=False,
+ has_relu=False,
+ )
+ residual_in = iCs[2]
+ elif iCs[0] != iCs[2]:
+ self.downsample = ConvBNReLU(
+ iCs[0],
+ iCs[2],
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=False,
+ )
+ else:
+ self.downsample = None
+ # self.out_dim = max(residual_in, iCs[2])
+ self.out_dim = iCs[2]
+
+ def forward(self, inputs):
+ basicblock = self.conv_a(inputs)
+ basicblock = self.conv_b(basicblock)
+
+ if self.downsample is not None:
+ residual = self.downsample(inputs)
+ else:
+ residual = inputs
+ out = residual + basicblock
+ return F.relu(out, inplace=True)
+
+
+class ResNetBottleneck(nn.Module):
+ expansion = 4
+ num_conv = 3
+
+ def __init__(self, iCs, stride):
+ super(ResNetBottleneck, self).__init__()
+ assert stride == 1 or stride == 2, "invalid stride {:}".format(stride)
+ assert isinstance(iCs, tuple) or isinstance(
+ iCs, list
+ ), "invalid type of iCs : {:}".format(iCs)
+ assert len(iCs) == 4, "invalid lengths of iCs : {:}".format(iCs)
+ self.conv_1x1 = ConvBNReLU(
+ iCs[0], iCs[1], 1, 1, 0, False, has_avg=False, has_bn=True, has_relu=True
+ )
+ self.conv_3x3 = ConvBNReLU(
+ iCs[1],
+ iCs[2],
+ 3,
+ stride,
+ 1,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=True,
+ )
+ self.conv_1x4 = ConvBNReLU(
+ iCs[2], iCs[3], 1, 1, 0, False, has_avg=False, has_bn=True, has_relu=False
+ )
+ residual_in = iCs[0]
+ if stride == 2:
+ self.downsample = ConvBNReLU(
+ iCs[0],
+ iCs[3],
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=True,
+ has_bn=False,
+ has_relu=False,
+ )
+ residual_in = iCs[3]
+ elif iCs[0] != iCs[3]:
+ self.downsample = ConvBNReLU(
+ iCs[0],
+ iCs[3],
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=False,
+ has_bn=False,
+ has_relu=False,
+ )
+ residual_in = iCs[3]
+ else:
+ self.downsample = None
+ # self.out_dim = max(residual_in, iCs[3])
+ self.out_dim = iCs[3]
+
+ def forward(self, inputs):
+
+ bottleneck = self.conv_1x1(inputs)
+ bottleneck = self.conv_3x3(bottleneck)
+ bottleneck = self.conv_1x4(bottleneck)
+
+ if self.downsample is not None:
+ residual = self.downsample(inputs)
+ else:
+ residual = inputs
+ out = residual + bottleneck
+ return F.relu(out, inplace=True)
+
+
+class InferWidthCifarResNet(nn.Module):
+ def __init__(self, block_name, depth, xchannels, num_classes, zero_init_residual):
+ super(InferWidthCifarResNet, self).__init__()
+
+ # Model type specifies number of layers for CIFAR-10 and CIFAR-100 model
+ if block_name == "ResNetBasicblock":
+ block = ResNetBasicblock
+ assert (depth - 2) % 6 == 0, "depth should be one of 20, 32, 44, 56, 110"
+ layer_blocks = (depth - 2) // 6
+ elif block_name == "ResNetBottleneck":
+ block = ResNetBottleneck
+ assert (depth - 2) % 9 == 0, "depth should be one of 164"
+ layer_blocks = (depth - 2) // 9
+ else:
+ raise ValueError("invalid block : {:}".format(block_name))
+
+ self.message = (
+ "InferWidthCifarResNet : Depth : {:} , Layers for each block : {:}".format(
+ depth, layer_blocks
+ )
+ )
+ self.num_classes = num_classes
+ self.xchannels = xchannels
+ self.layers = nn.ModuleList(
+ [
+ ConvBNReLU(
+ xchannels[0],
+ xchannels[1],
+ 3,
+ 1,
+ 1,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=True,
+ )
+ ]
+ )
+ last_channel_idx = 1
+ for stage in range(3):
+ for iL in range(layer_blocks):
+ num_conv = block.num_conv
+ iCs = self.xchannels[last_channel_idx : last_channel_idx + num_conv + 1]
+ stride = 2 if stage > 0 and iL == 0 else 1
+ module = block(iCs, stride)
+ last_channel_idx += num_conv
+ self.xchannels[last_channel_idx] = module.out_dim
+ self.layers.append(module)
+ self.message += "\nstage={:}, ilayer={:02d}/{:02d}, block={:03d}, iCs={:}, oC={:3d}, stride={:}".format(
+ stage,
+ iL,
+ layer_blocks,
+ len(self.layers) - 1,
+ iCs,
+ module.out_dim,
+ stride,
+ )
+
+ self.avgpool = nn.AvgPool2d(8)
+ self.classifier = nn.Linear(self.xchannels[-1], num_classes)
+
+ self.apply(initialize_resnet)
+ if zero_init_residual:
+ for m in self.modules():
+ if isinstance(m, ResNetBasicblock):
+ nn.init.constant_(m.conv_b.bn.weight, 0)
+ elif isinstance(m, ResNetBottleneck):
+ nn.init.constant_(m.conv_1x4.bn.weight, 0)
+
+ def get_message(self):
+ return self.message
+
+ def forward(self, inputs):
+ x = inputs
+ for i, layer in enumerate(self.layers):
+ x = layer(x)
+ features = self.avgpool(x)
+ features = features.view(features.size(0), -1)
+ logits = self.classifier(features)
+ return features, logits
diff --git a/AutoDL-Projects/xautodl/models/shape_infers/InferImagenetResNet.py b/AutoDL-Projects/xautodl/models/shape_infers/InferImagenetResNet.py
new file mode 100644
index 0000000..0415e58
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/shape_infers/InferImagenetResNet.py
@@ -0,0 +1,324 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.01 #
+#####################################################
+import torch.nn as nn
+import torch.nn.functional as F
+from ..initialization import initialize_resnet
+
+
+class ConvBNReLU(nn.Module):
+
+ num_conv = 1
+
+ def __init__(
+ self, nIn, nOut, kernel, stride, padding, bias, has_avg, has_bn, has_relu
+ ):
+ super(ConvBNReLU, self).__init__()
+ if has_avg:
+ self.avg = nn.AvgPool2d(kernel_size=2, stride=2, padding=0)
+ else:
+ self.avg = None
+ self.conv = nn.Conv2d(
+ nIn,
+ nOut,
+ kernel_size=kernel,
+ stride=stride,
+ padding=padding,
+ dilation=1,
+ groups=1,
+ bias=bias,
+ )
+ if has_bn:
+ self.bn = nn.BatchNorm2d(nOut)
+ else:
+ self.bn = None
+ if has_relu:
+ self.relu = nn.ReLU(inplace=True)
+ else:
+ self.relu = None
+
+ def forward(self, inputs):
+ if self.avg:
+ out = self.avg(inputs)
+ else:
+ out = inputs
+ conv = self.conv(out)
+ if self.bn:
+ out = self.bn(conv)
+ else:
+ out = conv
+ if self.relu:
+ out = self.relu(out)
+ else:
+ out = out
+
+ return out
+
+
+class ResNetBasicblock(nn.Module):
+ num_conv = 2
+ expansion = 1
+
+ def __init__(self, iCs, stride):
+ super(ResNetBasicblock, self).__init__()
+ assert stride == 1 or stride == 2, "invalid stride {:}".format(stride)
+ assert isinstance(iCs, tuple) or isinstance(
+ iCs, list
+ ), "invalid type of iCs : {:}".format(iCs)
+ assert len(iCs) == 3, "invalid lengths of iCs : {:}".format(iCs)
+
+ self.conv_a = ConvBNReLU(
+ iCs[0],
+ iCs[1],
+ 3,
+ stride,
+ 1,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=True,
+ )
+ self.conv_b = ConvBNReLU(
+ iCs[1], iCs[2], 3, 1, 1, False, has_avg=False, has_bn=True, has_relu=False
+ )
+ residual_in = iCs[0]
+ if stride == 2:
+ self.downsample = ConvBNReLU(
+ iCs[0],
+ iCs[2],
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=True,
+ has_bn=True,
+ has_relu=False,
+ )
+ residual_in = iCs[2]
+ elif iCs[0] != iCs[2]:
+ self.downsample = ConvBNReLU(
+ iCs[0],
+ iCs[2],
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=False,
+ )
+ else:
+ self.downsample = None
+ # self.out_dim = max(residual_in, iCs[2])
+ self.out_dim = iCs[2]
+
+ def forward(self, inputs):
+ basicblock = self.conv_a(inputs)
+ basicblock = self.conv_b(basicblock)
+
+ if self.downsample is not None:
+ residual = self.downsample(inputs)
+ else:
+ residual = inputs
+ out = residual + basicblock
+ return F.relu(out, inplace=True)
+
+
+class ResNetBottleneck(nn.Module):
+ expansion = 4
+ num_conv = 3
+
+ def __init__(self, iCs, stride):
+ super(ResNetBottleneck, self).__init__()
+ assert stride == 1 or stride == 2, "invalid stride {:}".format(stride)
+ assert isinstance(iCs, tuple) or isinstance(
+ iCs, list
+ ), "invalid type of iCs : {:}".format(iCs)
+ assert len(iCs) == 4, "invalid lengths of iCs : {:}".format(iCs)
+ self.conv_1x1 = ConvBNReLU(
+ iCs[0], iCs[1], 1, 1, 0, False, has_avg=False, has_bn=True, has_relu=True
+ )
+ self.conv_3x3 = ConvBNReLU(
+ iCs[1],
+ iCs[2],
+ 3,
+ stride,
+ 1,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=True,
+ )
+ self.conv_1x4 = ConvBNReLU(
+ iCs[2], iCs[3], 1, 1, 0, False, has_avg=False, has_bn=True, has_relu=False
+ )
+ residual_in = iCs[0]
+ if stride == 2:
+ self.downsample = ConvBNReLU(
+ iCs[0],
+ iCs[3],
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=True,
+ has_bn=True,
+ has_relu=False,
+ )
+ residual_in = iCs[3]
+ elif iCs[0] != iCs[3]:
+ self.downsample = ConvBNReLU(
+ iCs[0],
+ iCs[3],
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=False,
+ )
+ residual_in = iCs[3]
+ else:
+ self.downsample = None
+ # self.out_dim = max(residual_in, iCs[3])
+ self.out_dim = iCs[3]
+
+ def forward(self, inputs):
+
+ bottleneck = self.conv_1x1(inputs)
+ bottleneck = self.conv_3x3(bottleneck)
+ bottleneck = self.conv_1x4(bottleneck)
+
+ if self.downsample is not None:
+ residual = self.downsample(inputs)
+ else:
+ residual = inputs
+ out = residual + bottleneck
+ return F.relu(out, inplace=True)
+
+
+class InferImagenetResNet(nn.Module):
+ def __init__(
+ self,
+ block_name,
+ layers,
+ xblocks,
+ xchannels,
+ deep_stem,
+ num_classes,
+ zero_init_residual,
+ ):
+ super(InferImagenetResNet, self).__init__()
+
+ # Model type specifies number of layers for CIFAR-10 and CIFAR-100 model
+ if block_name == "BasicBlock":
+ block = ResNetBasicblock
+ elif block_name == "Bottleneck":
+ block = ResNetBottleneck
+ else:
+ raise ValueError("invalid block : {:}".format(block_name))
+ assert len(xblocks) == len(
+ layers
+ ), "invalid layers : {:} vs xblocks : {:}".format(layers, xblocks)
+
+ self.message = "InferImagenetResNet : Depth : {:} -> {:}, Layers for each block : {:}".format(
+ sum(layers) * block.num_conv, sum(xblocks) * block.num_conv, xblocks
+ )
+ self.num_classes = num_classes
+ self.xchannels = xchannels
+ if not deep_stem:
+ self.layers = nn.ModuleList(
+ [
+ ConvBNReLU(
+ xchannels[0],
+ xchannels[1],
+ 7,
+ 2,
+ 3,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=True,
+ )
+ ]
+ )
+ last_channel_idx = 1
+ else:
+ self.layers = nn.ModuleList(
+ [
+ ConvBNReLU(
+ xchannels[0],
+ xchannels[1],
+ 3,
+ 2,
+ 1,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=True,
+ ),
+ ConvBNReLU(
+ xchannels[1],
+ xchannels[2],
+ 3,
+ 1,
+ 1,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=True,
+ ),
+ ]
+ )
+ last_channel_idx = 2
+ self.layers.append(nn.MaxPool2d(kernel_size=3, stride=2, padding=1))
+ for stage, layer_blocks in enumerate(layers):
+ for iL in range(layer_blocks):
+ num_conv = block.num_conv
+ iCs = self.xchannels[last_channel_idx : last_channel_idx + num_conv + 1]
+ stride = 2 if stage > 0 and iL == 0 else 1
+ module = block(iCs, stride)
+ last_channel_idx += num_conv
+ self.xchannels[last_channel_idx] = module.out_dim
+ self.layers.append(module)
+ self.message += "\nstage={:}, ilayer={:02d}/{:02d}, block={:03d}, iCs={:}, oC={:3d}, stride={:}".format(
+ stage,
+ iL,
+ layer_blocks,
+ len(self.layers) - 1,
+ iCs,
+ module.out_dim,
+ stride,
+ )
+ if iL + 1 == xblocks[stage]: # reach the maximum depth
+ out_channel = module.out_dim
+ for iiL in range(iL + 1, layer_blocks):
+ last_channel_idx += num_conv
+ self.xchannels[last_channel_idx] = module.out_dim
+ break
+ assert last_channel_idx + 1 == len(self.xchannels), "{:} vs {:}".format(
+ last_channel_idx, len(self.xchannels)
+ )
+ self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
+ self.classifier = nn.Linear(self.xchannels[-1], num_classes)
+
+ self.apply(initialize_resnet)
+ if zero_init_residual:
+ for m in self.modules():
+ if isinstance(m, ResNetBasicblock):
+ nn.init.constant_(m.conv_b.bn.weight, 0)
+ elif isinstance(m, ResNetBottleneck):
+ nn.init.constant_(m.conv_1x4.bn.weight, 0)
+
+ def get_message(self):
+ return self.message
+
+ def forward(self, inputs):
+ x = inputs
+ for i, layer in enumerate(self.layers):
+ x = layer(x)
+ features = self.avgpool(x)
+ features = features.view(features.size(0), -1)
+ logits = self.classifier(features)
+ return features, logits
diff --git a/AutoDL-Projects/xautodl/models/shape_infers/InferMobileNetV2.py b/AutoDL-Projects/xautodl/models/shape_infers/InferMobileNetV2.py
new file mode 100644
index 0000000..d3db752
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/shape_infers/InferMobileNetV2.py
@@ -0,0 +1,176 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.01 #
+#####################################################
+# MobileNetV2: Inverted Residuals and Linear Bottlenecks, CVPR 2018
+#####################################################
+from torch import nn
+
+from ..initialization import initialize_resnet
+from ..SharedUtils import parse_channel_info
+
+
+class ConvBNReLU(nn.Module):
+ def __init__(
+ self,
+ in_planes,
+ out_planes,
+ kernel_size,
+ stride,
+ groups,
+ has_bn=True,
+ has_relu=True,
+ ):
+ super(ConvBNReLU, self).__init__()
+ padding = (kernel_size - 1) // 2
+ self.conv = nn.Conv2d(
+ in_planes,
+ out_planes,
+ kernel_size,
+ stride,
+ padding,
+ groups=groups,
+ bias=False,
+ )
+ if has_bn:
+ self.bn = nn.BatchNorm2d(out_planes)
+ else:
+ self.bn = None
+ if has_relu:
+ self.relu = nn.ReLU6(inplace=True)
+ else:
+ self.relu = None
+
+ def forward(self, x):
+ out = self.conv(x)
+ if self.bn:
+ out = self.bn(out)
+ if self.relu:
+ out = self.relu(out)
+ return out
+
+
+class InvertedResidual(nn.Module):
+ def __init__(self, channels, stride, expand_ratio, additive):
+ super(InvertedResidual, self).__init__()
+ self.stride = stride
+ assert stride in [1, 2], "invalid stride : {:}".format(stride)
+ assert len(channels) in [2, 3], "invalid channels : {:}".format(channels)
+
+ if len(channels) == 2:
+ layers = []
+ else:
+ layers = [ConvBNReLU(channels[0], channels[1], 1, 1, 1)]
+ layers.extend(
+ [
+ # dw
+ ConvBNReLU(channels[-2], channels[-2], 3, stride, channels[-2]),
+ # pw-linear
+ ConvBNReLU(channels[-2], channels[-1], 1, 1, 1, True, False),
+ ]
+ )
+ self.conv = nn.Sequential(*layers)
+ self.additive = additive
+ if self.additive and channels[0] != channels[-1]:
+ self.shortcut = ConvBNReLU(channels[0], channels[-1], 1, 1, 1, True, False)
+ else:
+ self.shortcut = None
+ self.out_dim = channels[-1]
+
+ def forward(self, x):
+ out = self.conv(x)
+ # if self.additive: return additive_func(out, x)
+ if self.shortcut:
+ return out + self.shortcut(x)
+ else:
+ return out
+
+
+class InferMobileNetV2(nn.Module):
+ def __init__(self, num_classes, xchannels, xblocks, dropout):
+ super(InferMobileNetV2, self).__init__()
+ block = InvertedResidual
+ inverted_residual_setting = [
+ # t, c, n, s
+ [1, 16, 1, 1],
+ [6, 24, 2, 2],
+ [6, 32, 3, 2],
+ [6, 64, 4, 2],
+ [6, 96, 3, 1],
+ [6, 160, 3, 2],
+ [6, 320, 1, 1],
+ ]
+ assert len(inverted_residual_setting) == len(
+ xblocks
+ ), "invalid number of layers : {:} vs {:}".format(
+ len(inverted_residual_setting), len(xblocks)
+ )
+ for block_num, ir_setting in zip(xblocks, inverted_residual_setting):
+ assert block_num <= ir_setting[2], "{:} vs {:}".format(
+ block_num, ir_setting
+ )
+ xchannels = parse_channel_info(xchannels)
+ # for i, chs in enumerate(xchannels):
+ # if i > 0: assert chs[0] == xchannels[i-1][-1], 'Layer[{:}] is invalid {:} vs {:}'.format(i, xchannels[i-1], chs)
+ self.xchannels = xchannels
+ self.message = "InferMobileNetV2 : xblocks={:}".format(xblocks)
+ # building first layer
+ features = [ConvBNReLU(xchannels[0][0], xchannels[0][1], 3, 2, 1)]
+ last_channel_idx = 1
+
+ # building inverted residual blocks
+ for stage, (t, c, n, s) in enumerate(inverted_residual_setting):
+ for i in range(n):
+ stride = s if i == 0 else 1
+ additv = True if i > 0 else False
+ module = block(self.xchannels[last_channel_idx], stride, t, additv)
+ features.append(module)
+ self.message += "\nstage={:}, ilayer={:02d}/{:02d}, block={:03d}, Cs={:}, stride={:}, expand={:}, original-C={:}".format(
+ stage,
+ i,
+ n,
+ len(features),
+ self.xchannels[last_channel_idx],
+ stride,
+ t,
+ c,
+ )
+ last_channel_idx += 1
+ if i + 1 == xblocks[stage]:
+ out_channel = module.out_dim
+ for iiL in range(i + 1, n):
+ last_channel_idx += 1
+ self.xchannels[last_channel_idx][0] = module.out_dim
+ break
+ # building last several layers
+ features.append(
+ ConvBNReLU(
+ self.xchannels[last_channel_idx][0],
+ self.xchannels[last_channel_idx][1],
+ 1,
+ 1,
+ 1,
+ )
+ )
+ assert last_channel_idx + 2 == len(self.xchannels), "{:} vs {:}".format(
+ last_channel_idx, len(self.xchannels)
+ )
+ # make it nn.Sequential
+ self.features = nn.Sequential(*features)
+
+ # building classifier
+ self.classifier = nn.Sequential(
+ nn.Dropout(dropout),
+ nn.Linear(self.xchannels[last_channel_idx][1], num_classes),
+ )
+
+ # weight initialization
+ self.apply(initialize_resnet)
+
+ def get_message(self):
+ return self.message
+
+ def forward(self, inputs):
+ features = self.features(inputs)
+ vectors = features.mean([2, 3])
+ predicts = self.classifier(vectors)
+ return features, predicts
diff --git a/AutoDL-Projects/xautodl/models/shape_infers/InferTinyCellNet.py b/AutoDL-Projects/xautodl/models/shape_infers/InferTinyCellNet.py
new file mode 100644
index 0000000..d437179
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/shape_infers/InferTinyCellNet.py
@@ -0,0 +1,65 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.01 #
+#####################################################
+from typing import List, Text, Any
+import torch.nn as nn
+
+from ..cell_operations import ResNetBasicblock
+from ..cell_infers.cells import InferCell
+
+
+class DynamicShapeTinyNet(nn.Module):
+ def __init__(self, channels: List[int], genotype: Any, num_classes: int):
+ super(DynamicShapeTinyNet, self).__init__()
+ self._channels = channels
+ if len(channels) % 3 != 2:
+ raise ValueError("invalid number of layers : {:}".format(len(channels)))
+ self._num_stage = N = len(channels) // 3
+
+ self.stem = nn.Sequential(
+ nn.Conv2d(3, channels[0], kernel_size=3, padding=1, bias=False),
+ nn.BatchNorm2d(channels[0]),
+ )
+
+ # layer_channels = [C ] * N + [C*2 ] + [C*2 ] * N + [C*4 ] + [C*4 ] * N
+ layer_reductions = [False] * N + [True] + [False] * N + [True] + [False] * N
+
+ c_prev = channels[0]
+ self.cells = nn.ModuleList()
+ for index, (c_curr, reduction) in enumerate(zip(channels, layer_reductions)):
+ if reduction:
+ cell = ResNetBasicblock(c_prev, c_curr, 2, True)
+ else:
+ cell = InferCell(genotype, c_prev, c_curr, 1)
+ self.cells.append(cell)
+ c_prev = cell.out_dim
+ self._num_layer = len(self.cells)
+
+ self.lastact = nn.Sequential(nn.BatchNorm2d(c_prev), nn.ReLU(inplace=True))
+ self.global_pooling = nn.AdaptiveAvgPool2d(1)
+ self.classifier = nn.Linear(c_prev, num_classes)
+
+ def get_message(self) -> Text:
+ string = self.extra_repr()
+ for i, cell in enumerate(self.cells):
+ string += "\n {:02d}/{:02d} :: {:}".format(
+ i, len(self.cells), cell.extra_repr()
+ )
+ return string
+
+ def extra_repr(self):
+ return "{name}(C={_channels}, N={_num_stage}, L={_num_layer})".format(
+ name=self.__class__.__name__, **self.__dict__
+ )
+
+ def forward(self, inputs):
+ feature = self.stem(inputs)
+ for i, cell in enumerate(self.cells):
+ feature = cell(feature)
+
+ out = self.lastact(feature)
+ out = self.global_pooling(out)
+ out = out.view(out.size(0), -1)
+ logits = self.classifier(out)
+
+ return out, logits
diff --git a/AutoDL-Projects/xautodl/models/shape_infers/__init__.py b/AutoDL-Projects/xautodl/models/shape_infers/__init__.py
new file mode 100644
index 0000000..9c305ff
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/shape_infers/__init__.py
@@ -0,0 +1,9 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.01 #
+#####################################################
+from .InferCifarResNet_width import InferWidthCifarResNet
+from .InferImagenetResNet import InferImagenetResNet
+from .InferCifarResNet_depth import InferDepthCifarResNet
+from .InferCifarResNet import InferCifarResNet
+from .InferMobileNetV2 import InferMobileNetV2
+from .InferTinyCellNet import DynamicShapeTinyNet
diff --git a/AutoDL-Projects/xautodl/models/shape_infers/shared_utils.py b/AutoDL-Projects/xautodl/models/shape_infers/shared_utils.py
new file mode 100644
index 0000000..86ab949
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/shape_infers/shared_utils.py
@@ -0,0 +1,5 @@
+def parse_channel_info(xstring):
+ blocks = xstring.split(" ")
+ blocks = [x.split("-") for x in blocks]
+ blocks = [[int(_) for _ in x] for x in blocks]
+ return blocks
diff --git a/AutoDL-Projects/xautodl/models/shape_searchs/SearchCifarResNet.py b/AutoDL-Projects/xautodl/models/shape_searchs/SearchCifarResNet.py
new file mode 100644
index 0000000..653051b
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/shape_searchs/SearchCifarResNet.py
@@ -0,0 +1,760 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019 #
+##################################################
+import math, torch
+from collections import OrderedDict
+from bisect import bisect_right
+import torch.nn as nn
+from ..initialization import initialize_resnet
+from ..SharedUtils import additive_func
+from .SoftSelect import select2withP, ChannelWiseInter
+from .SoftSelect import linear_forward
+from .SoftSelect import get_width_choices
+
+
+def get_depth_choices(nDepth, return_num):
+ if nDepth == 2:
+ choices = (1, 2)
+ elif nDepth == 3:
+ choices = (1, 2, 3)
+ elif nDepth > 3:
+ choices = list(range(1, nDepth + 1, 2))
+ if choices[-1] < nDepth:
+ choices.append(nDepth)
+ else:
+ raise ValueError("invalid nDepth : {:}".format(nDepth))
+ if return_num:
+ return len(choices)
+ else:
+ return choices
+
+
+def conv_forward(inputs, conv, choices):
+ iC = conv.in_channels
+ fill_size = list(inputs.size())
+ fill_size[1] = iC - fill_size[1]
+ filled = torch.zeros(fill_size, device=inputs.device)
+ xinputs = torch.cat((inputs, filled), dim=1)
+ outputs = conv(xinputs)
+ selecteds = [outputs[:, :oC] for oC in choices]
+ return selecteds
+
+
+class ConvBNReLU(nn.Module):
+ num_conv = 1
+
+ def __init__(
+ self, nIn, nOut, kernel, stride, padding, bias, has_avg, has_bn, has_relu
+ ):
+ super(ConvBNReLU, self).__init__()
+ self.InShape = None
+ self.OutShape = None
+ self.choices = get_width_choices(nOut)
+ self.register_buffer("choices_tensor", torch.Tensor(self.choices))
+
+ if has_avg:
+ self.avg = nn.AvgPool2d(kernel_size=2, stride=2, padding=0)
+ else:
+ self.avg = None
+ self.conv = nn.Conv2d(
+ nIn,
+ nOut,
+ kernel_size=kernel,
+ stride=stride,
+ padding=padding,
+ dilation=1,
+ groups=1,
+ bias=bias,
+ )
+ # if has_bn : self.bn = nn.BatchNorm2d(nOut)
+ # else : self.bn = None
+ self.has_bn = has_bn
+ self.BNs = nn.ModuleList()
+ for i, _out in enumerate(self.choices):
+ self.BNs.append(nn.BatchNorm2d(_out))
+ if has_relu:
+ self.relu = nn.ReLU(inplace=True)
+ else:
+ self.relu = None
+ self.in_dim = nIn
+ self.out_dim = nOut
+ self.search_mode = "basic"
+
+ def get_flops(self, channels, check_range=True, divide=1):
+ iC, oC = channels
+ if check_range:
+ assert (
+ iC <= self.conv.in_channels and oC <= self.conv.out_channels
+ ), "{:} vs {:} | {:} vs {:}".format(
+ iC, self.conv.in_channels, oC, self.conv.out_channels
+ )
+ assert (
+ isinstance(self.InShape, tuple) and len(self.InShape) == 2
+ ), "invalid in-shape : {:}".format(self.InShape)
+ assert (
+ isinstance(self.OutShape, tuple) and len(self.OutShape) == 2
+ ), "invalid out-shape : {:}".format(self.OutShape)
+ # conv_per_position_flops = self.conv.kernel_size[0] * self.conv.kernel_size[1] * iC * oC / self.conv.groups
+ conv_per_position_flops = (
+ self.conv.kernel_size[0] * self.conv.kernel_size[1] * 1.0 / self.conv.groups
+ )
+ all_positions = self.OutShape[0] * self.OutShape[1]
+ flops = (conv_per_position_flops * all_positions / divide) * iC * oC
+ if self.conv.bias is not None:
+ flops += all_positions / divide
+ return flops
+
+ def get_range(self):
+ return [self.choices]
+
+ def forward(self, inputs):
+ if self.search_mode == "basic":
+ return self.basic_forward(inputs)
+ elif self.search_mode == "search":
+ return self.search_forward(inputs)
+ else:
+ raise ValueError("invalid search_mode = {:}".format(self.search_mode))
+
+ def search_forward(self, tuple_inputs):
+ assert (
+ isinstance(tuple_inputs, tuple) and len(tuple_inputs) == 5
+ ), "invalid type input : {:}".format(type(tuple_inputs))
+ inputs, expected_inC, probability, index, prob = tuple_inputs
+ index, prob = torch.squeeze(index).tolist(), torch.squeeze(prob)
+ probability = torch.squeeze(probability)
+ assert len(index) == 2, "invalid length : {:}".format(index)
+ # compute expected flop
+ # coordinates = torch.arange(self.x_range[0], self.x_range[1]+1).type_as(probability)
+ expected_outC = (self.choices_tensor * probability).sum()
+ expected_flop = self.get_flops([expected_inC, expected_outC], False, 1e6)
+ if self.avg:
+ out = self.avg(inputs)
+ else:
+ out = inputs
+ # convolutional layer
+ out_convs = conv_forward(out, self.conv, [self.choices[i] for i in index])
+ out_bns = [self.BNs[idx](out_conv) for idx, out_conv in zip(index, out_convs)]
+ # merge
+ out_channel = max([x.size(1) for x in out_bns])
+ outA = ChannelWiseInter(out_bns[0], out_channel)
+ outB = ChannelWiseInter(out_bns[1], out_channel)
+ out = outA * prob[0] + outB * prob[1]
+ # out = additive_func(out_bns[0]*prob[0], out_bns[1]*prob[1])
+
+ if self.relu:
+ out = self.relu(out)
+ else:
+ out = out
+ return out, expected_outC, expected_flop
+
+ def basic_forward(self, inputs):
+ if self.avg:
+ out = self.avg(inputs)
+ else:
+ out = inputs
+ conv = self.conv(out)
+ if self.has_bn:
+ out = self.BNs[-1](conv)
+ else:
+ out = conv
+ if self.relu:
+ out = self.relu(out)
+ else:
+ out = out
+ if self.InShape is None:
+ self.InShape = (inputs.size(-2), inputs.size(-1))
+ self.OutShape = (out.size(-2), out.size(-1))
+ return out
+
+
+class ResNetBasicblock(nn.Module):
+ expansion = 1
+ num_conv = 2
+
+ def __init__(self, inplanes, planes, stride):
+ super(ResNetBasicblock, self).__init__()
+ assert stride == 1 or stride == 2, "invalid stride {:}".format(stride)
+ self.conv_a = ConvBNReLU(
+ inplanes,
+ planes,
+ 3,
+ stride,
+ 1,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=True,
+ )
+ self.conv_b = ConvBNReLU(
+ planes, planes, 3, 1, 1, False, has_avg=False, has_bn=True, has_relu=False
+ )
+ if stride == 2:
+ self.downsample = ConvBNReLU(
+ inplanes,
+ planes,
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=True,
+ has_bn=False,
+ has_relu=False,
+ )
+ elif inplanes != planes:
+ self.downsample = ConvBNReLU(
+ inplanes,
+ planes,
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=False,
+ )
+ else:
+ self.downsample = None
+ self.out_dim = planes
+ self.search_mode = "basic"
+
+ def get_range(self):
+ return self.conv_a.get_range() + self.conv_b.get_range()
+
+ def get_flops(self, channels):
+ assert len(channels) == 3, "invalid channels : {:}".format(channels)
+ flop_A = self.conv_a.get_flops([channels[0], channels[1]])
+ flop_B = self.conv_b.get_flops([channels[1], channels[2]])
+ if hasattr(self.downsample, "get_flops"):
+ flop_C = self.downsample.get_flops([channels[0], channels[-1]])
+ else:
+ flop_C = 0
+ if (
+ channels[0] != channels[-1] and self.downsample is None
+ ): # this short-cut will be added during the infer-train
+ flop_C = (
+ channels[0]
+ * channels[-1]
+ * self.conv_b.OutShape[0]
+ * self.conv_b.OutShape[1]
+ )
+ return flop_A + flop_B + flop_C
+
+ def forward(self, inputs):
+ if self.search_mode == "basic":
+ return self.basic_forward(inputs)
+ elif self.search_mode == "search":
+ return self.search_forward(inputs)
+ else:
+ raise ValueError("invalid search_mode = {:}".format(self.search_mode))
+
+ def search_forward(self, tuple_inputs):
+ assert (
+ isinstance(tuple_inputs, tuple) and len(tuple_inputs) == 5
+ ), "invalid type input : {:}".format(type(tuple_inputs))
+ inputs, expected_inC, probability, indexes, probs = tuple_inputs
+ assert indexes.size(0) == 2 and probs.size(0) == 2 and probability.size(0) == 2
+ out_a, expected_inC_a, expected_flop_a = self.conv_a(
+ (inputs, expected_inC, probability[0], indexes[0], probs[0])
+ )
+ out_b, expected_inC_b, expected_flop_b = self.conv_b(
+ (out_a, expected_inC_a, probability[1], indexes[1], probs[1])
+ )
+ if self.downsample is not None:
+ residual, _, expected_flop_c = self.downsample(
+ (inputs, expected_inC, probability[1], indexes[1], probs[1])
+ )
+ else:
+ residual, expected_flop_c = inputs, 0
+ out = additive_func(residual, out_b)
+ return (
+ nn.functional.relu(out, inplace=True),
+ expected_inC_b,
+ sum([expected_flop_a, expected_flop_b, expected_flop_c]),
+ )
+
+ def basic_forward(self, inputs):
+ basicblock = self.conv_a(inputs)
+ basicblock = self.conv_b(basicblock)
+ if self.downsample is not None:
+ residual = self.downsample(inputs)
+ else:
+ residual = inputs
+ out = additive_func(residual, basicblock)
+ return nn.functional.relu(out, inplace=True)
+
+
+class ResNetBottleneck(nn.Module):
+ expansion = 4
+ num_conv = 3
+
+ def __init__(self, inplanes, planes, stride):
+ super(ResNetBottleneck, self).__init__()
+ assert stride == 1 or stride == 2, "invalid stride {:}".format(stride)
+ self.conv_1x1 = ConvBNReLU(
+ inplanes, planes, 1, 1, 0, False, has_avg=False, has_bn=True, has_relu=True
+ )
+ self.conv_3x3 = ConvBNReLU(
+ planes,
+ planes,
+ 3,
+ stride,
+ 1,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=True,
+ )
+ self.conv_1x4 = ConvBNReLU(
+ planes,
+ planes * self.expansion,
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=False,
+ )
+ if stride == 2:
+ self.downsample = ConvBNReLU(
+ inplanes,
+ planes * self.expansion,
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=True,
+ has_bn=False,
+ has_relu=False,
+ )
+ elif inplanes != planes * self.expansion:
+ self.downsample = ConvBNReLU(
+ inplanes,
+ planes * self.expansion,
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=False,
+ )
+ else:
+ self.downsample = None
+ self.out_dim = planes * self.expansion
+ self.search_mode = "basic"
+
+ def get_range(self):
+ return (
+ self.conv_1x1.get_range()
+ + self.conv_3x3.get_range()
+ + self.conv_1x4.get_range()
+ )
+
+ def get_flops(self, channels):
+ assert len(channels) == 4, "invalid channels : {:}".format(channels)
+ flop_A = self.conv_1x1.get_flops([channels[0], channels[1]])
+ flop_B = self.conv_3x3.get_flops([channels[1], channels[2]])
+ flop_C = self.conv_1x4.get_flops([channels[2], channels[3]])
+ if hasattr(self.downsample, "get_flops"):
+ flop_D = self.downsample.get_flops([channels[0], channels[-1]])
+ else:
+ flop_D = 0
+ if (
+ channels[0] != channels[-1] and self.downsample is None
+ ): # this short-cut will be added during the infer-train
+ flop_D = (
+ channels[0]
+ * channels[-1]
+ * self.conv_1x4.OutShape[0]
+ * self.conv_1x4.OutShape[1]
+ )
+ return flop_A + flop_B + flop_C + flop_D
+
+ def forward(self, inputs):
+ if self.search_mode == "basic":
+ return self.basic_forward(inputs)
+ elif self.search_mode == "search":
+ return self.search_forward(inputs)
+ else:
+ raise ValueError("invalid search_mode = {:}".format(self.search_mode))
+
+ def basic_forward(self, inputs):
+ bottleneck = self.conv_1x1(inputs)
+ bottleneck = self.conv_3x3(bottleneck)
+ bottleneck = self.conv_1x4(bottleneck)
+ if self.downsample is not None:
+ residual = self.downsample(inputs)
+ else:
+ residual = inputs
+ out = additive_func(residual, bottleneck)
+ return nn.functional.relu(out, inplace=True)
+
+ def search_forward(self, tuple_inputs):
+ assert (
+ isinstance(tuple_inputs, tuple) and len(tuple_inputs) == 5
+ ), "invalid type input : {:}".format(type(tuple_inputs))
+ inputs, expected_inC, probability, indexes, probs = tuple_inputs
+ assert indexes.size(0) == 3 and probs.size(0) == 3 and probability.size(0) == 3
+ out_1x1, expected_inC_1x1, expected_flop_1x1 = self.conv_1x1(
+ (inputs, expected_inC, probability[0], indexes[0], probs[0])
+ )
+ out_3x3, expected_inC_3x3, expected_flop_3x3 = self.conv_3x3(
+ (out_1x1, expected_inC_1x1, probability[1], indexes[1], probs[1])
+ )
+ out_1x4, expected_inC_1x4, expected_flop_1x4 = self.conv_1x4(
+ (out_3x3, expected_inC_3x3, probability[2], indexes[2], probs[2])
+ )
+ if self.downsample is not None:
+ residual, _, expected_flop_c = self.downsample(
+ (inputs, expected_inC, probability[2], indexes[2], probs[2])
+ )
+ else:
+ residual, expected_flop_c = inputs, 0
+ out = additive_func(residual, out_1x4)
+ return (
+ nn.functional.relu(out, inplace=True),
+ expected_inC_1x4,
+ sum(
+ [
+ expected_flop_1x1,
+ expected_flop_3x3,
+ expected_flop_1x4,
+ expected_flop_c,
+ ]
+ ),
+ )
+
+
+class SearchShapeCifarResNet(nn.Module):
+ def __init__(self, block_name, depth, num_classes):
+ super(SearchShapeCifarResNet, self).__init__()
+
+ # Model type specifies number of layers for CIFAR-10 and CIFAR-100 model
+ if block_name == "ResNetBasicblock":
+ block = ResNetBasicblock
+ assert (depth - 2) % 6 == 0, "depth should be one of 20, 32, 44, 56, 110"
+ layer_blocks = (depth - 2) // 6
+ elif block_name == "ResNetBottleneck":
+ block = ResNetBottleneck
+ assert (depth - 2) % 9 == 0, "depth should be one of 164"
+ layer_blocks = (depth - 2) // 9
+ else:
+ raise ValueError("invalid block : {:}".format(block_name))
+
+ self.message = (
+ "SearchShapeCifarResNet : Depth : {:} , Layers for each block : {:}".format(
+ depth, layer_blocks
+ )
+ )
+ self.num_classes = num_classes
+ self.channels = [16]
+ self.layers = nn.ModuleList(
+ [
+ ConvBNReLU(
+ 3, 16, 3, 1, 1, False, has_avg=False, has_bn=True, has_relu=True
+ )
+ ]
+ )
+ self.InShape = None
+ self.depth_info = OrderedDict()
+ self.depth_at_i = OrderedDict()
+ for stage in range(3):
+ cur_block_choices = get_depth_choices(layer_blocks, False)
+ assert (
+ cur_block_choices[-1] == layer_blocks
+ ), "stage={:}, {:} vs {:}".format(stage, cur_block_choices, layer_blocks)
+ self.message += (
+ "\nstage={:} ::: depth-block-choices={:} for {:} blocks.".format(
+ stage, cur_block_choices, layer_blocks
+ )
+ )
+ block_choices, xstart = [], len(self.layers)
+ for iL in range(layer_blocks):
+ iC = self.channels[-1]
+ planes = 16 * (2 ** stage)
+ stride = 2 if stage > 0 and iL == 0 else 1
+ module = block(iC, planes, stride)
+ self.channels.append(module.out_dim)
+ self.layers.append(module)
+ self.message += "\nstage={:}, ilayer={:02d}/{:02d}, block={:03d}, iC={:3d}, oC={:3d}, stride={:}".format(
+ stage,
+ iL,
+ layer_blocks,
+ len(self.layers) - 1,
+ iC,
+ module.out_dim,
+ stride,
+ )
+ # added for depth
+ layer_index = len(self.layers) - 1
+ if iL + 1 in cur_block_choices:
+ block_choices.append(layer_index)
+ if iL + 1 == layer_blocks:
+ self.depth_info[layer_index] = {
+ "choices": block_choices,
+ "stage": stage,
+ "xstart": xstart,
+ }
+ self.depth_info_list = []
+ for xend, info in self.depth_info.items():
+ self.depth_info_list.append((xend, info))
+ xstart, xstage = info["xstart"], info["stage"]
+ for ilayer in range(xstart, xend + 1):
+ idx = bisect_right(info["choices"], ilayer - 1)
+ self.depth_at_i[ilayer] = (xstage, idx)
+
+ self.avgpool = nn.AvgPool2d(8)
+ self.classifier = nn.Linear(module.out_dim, num_classes)
+ self.InShape = None
+ self.tau = -1
+ self.search_mode = "basic"
+ # assert sum(x.num_conv for x in self.layers) + 1 == depth, 'invalid depth check {:} vs {:}'.format(sum(x.num_conv for x in self.layers)+1, depth)
+
+ # parameters for width
+ self.Ranges = []
+ self.layer2indexRange = []
+ for i, layer in enumerate(self.layers):
+ start_index = len(self.Ranges)
+ self.Ranges += layer.get_range()
+ self.layer2indexRange.append((start_index, len(self.Ranges)))
+ assert len(self.Ranges) + 1 == depth, "invalid depth check {:} vs {:}".format(
+ len(self.Ranges) + 1, depth
+ )
+
+ self.register_parameter(
+ "width_attentions",
+ nn.Parameter(torch.Tensor(len(self.Ranges), get_width_choices(None))),
+ )
+ self.register_parameter(
+ "depth_attentions",
+ nn.Parameter(torch.Tensor(3, get_depth_choices(layer_blocks, True))),
+ )
+ nn.init.normal_(self.width_attentions, 0, 0.01)
+ nn.init.normal_(self.depth_attentions, 0, 0.01)
+ self.apply(initialize_resnet)
+
+ def arch_parameters(self, LR=None):
+ if LR is None:
+ return [self.width_attentions, self.depth_attentions]
+ else:
+ return [
+ {"params": self.width_attentions, "lr": LR},
+ {"params": self.depth_attentions, "lr": LR},
+ ]
+
+ def base_parameters(self):
+ return (
+ list(self.layers.parameters())
+ + list(self.avgpool.parameters())
+ + list(self.classifier.parameters())
+ )
+
+ def get_flop(self, mode, config_dict, extra_info):
+ if config_dict is not None:
+ config_dict = config_dict.copy()
+ # select channels
+ channels = [3]
+ for i, weight in enumerate(self.width_attentions):
+ if mode == "genotype":
+ with torch.no_grad():
+ probe = nn.functional.softmax(weight, dim=0)
+ C = self.Ranges[i][torch.argmax(probe).item()]
+ elif mode == "max":
+ C = self.Ranges[i][-1]
+ elif mode == "fix":
+ C = int(math.sqrt(extra_info) * self.Ranges[i][-1])
+ elif mode == "random":
+ assert isinstance(extra_info, float), "invalid extra_info : {:}".format(
+ extra_info
+ )
+ with torch.no_grad():
+ prob = nn.functional.softmax(weight, dim=0)
+ approximate_C = int(math.sqrt(extra_info) * self.Ranges[i][-1])
+ for j in range(prob.size(0)):
+ prob[j] = 1 / (
+ abs(j - (approximate_C - self.Ranges[i][j])) + 0.2
+ )
+ C = self.Ranges[i][torch.multinomial(prob, 1, False).item()]
+ else:
+ raise ValueError("invalid mode : {:}".format(mode))
+ channels.append(C)
+ # select depth
+ if mode == "genotype":
+ with torch.no_grad():
+ depth_probs = nn.functional.softmax(self.depth_attentions, dim=1)
+ choices = torch.argmax(depth_probs, dim=1).cpu().tolist()
+ elif mode == "max" or mode == "fix":
+ choices = [depth_probs.size(1) - 1 for _ in range(depth_probs.size(0))]
+ elif mode == "random":
+ with torch.no_grad():
+ depth_probs = nn.functional.softmax(self.depth_attentions, dim=1)
+ choices = torch.multinomial(depth_probs, 1, False).cpu().tolist()
+ else:
+ raise ValueError("invalid mode : {:}".format(mode))
+ selected_layers = []
+ for choice, xvalue in zip(choices, self.depth_info_list):
+ xtemp = xvalue[1]["choices"][choice] - xvalue[1]["xstart"] + 1
+ selected_layers.append(xtemp)
+ flop = 0
+ for i, layer in enumerate(self.layers):
+ s, e = self.layer2indexRange[i]
+ xchl = tuple(channels[s : e + 1])
+ if i in self.depth_at_i:
+ xstagei, xatti = self.depth_at_i[i]
+ if xatti <= choices[xstagei]: # leave this depth
+ flop += layer.get_flops(xchl)
+ else:
+ flop += 0 # do not use this layer
+ else:
+ flop += layer.get_flops(xchl)
+ # the last fc layer
+ flop += channels[-1] * self.classifier.out_features
+ if config_dict is None:
+ return flop / 1e6
+ else:
+ config_dict["xchannels"] = channels
+ config_dict["xblocks"] = selected_layers
+ config_dict["super_type"] = "infer-shape"
+ config_dict["estimated_FLOP"] = flop / 1e6
+ return flop / 1e6, config_dict
+
+ def get_arch_info(self):
+ string = (
+ "for depth and width, there are {:} + {:} attention probabilities.".format(
+ len(self.depth_attentions), len(self.width_attentions)
+ )
+ )
+ string += "\n{:}".format(self.depth_info)
+ discrepancy = []
+ with torch.no_grad():
+ for i, att in enumerate(self.depth_attentions):
+ prob = nn.functional.softmax(att, dim=0)
+ prob = prob.cpu()
+ selc = prob.argmax().item()
+ prob = prob.tolist()
+ prob = ["{:.3f}".format(x) for x in prob]
+ xstring = "{:03d}/{:03d}-th : {:}".format(
+ i, len(self.depth_attentions), " ".join(prob)
+ )
+ logt = ["{:.4f}".format(x) for x in att.cpu().tolist()]
+ xstring += " || {:17s}".format(" ".join(logt))
+ prob = sorted([float(x) for x in prob])
+ disc = prob[-1] - prob[-2]
+ xstring += " || discrepancy={:.2f} || select={:}/{:}".format(
+ disc, selc, len(prob)
+ )
+ discrepancy.append(disc)
+ string += "\n{:}".format(xstring)
+ string += "\n-----------------------------------------------"
+ for i, att in enumerate(self.width_attentions):
+ prob = nn.functional.softmax(att, dim=0)
+ prob = prob.cpu()
+ selc = prob.argmax().item()
+ prob = prob.tolist()
+ prob = ["{:.3f}".format(x) for x in prob]
+ xstring = "{:03d}/{:03d}-th : {:}".format(
+ i, len(self.width_attentions), " ".join(prob)
+ )
+ logt = ["{:.3f}".format(x) for x in att.cpu().tolist()]
+ xstring += " || {:52s}".format(" ".join(logt))
+ prob = sorted([float(x) for x in prob])
+ disc = prob[-1] - prob[-2]
+ xstring += " || dis={:.2f} || select={:}/{:}".format(
+ disc, selc, len(prob)
+ )
+ discrepancy.append(disc)
+ string += "\n{:}".format(xstring)
+ return string, discrepancy
+
+ def set_tau(self, tau_max, tau_min, epoch_ratio):
+ assert (
+ epoch_ratio >= 0 and epoch_ratio <= 1
+ ), "invalid epoch-ratio : {:}".format(epoch_ratio)
+ tau = tau_min + (tau_max - tau_min) * (1 + math.cos(math.pi * epoch_ratio)) / 2
+ self.tau = tau
+
+ def get_message(self):
+ return self.message
+
+ def forward(self, inputs):
+ if self.search_mode == "basic":
+ return self.basic_forward(inputs)
+ elif self.search_mode == "search":
+ return self.search_forward(inputs)
+ else:
+ raise ValueError("invalid search_mode = {:}".format(self.search_mode))
+
+ def search_forward(self, inputs):
+ flop_width_probs = nn.functional.softmax(self.width_attentions, dim=1)
+ flop_depth_probs = nn.functional.softmax(self.depth_attentions, dim=1)
+ flop_depth_probs = torch.flip(
+ torch.cumsum(torch.flip(flop_depth_probs, [1]), 1), [1]
+ )
+ selected_widths, selected_width_probs = select2withP(
+ self.width_attentions, self.tau
+ )
+ selected_depth_probs = select2withP(self.depth_attentions, self.tau, True)
+ with torch.no_grad():
+ selected_widths = selected_widths.cpu()
+
+ x, last_channel_idx, expected_inC, flops = inputs, 0, 3, []
+ feature_maps = []
+ for i, layer in enumerate(self.layers):
+ selected_w_index = selected_widths[
+ last_channel_idx : last_channel_idx + layer.num_conv
+ ]
+ selected_w_probs = selected_width_probs[
+ last_channel_idx : last_channel_idx + layer.num_conv
+ ]
+ layer_prob = flop_width_probs[
+ last_channel_idx : last_channel_idx + layer.num_conv
+ ]
+ x, expected_inC, expected_flop = layer(
+ (x, expected_inC, layer_prob, selected_w_index, selected_w_probs)
+ )
+ feature_maps.append(x)
+ last_channel_idx += layer.num_conv
+ if i in self.depth_info: # aggregate the information
+ choices = self.depth_info[i]["choices"]
+ xstagei = self.depth_info[i]["stage"]
+ # print ('iL={:}, choices={:}, stage={:}, probs={:}'.format(i, choices, xstagei, selected_depth_probs[xstagei].cpu().tolist()))
+ # for A, W in zip(choices, selected_depth_probs[xstagei]):
+ # print('Size = {:}, W = {:}'.format(feature_maps[A].size(), W))
+ possible_tensors = []
+ max_C = max(feature_maps[A].size(1) for A in choices)
+ for tempi, A in enumerate(choices):
+ xtensor = ChannelWiseInter(feature_maps[A], max_C)
+ # drop_ratio = 1-(tempi+1.0)/len(choices)
+ # xtensor = drop_path(xtensor, drop_ratio)
+ possible_tensors.append(xtensor)
+ weighted_sum = sum(
+ xtensor * W
+ for xtensor, W in zip(
+ possible_tensors, selected_depth_probs[xstagei]
+ )
+ )
+ x = weighted_sum
+
+ if i in self.depth_at_i:
+ xstagei, xatti = self.depth_at_i[i]
+ x_expected_flop = flop_depth_probs[xstagei, xatti] * expected_flop
+ else:
+ x_expected_flop = expected_flop
+ flops.append(x_expected_flop)
+ flops.append(expected_inC * (self.classifier.out_features * 1.0 / 1e6))
+ features = self.avgpool(x)
+ features = features.view(features.size(0), -1)
+ logits = linear_forward(features, self.classifier)
+ return logits, torch.stack([sum(flops)])
+
+ def basic_forward(self, inputs):
+ if self.InShape is None:
+ self.InShape = (inputs.size(-2), inputs.size(-1))
+ x = inputs
+ for i, layer in enumerate(self.layers):
+ x = layer(x)
+ features = self.avgpool(x)
+ features = features.view(features.size(0), -1)
+ logits = self.classifier(features)
+ return features, logits
diff --git a/AutoDL-Projects/xautodl/models/shape_searchs/SearchCifarResNet_depth.py b/AutoDL-Projects/xautodl/models/shape_searchs/SearchCifarResNet_depth.py
new file mode 100644
index 0000000..24c5d83
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/shape_searchs/SearchCifarResNet_depth.py
@@ -0,0 +1,515 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019 #
+##################################################
+import math, torch
+from collections import OrderedDict
+from bisect import bisect_right
+import torch.nn as nn
+from ..initialization import initialize_resnet
+from ..SharedUtils import additive_func
+from .SoftSelect import select2withP, ChannelWiseInter
+from .SoftSelect import linear_forward
+from .SoftSelect import get_width_choices
+
+
+def get_depth_choices(nDepth, return_num):
+ if nDepth == 2:
+ choices = (1, 2)
+ elif nDepth == 3:
+ choices = (1, 2, 3)
+ elif nDepth > 3:
+ choices = list(range(1, nDepth + 1, 2))
+ if choices[-1] < nDepth:
+ choices.append(nDepth)
+ else:
+ raise ValueError("invalid nDepth : {:}".format(nDepth))
+ if return_num:
+ return len(choices)
+ else:
+ return choices
+
+
+class ConvBNReLU(nn.Module):
+ num_conv = 1
+
+ def __init__(
+ self, nIn, nOut, kernel, stride, padding, bias, has_avg, has_bn, has_relu
+ ):
+ super(ConvBNReLU, self).__init__()
+ self.InShape = None
+ self.OutShape = None
+ self.choices = get_width_choices(nOut)
+ self.register_buffer("choices_tensor", torch.Tensor(self.choices))
+
+ if has_avg:
+ self.avg = nn.AvgPool2d(kernel_size=2, stride=2, padding=0)
+ else:
+ self.avg = None
+ self.conv = nn.Conv2d(
+ nIn,
+ nOut,
+ kernel_size=kernel,
+ stride=stride,
+ padding=padding,
+ dilation=1,
+ groups=1,
+ bias=bias,
+ )
+ if has_bn:
+ self.bn = nn.BatchNorm2d(nOut)
+ else:
+ self.bn = None
+ if has_relu:
+ self.relu = nn.ReLU(inplace=False)
+ else:
+ self.relu = None
+ self.in_dim = nIn
+ self.out_dim = nOut
+
+ def get_flops(self, divide=1):
+ iC, oC = self.in_dim, self.out_dim
+ assert (
+ iC <= self.conv.in_channels and oC <= self.conv.out_channels
+ ), "{:} vs {:} | {:} vs {:}".format(
+ iC, self.conv.in_channels, oC, self.conv.out_channels
+ )
+ assert (
+ isinstance(self.InShape, tuple) and len(self.InShape) == 2
+ ), "invalid in-shape : {:}".format(self.InShape)
+ assert (
+ isinstance(self.OutShape, tuple) and len(self.OutShape) == 2
+ ), "invalid out-shape : {:}".format(self.OutShape)
+ # conv_per_position_flops = self.conv.kernel_size[0] * self.conv.kernel_size[1] * iC * oC / self.conv.groups
+ conv_per_position_flops = (
+ self.conv.kernel_size[0] * self.conv.kernel_size[1] * 1.0 / self.conv.groups
+ )
+ all_positions = self.OutShape[0] * self.OutShape[1]
+ flops = (conv_per_position_flops * all_positions / divide) * iC * oC
+ if self.conv.bias is not None:
+ flops += all_positions / divide
+ return flops
+
+ def forward(self, inputs):
+ if self.avg:
+ out = self.avg(inputs)
+ else:
+ out = inputs
+ conv = self.conv(out)
+ if self.bn:
+ out = self.bn(conv)
+ else:
+ out = conv
+ if self.relu:
+ out = self.relu(out)
+ else:
+ out = out
+ if self.InShape is None:
+ self.InShape = (inputs.size(-2), inputs.size(-1))
+ self.OutShape = (out.size(-2), out.size(-1))
+ return out
+
+
+class ResNetBasicblock(nn.Module):
+ expansion = 1
+ num_conv = 2
+
+ def __init__(self, inplanes, planes, stride):
+ super(ResNetBasicblock, self).__init__()
+ assert stride == 1 or stride == 2, "invalid stride {:}".format(stride)
+ self.conv_a = ConvBNReLU(
+ inplanes,
+ planes,
+ 3,
+ stride,
+ 1,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=True,
+ )
+ self.conv_b = ConvBNReLU(
+ planes, planes, 3, 1, 1, False, has_avg=False, has_bn=True, has_relu=False
+ )
+ if stride == 2:
+ self.downsample = ConvBNReLU(
+ inplanes,
+ planes,
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=True,
+ has_bn=False,
+ has_relu=False,
+ )
+ elif inplanes != planes:
+ self.downsample = ConvBNReLU(
+ inplanes,
+ planes,
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=False,
+ )
+ else:
+ self.downsample = None
+ self.out_dim = planes
+ self.search_mode = "basic"
+
+ def get_flops(self, divide=1):
+ flop_A = self.conv_a.get_flops(divide)
+ flop_B = self.conv_b.get_flops(divide)
+ if hasattr(self.downsample, "get_flops"):
+ flop_C = self.downsample.get_flops(divide)
+ else:
+ flop_C = 0
+ return flop_A + flop_B + flop_C
+
+ def forward(self, inputs):
+ basicblock = self.conv_a(inputs)
+ basicblock = self.conv_b(basicblock)
+ if self.downsample is not None:
+ residual = self.downsample(inputs)
+ else:
+ residual = inputs
+ out = additive_func(residual, basicblock)
+ return nn.functional.relu(out, inplace=True)
+
+
+class ResNetBottleneck(nn.Module):
+ expansion = 4
+ num_conv = 3
+
+ def __init__(self, inplanes, planes, stride):
+ super(ResNetBottleneck, self).__init__()
+ assert stride == 1 or stride == 2, "invalid stride {:}".format(stride)
+ self.conv_1x1 = ConvBNReLU(
+ inplanes, planes, 1, 1, 0, False, has_avg=False, has_bn=True, has_relu=True
+ )
+ self.conv_3x3 = ConvBNReLU(
+ planes,
+ planes,
+ 3,
+ stride,
+ 1,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=True,
+ )
+ self.conv_1x4 = ConvBNReLU(
+ planes,
+ planes * self.expansion,
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=False,
+ )
+ if stride == 2:
+ self.downsample = ConvBNReLU(
+ inplanes,
+ planes * self.expansion,
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=True,
+ has_bn=False,
+ has_relu=False,
+ )
+ elif inplanes != planes * self.expansion:
+ self.downsample = ConvBNReLU(
+ inplanes,
+ planes * self.expansion,
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=False,
+ )
+ else:
+ self.downsample = None
+ self.out_dim = planes * self.expansion
+ self.search_mode = "basic"
+
+ def get_range(self):
+ return (
+ self.conv_1x1.get_range()
+ + self.conv_3x3.get_range()
+ + self.conv_1x4.get_range()
+ )
+
+ def get_flops(self, divide):
+ flop_A = self.conv_1x1.get_flops(divide)
+ flop_B = self.conv_3x3.get_flops(divide)
+ flop_C = self.conv_1x4.get_flops(divide)
+ if hasattr(self.downsample, "get_flops"):
+ flop_D = self.downsample.get_flops(divide)
+ else:
+ flop_D = 0
+ return flop_A + flop_B + flop_C + flop_D
+
+ def forward(self, inputs):
+ bottleneck = self.conv_1x1(inputs)
+ bottleneck = self.conv_3x3(bottleneck)
+ bottleneck = self.conv_1x4(bottleneck)
+ if self.downsample is not None:
+ residual = self.downsample(inputs)
+ else:
+ residual = inputs
+ out = additive_func(residual, bottleneck)
+ return nn.functional.relu(out, inplace=True)
+
+
+class SearchDepthCifarResNet(nn.Module):
+ def __init__(self, block_name, depth, num_classes):
+ super(SearchDepthCifarResNet, self).__init__()
+
+ # Model type specifies number of layers for CIFAR-10 and CIFAR-100 model
+ if block_name == "ResNetBasicblock":
+ block = ResNetBasicblock
+ assert (depth - 2) % 6 == 0, "depth should be one of 20, 32, 44, 56, 110"
+ layer_blocks = (depth - 2) // 6
+ elif block_name == "ResNetBottleneck":
+ block = ResNetBottleneck
+ assert (depth - 2) % 9 == 0, "depth should be one of 164"
+ layer_blocks = (depth - 2) // 9
+ else:
+ raise ValueError("invalid block : {:}".format(block_name))
+
+ self.message = (
+ "SearchShapeCifarResNet : Depth : {:} , Layers for each block : {:}".format(
+ depth, layer_blocks
+ )
+ )
+ self.num_classes = num_classes
+ self.channels = [16]
+ self.layers = nn.ModuleList(
+ [
+ ConvBNReLU(
+ 3, 16, 3, 1, 1, False, has_avg=False, has_bn=True, has_relu=True
+ )
+ ]
+ )
+ self.InShape = None
+ self.depth_info = OrderedDict()
+ self.depth_at_i = OrderedDict()
+ for stage in range(3):
+ cur_block_choices = get_depth_choices(layer_blocks, False)
+ assert (
+ cur_block_choices[-1] == layer_blocks
+ ), "stage={:}, {:} vs {:}".format(stage, cur_block_choices, layer_blocks)
+ self.message += (
+ "\nstage={:} ::: depth-block-choices={:} for {:} blocks.".format(
+ stage, cur_block_choices, layer_blocks
+ )
+ )
+ block_choices, xstart = [], len(self.layers)
+ for iL in range(layer_blocks):
+ iC = self.channels[-1]
+ planes = 16 * (2 ** stage)
+ stride = 2 if stage > 0 and iL == 0 else 1
+ module = block(iC, planes, stride)
+ self.channels.append(module.out_dim)
+ self.layers.append(module)
+ self.message += "\nstage={:}, ilayer={:02d}/{:02d}, block={:03d}, iC={:3d}, oC={:3d}, stride={:}".format(
+ stage,
+ iL,
+ layer_blocks,
+ len(self.layers) - 1,
+ iC,
+ module.out_dim,
+ stride,
+ )
+ # added for depth
+ layer_index = len(self.layers) - 1
+ if iL + 1 in cur_block_choices:
+ block_choices.append(layer_index)
+ if iL + 1 == layer_blocks:
+ self.depth_info[layer_index] = {
+ "choices": block_choices,
+ "stage": stage,
+ "xstart": xstart,
+ }
+ self.depth_info_list = []
+ for xend, info in self.depth_info.items():
+ self.depth_info_list.append((xend, info))
+ xstart, xstage = info["xstart"], info["stage"]
+ for ilayer in range(xstart, xend + 1):
+ idx = bisect_right(info["choices"], ilayer - 1)
+ self.depth_at_i[ilayer] = (xstage, idx)
+
+ self.avgpool = nn.AvgPool2d(8)
+ self.classifier = nn.Linear(module.out_dim, num_classes)
+ self.InShape = None
+ self.tau = -1
+ self.search_mode = "basic"
+ # assert sum(x.num_conv for x in self.layers) + 1 == depth, 'invalid depth check {:} vs {:}'.format(sum(x.num_conv for x in self.layers)+1, depth)
+
+ self.register_parameter(
+ "depth_attentions",
+ nn.Parameter(torch.Tensor(3, get_depth_choices(layer_blocks, True))),
+ )
+ nn.init.normal_(self.depth_attentions, 0, 0.01)
+ self.apply(initialize_resnet)
+
+ def arch_parameters(self):
+ return [self.depth_attentions]
+
+ def base_parameters(self):
+ return (
+ list(self.layers.parameters())
+ + list(self.avgpool.parameters())
+ + list(self.classifier.parameters())
+ )
+
+ def get_flop(self, mode, config_dict, extra_info):
+ if config_dict is not None:
+ config_dict = config_dict.copy()
+ # select depth
+ if mode == "genotype":
+ with torch.no_grad():
+ depth_probs = nn.functional.softmax(self.depth_attentions, dim=1)
+ choices = torch.argmax(depth_probs, dim=1).cpu().tolist()
+ elif mode == "max":
+ choices = [depth_probs.size(1) - 1 for _ in range(depth_probs.size(0))]
+ elif mode == "random":
+ with torch.no_grad():
+ depth_probs = nn.functional.softmax(self.depth_attentions, dim=1)
+ choices = torch.multinomial(depth_probs, 1, False).cpu().tolist()
+ else:
+ raise ValueError("invalid mode : {:}".format(mode))
+ selected_layers = []
+ for choice, xvalue in zip(choices, self.depth_info_list):
+ xtemp = xvalue[1]["choices"][choice] - xvalue[1]["xstart"] + 1
+ selected_layers.append(xtemp)
+ flop = 0
+ for i, layer in enumerate(self.layers):
+ if i in self.depth_at_i:
+ xstagei, xatti = self.depth_at_i[i]
+ if xatti <= choices[xstagei]: # leave this depth
+ flop += layer.get_flops()
+ else:
+ flop += 0 # do not use this layer
+ else:
+ flop += layer.get_flops()
+ # the last fc layer
+ flop += self.classifier.in_features * self.classifier.out_features
+ if config_dict is None:
+ return flop / 1e6
+ else:
+ config_dict["xblocks"] = selected_layers
+ config_dict["super_type"] = "infer-depth"
+ config_dict["estimated_FLOP"] = flop / 1e6
+ return flop / 1e6, config_dict
+
+ def get_arch_info(self):
+ string = "for depth, there are {:} attention probabilities.".format(
+ len(self.depth_attentions)
+ )
+ string += "\n{:}".format(self.depth_info)
+ discrepancy = []
+ with torch.no_grad():
+ for i, att in enumerate(self.depth_attentions):
+ prob = nn.functional.softmax(att, dim=0)
+ prob = prob.cpu()
+ selc = prob.argmax().item()
+ prob = prob.tolist()
+ prob = ["{:.3f}".format(x) for x in prob]
+ xstring = "{:03d}/{:03d}-th : {:}".format(
+ i, len(self.depth_attentions), " ".join(prob)
+ )
+ logt = ["{:.4f}".format(x) for x in att.cpu().tolist()]
+ xstring += " || {:17s}".format(" ".join(logt))
+ prob = sorted([float(x) for x in prob])
+ disc = prob[-1] - prob[-2]
+ xstring += " || discrepancy={:.2f} || select={:}/{:}".format(
+ disc, selc, len(prob)
+ )
+ discrepancy.append(disc)
+ string += "\n{:}".format(xstring)
+ return string, discrepancy
+
+ def set_tau(self, tau_max, tau_min, epoch_ratio):
+ assert (
+ epoch_ratio >= 0 and epoch_ratio <= 1
+ ), "invalid epoch-ratio : {:}".format(epoch_ratio)
+ tau = tau_min + (tau_max - tau_min) * (1 + math.cos(math.pi * epoch_ratio)) / 2
+ self.tau = tau
+
+ def get_message(self):
+ return self.message
+
+ def forward(self, inputs):
+ if self.search_mode == "basic":
+ return self.basic_forward(inputs)
+ elif self.search_mode == "search":
+ return self.search_forward(inputs)
+ else:
+ raise ValueError("invalid search_mode = {:}".format(self.search_mode))
+
+ def search_forward(self, inputs):
+ flop_depth_probs = nn.functional.softmax(self.depth_attentions, dim=1)
+ flop_depth_probs = torch.flip(
+ torch.cumsum(torch.flip(flop_depth_probs, [1]), 1), [1]
+ )
+ selected_depth_probs = select2withP(self.depth_attentions, self.tau, True)
+
+ x, flops = inputs, []
+ feature_maps = []
+ for i, layer in enumerate(self.layers):
+ layer_i = layer(x)
+ feature_maps.append(layer_i)
+ if i in self.depth_info: # aggregate the information
+ choices = self.depth_info[i]["choices"]
+ xstagei = self.depth_info[i]["stage"]
+ possible_tensors = []
+ for tempi, A in enumerate(choices):
+ xtensor = feature_maps[A]
+ possible_tensors.append(xtensor)
+ weighted_sum = sum(
+ xtensor * W
+ for xtensor, W in zip(
+ possible_tensors, selected_depth_probs[xstagei]
+ )
+ )
+ x = weighted_sum
+ else:
+ x = layer_i
+
+ if i in self.depth_at_i:
+ xstagei, xatti = self.depth_at_i[i]
+ # print ('layer-{:03d}, stage={:}, att={:}, prob={:}, flop={:}'.format(i, xstagei, xatti, flop_depth_probs[xstagei, xatti].item(), layer.get_flops(1e6)))
+ x_expected_flop = flop_depth_probs[xstagei, xatti] * layer.get_flops(
+ 1e6
+ )
+ else:
+ x_expected_flop = layer.get_flops(1e6)
+ flops.append(x_expected_flop)
+ flops.append(
+ (self.classifier.in_features * self.classifier.out_features * 1.0 / 1e6)
+ )
+
+ features = self.avgpool(x)
+ features = features.view(features.size(0), -1)
+ logits = linear_forward(features, self.classifier)
+ return logits, torch.stack([sum(flops)])
+
+ def basic_forward(self, inputs):
+ if self.InShape is None:
+ self.InShape = (inputs.size(-2), inputs.size(-1))
+ x = inputs
+ for i, layer in enumerate(self.layers):
+ x = layer(x)
+ features = self.avgpool(x)
+ features = features.view(features.size(0), -1)
+ logits = self.classifier(features)
+ return features, logits
diff --git a/AutoDL-Projects/xautodl/models/shape_searchs/SearchCifarResNet_width.py b/AutoDL-Projects/xautodl/models/shape_searchs/SearchCifarResNet_width.py
new file mode 100644
index 0000000..61bee6f
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/shape_searchs/SearchCifarResNet_width.py
@@ -0,0 +1,619 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019 #
+##################################################
+import math, torch
+import torch.nn as nn
+from ..initialization import initialize_resnet
+from ..SharedUtils import additive_func
+from .SoftSelect import select2withP, ChannelWiseInter
+from .SoftSelect import linear_forward
+from .SoftSelect import get_width_choices as get_choices
+
+
+def conv_forward(inputs, conv, choices):
+ iC = conv.in_channels
+ fill_size = list(inputs.size())
+ fill_size[1] = iC - fill_size[1]
+ filled = torch.zeros(fill_size, device=inputs.device)
+ xinputs = torch.cat((inputs, filled), dim=1)
+ outputs = conv(xinputs)
+ selecteds = [outputs[:, :oC] for oC in choices]
+ return selecteds
+
+
+class ConvBNReLU(nn.Module):
+ num_conv = 1
+
+ def __init__(
+ self, nIn, nOut, kernel, stride, padding, bias, has_avg, has_bn, has_relu
+ ):
+ super(ConvBNReLU, self).__init__()
+ self.InShape = None
+ self.OutShape = None
+ self.choices = get_choices(nOut)
+ self.register_buffer("choices_tensor", torch.Tensor(self.choices))
+
+ if has_avg:
+ self.avg = nn.AvgPool2d(kernel_size=2, stride=2, padding=0)
+ else:
+ self.avg = None
+ self.conv = nn.Conv2d(
+ nIn,
+ nOut,
+ kernel_size=kernel,
+ stride=stride,
+ padding=padding,
+ dilation=1,
+ groups=1,
+ bias=bias,
+ )
+ # if has_bn : self.bn = nn.BatchNorm2d(nOut)
+ # else : self.bn = None
+ self.has_bn = has_bn
+ self.BNs = nn.ModuleList()
+ for i, _out in enumerate(self.choices):
+ self.BNs.append(nn.BatchNorm2d(_out))
+ if has_relu:
+ self.relu = nn.ReLU(inplace=True)
+ else:
+ self.relu = None
+ self.in_dim = nIn
+ self.out_dim = nOut
+ self.search_mode = "basic"
+
+ def get_flops(self, channels, check_range=True, divide=1):
+ iC, oC = channels
+ if check_range:
+ assert (
+ iC <= self.conv.in_channels and oC <= self.conv.out_channels
+ ), "{:} vs {:} | {:} vs {:}".format(
+ iC, self.conv.in_channels, oC, self.conv.out_channels
+ )
+ assert (
+ isinstance(self.InShape, tuple) and len(self.InShape) == 2
+ ), "invalid in-shape : {:}".format(self.InShape)
+ assert (
+ isinstance(self.OutShape, tuple) and len(self.OutShape) == 2
+ ), "invalid out-shape : {:}".format(self.OutShape)
+ # conv_per_position_flops = self.conv.kernel_size[0] * self.conv.kernel_size[1] * iC * oC / self.conv.groups
+ conv_per_position_flops = (
+ self.conv.kernel_size[0] * self.conv.kernel_size[1] * 1.0 / self.conv.groups
+ )
+ all_positions = self.OutShape[0] * self.OutShape[1]
+ flops = (conv_per_position_flops * all_positions / divide) * iC * oC
+ if self.conv.bias is not None:
+ flops += all_positions / divide
+ return flops
+
+ def get_range(self):
+ return [self.choices]
+
+ def forward(self, inputs):
+ if self.search_mode == "basic":
+ return self.basic_forward(inputs)
+ elif self.search_mode == "search":
+ return self.search_forward(inputs)
+ else:
+ raise ValueError("invalid search_mode = {:}".format(self.search_mode))
+
+ def search_forward(self, tuple_inputs):
+ assert (
+ isinstance(tuple_inputs, tuple) and len(tuple_inputs) == 5
+ ), "invalid type input : {:}".format(type(tuple_inputs))
+ inputs, expected_inC, probability, index, prob = tuple_inputs
+ index, prob = torch.squeeze(index).tolist(), torch.squeeze(prob)
+ probability = torch.squeeze(probability)
+ assert len(index) == 2, "invalid length : {:}".format(index)
+ # compute expected flop
+ # coordinates = torch.arange(self.x_range[0], self.x_range[1]+1).type_as(probability)
+ expected_outC = (self.choices_tensor * probability).sum()
+ expected_flop = self.get_flops([expected_inC, expected_outC], False, 1e6)
+ if self.avg:
+ out = self.avg(inputs)
+ else:
+ out = inputs
+ # convolutional layer
+ out_convs = conv_forward(out, self.conv, [self.choices[i] for i in index])
+ out_bns = [self.BNs[idx](out_conv) for idx, out_conv in zip(index, out_convs)]
+ # merge
+ out_channel = max([x.size(1) for x in out_bns])
+ outA = ChannelWiseInter(out_bns[0], out_channel)
+ outB = ChannelWiseInter(out_bns[1], out_channel)
+ out = outA * prob[0] + outB * prob[1]
+ # out = additive_func(out_bns[0]*prob[0], out_bns[1]*prob[1])
+
+ if self.relu:
+ out = self.relu(out)
+ else:
+ out = out
+ return out, expected_outC, expected_flop
+
+ def basic_forward(self, inputs):
+ if self.avg:
+ out = self.avg(inputs)
+ else:
+ out = inputs
+ conv = self.conv(out)
+ if self.has_bn:
+ out = self.BNs[-1](conv)
+ else:
+ out = conv
+ if self.relu:
+ out = self.relu(out)
+ else:
+ out = out
+ if self.InShape is None:
+ self.InShape = (inputs.size(-2), inputs.size(-1))
+ self.OutShape = (out.size(-2), out.size(-1))
+ return out
+
+
+class ResNetBasicblock(nn.Module):
+ expansion = 1
+ num_conv = 2
+
+ def __init__(self, inplanes, planes, stride):
+ super(ResNetBasicblock, self).__init__()
+ assert stride == 1 or stride == 2, "invalid stride {:}".format(stride)
+ self.conv_a = ConvBNReLU(
+ inplanes,
+ planes,
+ 3,
+ stride,
+ 1,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=True,
+ )
+ self.conv_b = ConvBNReLU(
+ planes, planes, 3, 1, 1, False, has_avg=False, has_bn=True, has_relu=False
+ )
+ if stride == 2:
+ self.downsample = ConvBNReLU(
+ inplanes,
+ planes,
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=True,
+ has_bn=False,
+ has_relu=False,
+ )
+ elif inplanes != planes:
+ self.downsample = ConvBNReLU(
+ inplanes,
+ planes,
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=False,
+ )
+ else:
+ self.downsample = None
+ self.out_dim = planes
+ self.search_mode = "basic"
+
+ def get_range(self):
+ return self.conv_a.get_range() + self.conv_b.get_range()
+
+ def get_flops(self, channels):
+ assert len(channels) == 3, "invalid channels : {:}".format(channels)
+ flop_A = self.conv_a.get_flops([channels[0], channels[1]])
+ flop_B = self.conv_b.get_flops([channels[1], channels[2]])
+ if hasattr(self.downsample, "get_flops"):
+ flop_C = self.downsample.get_flops([channels[0], channels[-1]])
+ else:
+ flop_C = 0
+ if (
+ channels[0] != channels[-1] and self.downsample is None
+ ): # this short-cut will be added during the infer-train
+ flop_C = (
+ channels[0]
+ * channels[-1]
+ * self.conv_b.OutShape[0]
+ * self.conv_b.OutShape[1]
+ )
+ return flop_A + flop_B + flop_C
+
+ def forward(self, inputs):
+ if self.search_mode == "basic":
+ return self.basic_forward(inputs)
+ elif self.search_mode == "search":
+ return self.search_forward(inputs)
+ else:
+ raise ValueError("invalid search_mode = {:}".format(self.search_mode))
+
+ def search_forward(self, tuple_inputs):
+ assert (
+ isinstance(tuple_inputs, tuple) and len(tuple_inputs) == 5
+ ), "invalid type input : {:}".format(type(tuple_inputs))
+ inputs, expected_inC, probability, indexes, probs = tuple_inputs
+ assert indexes.size(0) == 2 and probs.size(0) == 2 and probability.size(0) == 2
+ out_a, expected_inC_a, expected_flop_a = self.conv_a(
+ (inputs, expected_inC, probability[0], indexes[0], probs[0])
+ )
+ out_b, expected_inC_b, expected_flop_b = self.conv_b(
+ (out_a, expected_inC_a, probability[1], indexes[1], probs[1])
+ )
+ if self.downsample is not None:
+ residual, _, expected_flop_c = self.downsample(
+ (inputs, expected_inC, probability[1], indexes[1], probs[1])
+ )
+ else:
+ residual, expected_flop_c = inputs, 0
+ out = additive_func(residual, out_b)
+ return (
+ nn.functional.relu(out, inplace=True),
+ expected_inC_b,
+ sum([expected_flop_a, expected_flop_b, expected_flop_c]),
+ )
+
+ def basic_forward(self, inputs):
+ basicblock = self.conv_a(inputs)
+ basicblock = self.conv_b(basicblock)
+ if self.downsample is not None:
+ residual = self.downsample(inputs)
+ else:
+ residual = inputs
+ out = additive_func(residual, basicblock)
+ return nn.functional.relu(out, inplace=True)
+
+
+class ResNetBottleneck(nn.Module):
+ expansion = 4
+ num_conv = 3
+
+ def __init__(self, inplanes, planes, stride):
+ super(ResNetBottleneck, self).__init__()
+ assert stride == 1 or stride == 2, "invalid stride {:}".format(stride)
+ self.conv_1x1 = ConvBNReLU(
+ inplanes, planes, 1, 1, 0, False, has_avg=False, has_bn=True, has_relu=True
+ )
+ self.conv_3x3 = ConvBNReLU(
+ planes,
+ planes,
+ 3,
+ stride,
+ 1,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=True,
+ )
+ self.conv_1x4 = ConvBNReLU(
+ planes,
+ planes * self.expansion,
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=False,
+ )
+ if stride == 2:
+ self.downsample = ConvBNReLU(
+ inplanes,
+ planes * self.expansion,
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=True,
+ has_bn=False,
+ has_relu=False,
+ )
+ elif inplanes != planes * self.expansion:
+ self.downsample = ConvBNReLU(
+ inplanes,
+ planes * self.expansion,
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=False,
+ )
+ else:
+ self.downsample = None
+ self.out_dim = planes * self.expansion
+ self.search_mode = "basic"
+
+ def get_range(self):
+ return (
+ self.conv_1x1.get_range()
+ + self.conv_3x3.get_range()
+ + self.conv_1x4.get_range()
+ )
+
+ def get_flops(self, channels):
+ assert len(channels) == 4, "invalid channels : {:}".format(channels)
+ flop_A = self.conv_1x1.get_flops([channels[0], channels[1]])
+ flop_B = self.conv_3x3.get_flops([channels[1], channels[2]])
+ flop_C = self.conv_1x4.get_flops([channels[2], channels[3]])
+ if hasattr(self.downsample, "get_flops"):
+ flop_D = self.downsample.get_flops([channels[0], channels[-1]])
+ else:
+ flop_D = 0
+ if (
+ channels[0] != channels[-1] and self.downsample is None
+ ): # this short-cut will be added during the infer-train
+ flop_D = (
+ channels[0]
+ * channels[-1]
+ * self.conv_1x4.OutShape[0]
+ * self.conv_1x4.OutShape[1]
+ )
+ return flop_A + flop_B + flop_C + flop_D
+
+ def forward(self, inputs):
+ if self.search_mode == "basic":
+ return self.basic_forward(inputs)
+ elif self.search_mode == "search":
+ return self.search_forward(inputs)
+ else:
+ raise ValueError("invalid search_mode = {:}".format(self.search_mode))
+
+ def basic_forward(self, inputs):
+ bottleneck = self.conv_1x1(inputs)
+ bottleneck = self.conv_3x3(bottleneck)
+ bottleneck = self.conv_1x4(bottleneck)
+ if self.downsample is not None:
+ residual = self.downsample(inputs)
+ else:
+ residual = inputs
+ out = additive_func(residual, bottleneck)
+ return nn.functional.relu(out, inplace=True)
+
+ def search_forward(self, tuple_inputs):
+ assert (
+ isinstance(tuple_inputs, tuple) and len(tuple_inputs) == 5
+ ), "invalid type input : {:}".format(type(tuple_inputs))
+ inputs, expected_inC, probability, indexes, probs = tuple_inputs
+ assert indexes.size(0) == 3 and probs.size(0) == 3 and probability.size(0) == 3
+ out_1x1, expected_inC_1x1, expected_flop_1x1 = self.conv_1x1(
+ (inputs, expected_inC, probability[0], indexes[0], probs[0])
+ )
+ out_3x3, expected_inC_3x3, expected_flop_3x3 = self.conv_3x3(
+ (out_1x1, expected_inC_1x1, probability[1], indexes[1], probs[1])
+ )
+ out_1x4, expected_inC_1x4, expected_flop_1x4 = self.conv_1x4(
+ (out_3x3, expected_inC_3x3, probability[2], indexes[2], probs[2])
+ )
+ if self.downsample is not None:
+ residual, _, expected_flop_c = self.downsample(
+ (inputs, expected_inC, probability[2], indexes[2], probs[2])
+ )
+ else:
+ residual, expected_flop_c = inputs, 0
+ out = additive_func(residual, out_1x4)
+ return (
+ nn.functional.relu(out, inplace=True),
+ expected_inC_1x4,
+ sum(
+ [
+ expected_flop_1x1,
+ expected_flop_3x3,
+ expected_flop_1x4,
+ expected_flop_c,
+ ]
+ ),
+ )
+
+
+class SearchWidthCifarResNet(nn.Module):
+ def __init__(self, block_name, depth, num_classes):
+ super(SearchWidthCifarResNet, self).__init__()
+
+ # Model type specifies number of layers for CIFAR-10 and CIFAR-100 model
+ if block_name == "ResNetBasicblock":
+ block = ResNetBasicblock
+ assert (depth - 2) % 6 == 0, "depth should be one of 20, 32, 44, 56, 110"
+ layer_blocks = (depth - 2) // 6
+ elif block_name == "ResNetBottleneck":
+ block = ResNetBottleneck
+ assert (depth - 2) % 9 == 0, "depth should be one of 164"
+ layer_blocks = (depth - 2) // 9
+ else:
+ raise ValueError("invalid block : {:}".format(block_name))
+
+ self.message = (
+ "SearchWidthCifarResNet : Depth : {:} , Layers for each block : {:}".format(
+ depth, layer_blocks
+ )
+ )
+ self.num_classes = num_classes
+ self.channels = [16]
+ self.layers = nn.ModuleList(
+ [
+ ConvBNReLU(
+ 3, 16, 3, 1, 1, False, has_avg=False, has_bn=True, has_relu=True
+ )
+ ]
+ )
+ self.InShape = None
+ for stage in range(3):
+ for iL in range(layer_blocks):
+ iC = self.channels[-1]
+ planes = 16 * (2 ** stage)
+ stride = 2 if stage > 0 and iL == 0 else 1
+ module = block(iC, planes, stride)
+ self.channels.append(module.out_dim)
+ self.layers.append(module)
+ self.message += "\nstage={:}, ilayer={:02d}/{:02d}, block={:03d}, iC={:3d}, oC={:3d}, stride={:}".format(
+ stage,
+ iL,
+ layer_blocks,
+ len(self.layers) - 1,
+ iC,
+ module.out_dim,
+ stride,
+ )
+
+ self.avgpool = nn.AvgPool2d(8)
+ self.classifier = nn.Linear(module.out_dim, num_classes)
+ self.InShape = None
+ self.tau = -1
+ self.search_mode = "basic"
+ # assert sum(x.num_conv for x in self.layers) + 1 == depth, 'invalid depth check {:} vs {:}'.format(sum(x.num_conv for x in self.layers)+1, depth)
+
+ # parameters for width
+ self.Ranges = []
+ self.layer2indexRange = []
+ for i, layer in enumerate(self.layers):
+ start_index = len(self.Ranges)
+ self.Ranges += layer.get_range()
+ self.layer2indexRange.append((start_index, len(self.Ranges)))
+ assert len(self.Ranges) + 1 == depth, "invalid depth check {:} vs {:}".format(
+ len(self.Ranges) + 1, depth
+ )
+
+ self.register_parameter(
+ "width_attentions",
+ nn.Parameter(torch.Tensor(len(self.Ranges), get_choices(None))),
+ )
+ nn.init.normal_(self.width_attentions, 0, 0.01)
+ self.apply(initialize_resnet)
+
+ def arch_parameters(self):
+ return [self.width_attentions]
+
+ def base_parameters(self):
+ return (
+ list(self.layers.parameters())
+ + list(self.avgpool.parameters())
+ + list(self.classifier.parameters())
+ )
+
+ def get_flop(self, mode, config_dict, extra_info):
+ if config_dict is not None:
+ config_dict = config_dict.copy()
+ # weights = [F.softmax(x, dim=0) for x in self.width_attentions]
+ channels = [3]
+ for i, weight in enumerate(self.width_attentions):
+ if mode == "genotype":
+ with torch.no_grad():
+ probe = nn.functional.softmax(weight, dim=0)
+ C = self.Ranges[i][torch.argmax(probe).item()]
+ elif mode == "max":
+ C = self.Ranges[i][-1]
+ elif mode == "fix":
+ C = int(math.sqrt(extra_info) * self.Ranges[i][-1])
+ elif mode == "random":
+ assert isinstance(extra_info, float), "invalid extra_info : {:}".format(
+ extra_info
+ )
+ with torch.no_grad():
+ prob = nn.functional.softmax(weight, dim=0)
+ approximate_C = int(math.sqrt(extra_info) * self.Ranges[i][-1])
+ for j in range(prob.size(0)):
+ prob[j] = 1 / (
+ abs(j - (approximate_C - self.Ranges[i][j])) + 0.2
+ )
+ C = self.Ranges[i][torch.multinomial(prob, 1, False).item()]
+ else:
+ raise ValueError("invalid mode : {:}".format(mode))
+ channels.append(C)
+ flop = 0
+ for i, layer in enumerate(self.layers):
+ s, e = self.layer2indexRange[i]
+ xchl = tuple(channels[s : e + 1])
+ flop += layer.get_flops(xchl)
+ # the last fc layer
+ flop += channels[-1] * self.classifier.out_features
+ if config_dict is None:
+ return flop / 1e6
+ else:
+ config_dict["xchannels"] = channels
+ config_dict["super_type"] = "infer-width"
+ config_dict["estimated_FLOP"] = flop / 1e6
+ return flop / 1e6, config_dict
+
+ def get_arch_info(self):
+ string = "for width, there are {:} attention probabilities.".format(
+ len(self.width_attentions)
+ )
+ discrepancy = []
+ with torch.no_grad():
+ for i, att in enumerate(self.width_attentions):
+ prob = nn.functional.softmax(att, dim=0)
+ prob = prob.cpu()
+ selc = prob.argmax().item()
+ prob = prob.tolist()
+ prob = ["{:.3f}".format(x) for x in prob]
+ xstring = "{:03d}/{:03d}-th : {:}".format(
+ i, len(self.width_attentions), " ".join(prob)
+ )
+ logt = ["{:.3f}".format(x) for x in att.cpu().tolist()]
+ xstring += " || {:52s}".format(" ".join(logt))
+ prob = sorted([float(x) for x in prob])
+ disc = prob[-1] - prob[-2]
+ xstring += " || dis={:.2f} || select={:}/{:}".format(
+ disc, selc, len(prob)
+ )
+ discrepancy.append(disc)
+ string += "\n{:}".format(xstring)
+ return string, discrepancy
+
+ def set_tau(self, tau_max, tau_min, epoch_ratio):
+ assert (
+ epoch_ratio >= 0 and epoch_ratio <= 1
+ ), "invalid epoch-ratio : {:}".format(epoch_ratio)
+ tau = tau_min + (tau_max - tau_min) * (1 + math.cos(math.pi * epoch_ratio)) / 2
+ self.tau = tau
+
+ def get_message(self):
+ return self.message
+
+ def forward(self, inputs):
+ if self.search_mode == "basic":
+ return self.basic_forward(inputs)
+ elif self.search_mode == "search":
+ return self.search_forward(inputs)
+ else:
+ raise ValueError("invalid search_mode = {:}".format(self.search_mode))
+
+ def search_forward(self, inputs):
+ flop_probs = nn.functional.softmax(self.width_attentions, dim=1)
+ selected_widths, selected_probs = select2withP(self.width_attentions, self.tau)
+ with torch.no_grad():
+ selected_widths = selected_widths.cpu()
+
+ x, last_channel_idx, expected_inC, flops = inputs, 0, 3, []
+ for i, layer in enumerate(self.layers):
+ selected_w_index = selected_widths[
+ last_channel_idx : last_channel_idx + layer.num_conv
+ ]
+ selected_w_probs = selected_probs[
+ last_channel_idx : last_channel_idx + layer.num_conv
+ ]
+ layer_prob = flop_probs[
+ last_channel_idx : last_channel_idx + layer.num_conv
+ ]
+ x, expected_inC, expected_flop = layer(
+ (x, expected_inC, layer_prob, selected_w_index, selected_w_probs)
+ )
+ last_channel_idx += layer.num_conv
+ flops.append(expected_flop)
+ flops.append(expected_inC * (self.classifier.out_features * 1.0 / 1e6))
+ features = self.avgpool(x)
+ features = features.view(features.size(0), -1)
+ logits = linear_forward(features, self.classifier)
+ return logits, torch.stack([sum(flops)])
+
+ def basic_forward(self, inputs):
+ if self.InShape is None:
+ self.InShape = (inputs.size(-2), inputs.size(-1))
+ x = inputs
+ for i, layer in enumerate(self.layers):
+ x = layer(x)
+ features = self.avgpool(x)
+ features = features.view(features.size(0), -1)
+ logits = self.classifier(features)
+ return features, logits
diff --git a/AutoDL-Projects/xautodl/models/shape_searchs/SearchImagenetResNet.py b/AutoDL-Projects/xautodl/models/shape_searchs/SearchImagenetResNet.py
new file mode 100644
index 0000000..11da09a
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/shape_searchs/SearchImagenetResNet.py
@@ -0,0 +1,766 @@
+import math, torch
+from collections import OrderedDict
+from bisect import bisect_right
+import torch.nn as nn
+from ..initialization import initialize_resnet
+from ..SharedUtils import additive_func
+from .SoftSelect import select2withP, ChannelWiseInter
+from .SoftSelect import linear_forward
+from .SoftSelect import get_width_choices
+
+
+def get_depth_choices(layers):
+ min_depth = min(layers)
+ info = {"num": min_depth}
+ for i, depth in enumerate(layers):
+ choices = []
+ for j in range(1, min_depth + 1):
+ choices.append(int(float(depth) * j / min_depth))
+ info[i] = choices
+ return info
+
+
+def conv_forward(inputs, conv, choices):
+ iC = conv.in_channels
+ fill_size = list(inputs.size())
+ fill_size[1] = iC - fill_size[1]
+ filled = torch.zeros(fill_size, device=inputs.device)
+ xinputs = torch.cat((inputs, filled), dim=1)
+ outputs = conv(xinputs)
+ selecteds = [outputs[:, :oC] for oC in choices]
+ return selecteds
+
+
+class ConvBNReLU(nn.Module):
+ num_conv = 1
+
+ def __init__(
+ self,
+ nIn,
+ nOut,
+ kernel,
+ stride,
+ padding,
+ bias,
+ has_avg,
+ has_bn,
+ has_relu,
+ last_max_pool=False,
+ ):
+ super(ConvBNReLU, self).__init__()
+ self.InShape = None
+ self.OutShape = None
+ self.choices = get_width_choices(nOut)
+ self.register_buffer("choices_tensor", torch.Tensor(self.choices))
+
+ if has_avg:
+ self.avg = nn.AvgPool2d(kernel_size=2, stride=2, padding=0)
+ else:
+ self.avg = None
+ self.conv = nn.Conv2d(
+ nIn,
+ nOut,
+ kernel_size=kernel,
+ stride=stride,
+ padding=padding,
+ dilation=1,
+ groups=1,
+ bias=bias,
+ )
+ # if has_bn : self.bn = nn.BatchNorm2d(nOut)
+ # else : self.bn = None
+ self.has_bn = has_bn
+ self.BNs = nn.ModuleList()
+ for i, _out in enumerate(self.choices):
+ self.BNs.append(nn.BatchNorm2d(_out))
+ if has_relu:
+ self.relu = nn.ReLU(inplace=True)
+ else:
+ self.relu = None
+
+ if last_max_pool:
+ self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
+ else:
+ self.maxpool = None
+ self.in_dim = nIn
+ self.out_dim = nOut
+ self.search_mode = "basic"
+
+ def get_flops(self, channels, check_range=True, divide=1):
+ iC, oC = channels
+ if check_range:
+ assert (
+ iC <= self.conv.in_channels and oC <= self.conv.out_channels
+ ), "{:} vs {:} | {:} vs {:}".format(
+ iC, self.conv.in_channels, oC, self.conv.out_channels
+ )
+ assert (
+ isinstance(self.InShape, tuple) and len(self.InShape) == 2
+ ), "invalid in-shape : {:}".format(self.InShape)
+ assert (
+ isinstance(self.OutShape, tuple) and len(self.OutShape) == 2
+ ), "invalid out-shape : {:}".format(self.OutShape)
+ # conv_per_position_flops = self.conv.kernel_size[0] * self.conv.kernel_size[1] * iC * oC / self.conv.groups
+ conv_per_position_flops = (
+ self.conv.kernel_size[0] * self.conv.kernel_size[1] * 1.0 / self.conv.groups
+ )
+ all_positions = self.OutShape[0] * self.OutShape[1]
+ flops = (conv_per_position_flops * all_positions / divide) * iC * oC
+ if self.conv.bias is not None:
+ flops += all_positions / divide
+ return flops
+
+ def get_range(self):
+ return [self.choices]
+
+ def forward(self, inputs):
+ if self.search_mode == "basic":
+ return self.basic_forward(inputs)
+ elif self.search_mode == "search":
+ return self.search_forward(inputs)
+ else:
+ raise ValueError("invalid search_mode = {:}".format(self.search_mode))
+
+ def search_forward(self, tuple_inputs):
+ assert (
+ isinstance(tuple_inputs, tuple) and len(tuple_inputs) == 5
+ ), "invalid type input : {:}".format(type(tuple_inputs))
+ inputs, expected_inC, probability, index, prob = tuple_inputs
+ index, prob = torch.squeeze(index).tolist(), torch.squeeze(prob)
+ probability = torch.squeeze(probability)
+ assert len(index) == 2, "invalid length : {:}".format(index)
+ # compute expected flop
+ # coordinates = torch.arange(self.x_range[0], self.x_range[1]+1).type_as(probability)
+ expected_outC = (self.choices_tensor * probability).sum()
+ expected_flop = self.get_flops([expected_inC, expected_outC], False, 1e6)
+ if self.avg:
+ out = self.avg(inputs)
+ else:
+ out = inputs
+ # convolutional layer
+ out_convs = conv_forward(out, self.conv, [self.choices[i] for i in index])
+ out_bns = [self.BNs[idx](out_conv) for idx, out_conv in zip(index, out_convs)]
+ # merge
+ out_channel = max([x.size(1) for x in out_bns])
+ outA = ChannelWiseInter(out_bns[0], out_channel)
+ outB = ChannelWiseInter(out_bns[1], out_channel)
+ out = outA * prob[0] + outB * prob[1]
+ # out = additive_func(out_bns[0]*prob[0], out_bns[1]*prob[1])
+
+ if self.relu:
+ out = self.relu(out)
+ if self.maxpool:
+ out = self.maxpool(out)
+ return out, expected_outC, expected_flop
+
+ def basic_forward(self, inputs):
+ if self.avg:
+ out = self.avg(inputs)
+ else:
+ out = inputs
+ conv = self.conv(out)
+ if self.has_bn:
+ out = self.BNs[-1](conv)
+ else:
+ out = conv
+ if self.relu:
+ out = self.relu(out)
+ else:
+ out = out
+ if self.InShape is None:
+ self.InShape = (inputs.size(-2), inputs.size(-1))
+ self.OutShape = (out.size(-2), out.size(-1))
+ if self.maxpool:
+ out = self.maxpool(out)
+ return out
+
+
+class ResNetBasicblock(nn.Module):
+ expansion = 1
+ num_conv = 2
+
+ def __init__(self, inplanes, planes, stride):
+ super(ResNetBasicblock, self).__init__()
+ assert stride == 1 or stride == 2, "invalid stride {:}".format(stride)
+ self.conv_a = ConvBNReLU(
+ inplanes,
+ planes,
+ 3,
+ stride,
+ 1,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=True,
+ )
+ self.conv_b = ConvBNReLU(
+ planes, planes, 3, 1, 1, False, has_avg=False, has_bn=True, has_relu=False
+ )
+ if stride == 2:
+ self.downsample = ConvBNReLU(
+ inplanes,
+ planes,
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=True,
+ has_bn=True,
+ has_relu=False,
+ )
+ elif inplanes != planes:
+ self.downsample = ConvBNReLU(
+ inplanes,
+ planes,
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=False,
+ )
+ else:
+ self.downsample = None
+ self.out_dim = planes
+ self.search_mode = "basic"
+
+ def get_range(self):
+ return self.conv_a.get_range() + self.conv_b.get_range()
+
+ def get_flops(self, channels):
+ assert len(channels) == 3, "invalid channels : {:}".format(channels)
+ flop_A = self.conv_a.get_flops([channels[0], channels[1]])
+ flop_B = self.conv_b.get_flops([channels[1], channels[2]])
+ if hasattr(self.downsample, "get_flops"):
+ flop_C = self.downsample.get_flops([channels[0], channels[-1]])
+ else:
+ flop_C = 0
+ if (
+ channels[0] != channels[-1] and self.downsample is None
+ ): # this short-cut will be added during the infer-train
+ flop_C = (
+ channels[0]
+ * channels[-1]
+ * self.conv_b.OutShape[0]
+ * self.conv_b.OutShape[1]
+ )
+ return flop_A + flop_B + flop_C
+
+ def forward(self, inputs):
+ if self.search_mode == "basic":
+ return self.basic_forward(inputs)
+ elif self.search_mode == "search":
+ return self.search_forward(inputs)
+ else:
+ raise ValueError("invalid search_mode = {:}".format(self.search_mode))
+
+ def search_forward(self, tuple_inputs):
+ assert (
+ isinstance(tuple_inputs, tuple) and len(tuple_inputs) == 5
+ ), "invalid type input : {:}".format(type(tuple_inputs))
+ inputs, expected_inC, probability, indexes, probs = tuple_inputs
+ assert indexes.size(0) == 2 and probs.size(0) == 2 and probability.size(0) == 2
+ # import pdb; pdb.set_trace()
+ out_a, expected_inC_a, expected_flop_a = self.conv_a(
+ (inputs, expected_inC, probability[0], indexes[0], probs[0])
+ )
+ out_b, expected_inC_b, expected_flop_b = self.conv_b(
+ (out_a, expected_inC_a, probability[1], indexes[1], probs[1])
+ )
+ if self.downsample is not None:
+ residual, _, expected_flop_c = self.downsample(
+ (inputs, expected_inC, probability[1], indexes[1], probs[1])
+ )
+ else:
+ residual, expected_flop_c = inputs, 0
+ out = additive_func(residual, out_b)
+ return (
+ nn.functional.relu(out, inplace=True),
+ expected_inC_b,
+ sum([expected_flop_a, expected_flop_b, expected_flop_c]),
+ )
+
+ def basic_forward(self, inputs):
+ basicblock = self.conv_a(inputs)
+ basicblock = self.conv_b(basicblock)
+ if self.downsample is not None:
+ residual = self.downsample(inputs)
+ else:
+ residual = inputs
+ out = additive_func(residual, basicblock)
+ return nn.functional.relu(out, inplace=True)
+
+
+class ResNetBottleneck(nn.Module):
+ expansion = 4
+ num_conv = 3
+
+ def __init__(self, inplanes, planes, stride):
+ super(ResNetBottleneck, self).__init__()
+ assert stride == 1 or stride == 2, "invalid stride {:}".format(stride)
+ self.conv_1x1 = ConvBNReLU(
+ inplanes, planes, 1, 1, 0, False, has_avg=False, has_bn=True, has_relu=True
+ )
+ self.conv_3x3 = ConvBNReLU(
+ planes,
+ planes,
+ 3,
+ stride,
+ 1,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=True,
+ )
+ self.conv_1x4 = ConvBNReLU(
+ planes,
+ planes * self.expansion,
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=False,
+ )
+ if stride == 2:
+ self.downsample = ConvBNReLU(
+ inplanes,
+ planes * self.expansion,
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=True,
+ has_bn=True,
+ has_relu=False,
+ )
+ elif inplanes != planes * self.expansion:
+ self.downsample = ConvBNReLU(
+ inplanes,
+ planes * self.expansion,
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=False,
+ )
+ else:
+ self.downsample = None
+ self.out_dim = planes * self.expansion
+ self.search_mode = "basic"
+
+ def get_range(self):
+ return (
+ self.conv_1x1.get_range()
+ + self.conv_3x3.get_range()
+ + self.conv_1x4.get_range()
+ )
+
+ def get_flops(self, channels):
+ assert len(channels) == 4, "invalid channels : {:}".format(channels)
+ flop_A = self.conv_1x1.get_flops([channels[0], channels[1]])
+ flop_B = self.conv_3x3.get_flops([channels[1], channels[2]])
+ flop_C = self.conv_1x4.get_flops([channels[2], channels[3]])
+ if hasattr(self.downsample, "get_flops"):
+ flop_D = self.downsample.get_flops([channels[0], channels[-1]])
+ else:
+ flop_D = 0
+ if (
+ channels[0] != channels[-1] and self.downsample is None
+ ): # this short-cut will be added during the infer-train
+ flop_D = (
+ channels[0]
+ * channels[-1]
+ * self.conv_1x4.OutShape[0]
+ * self.conv_1x4.OutShape[1]
+ )
+ return flop_A + flop_B + flop_C + flop_D
+
+ def forward(self, inputs):
+ if self.search_mode == "basic":
+ return self.basic_forward(inputs)
+ elif self.search_mode == "search":
+ return self.search_forward(inputs)
+ else:
+ raise ValueError("invalid search_mode = {:}".format(self.search_mode))
+
+ def basic_forward(self, inputs):
+ bottleneck = self.conv_1x1(inputs)
+ bottleneck = self.conv_3x3(bottleneck)
+ bottleneck = self.conv_1x4(bottleneck)
+ if self.downsample is not None:
+ residual = self.downsample(inputs)
+ else:
+ residual = inputs
+ out = additive_func(residual, bottleneck)
+ return nn.functional.relu(out, inplace=True)
+
+ def search_forward(self, tuple_inputs):
+ assert (
+ isinstance(tuple_inputs, tuple) and len(tuple_inputs) == 5
+ ), "invalid type input : {:}".format(type(tuple_inputs))
+ inputs, expected_inC, probability, indexes, probs = tuple_inputs
+ assert indexes.size(0) == 3 and probs.size(0) == 3 and probability.size(0) == 3
+ out_1x1, expected_inC_1x1, expected_flop_1x1 = self.conv_1x1(
+ (inputs, expected_inC, probability[0], indexes[0], probs[0])
+ )
+ out_3x3, expected_inC_3x3, expected_flop_3x3 = self.conv_3x3(
+ (out_1x1, expected_inC_1x1, probability[1], indexes[1], probs[1])
+ )
+ out_1x4, expected_inC_1x4, expected_flop_1x4 = self.conv_1x4(
+ (out_3x3, expected_inC_3x3, probability[2], indexes[2], probs[2])
+ )
+ if self.downsample is not None:
+ residual, _, expected_flop_c = self.downsample(
+ (inputs, expected_inC, probability[2], indexes[2], probs[2])
+ )
+ else:
+ residual, expected_flop_c = inputs, 0
+ out = additive_func(residual, out_1x4)
+ return (
+ nn.functional.relu(out, inplace=True),
+ expected_inC_1x4,
+ sum(
+ [
+ expected_flop_1x1,
+ expected_flop_3x3,
+ expected_flop_1x4,
+ expected_flop_c,
+ ]
+ ),
+ )
+
+
+class SearchShapeImagenetResNet(nn.Module):
+ def __init__(self, block_name, layers, deep_stem, num_classes):
+ super(SearchShapeImagenetResNet, self).__init__()
+
+ # Model type specifies number of layers for CIFAR-10 and CIFAR-100 model
+ if block_name == "BasicBlock":
+ block = ResNetBasicblock
+ elif block_name == "Bottleneck":
+ block = ResNetBottleneck
+ else:
+ raise ValueError("invalid block : {:}".format(block_name))
+
+ self.message = (
+ "SearchShapeCifarResNet : Depth : {:} , Layers for each block : {:}".format(
+ sum(layers) * block.num_conv, layers
+ )
+ )
+ self.num_classes = num_classes
+ if not deep_stem:
+ self.layers = nn.ModuleList(
+ [
+ ConvBNReLU(
+ 3,
+ 64,
+ 7,
+ 2,
+ 3,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=True,
+ last_max_pool=True,
+ )
+ ]
+ )
+ self.channels = [64]
+ else:
+ self.layers = nn.ModuleList(
+ [
+ ConvBNReLU(
+ 3, 32, 3, 2, 1, False, has_avg=False, has_bn=True, has_relu=True
+ ),
+ ConvBNReLU(
+ 32,
+ 64,
+ 3,
+ 1,
+ 1,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=True,
+ last_max_pool=True,
+ ),
+ ]
+ )
+ self.channels = [32, 64]
+
+ meta_depth_info = get_depth_choices(layers)
+ self.InShape = None
+ self.depth_info = OrderedDict()
+ self.depth_at_i = OrderedDict()
+ for stage, layer_blocks in enumerate(layers):
+ cur_block_choices = meta_depth_info[stage]
+ assert (
+ cur_block_choices[-1] == layer_blocks
+ ), "stage={:}, {:} vs {:}".format(stage, cur_block_choices, layer_blocks)
+ block_choices, xstart = [], len(self.layers)
+ for iL in range(layer_blocks):
+ iC = self.channels[-1]
+ planes = 64 * (2 ** stage)
+ stride = 2 if stage > 0 and iL == 0 else 1
+ module = block(iC, planes, stride)
+ self.channels.append(module.out_dim)
+ self.layers.append(module)
+ self.message += "\nstage={:}, ilayer={:02d}/{:02d}, block={:03d}, iC={:3d}, oC={:3d}, stride={:}".format(
+ stage,
+ iL,
+ layer_blocks,
+ len(self.layers) - 1,
+ iC,
+ module.out_dim,
+ stride,
+ )
+ # added for depth
+ layer_index = len(self.layers) - 1
+ if iL + 1 in cur_block_choices:
+ block_choices.append(layer_index)
+ if iL + 1 == layer_blocks:
+ self.depth_info[layer_index] = {
+ "choices": block_choices,
+ "stage": stage,
+ "xstart": xstart,
+ }
+ self.depth_info_list = []
+ for xend, info in self.depth_info.items():
+ self.depth_info_list.append((xend, info))
+ xstart, xstage = info["xstart"], info["stage"]
+ for ilayer in range(xstart, xend + 1):
+ idx = bisect_right(info["choices"], ilayer - 1)
+ self.depth_at_i[ilayer] = (xstage, idx)
+
+ self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
+ self.classifier = nn.Linear(module.out_dim, num_classes)
+ self.InShape = None
+ self.tau = -1
+ self.search_mode = "basic"
+ # assert sum(x.num_conv for x in self.layers) + 1 == depth, 'invalid depth check {:} vs {:}'.format(sum(x.num_conv for x in self.layers)+1, depth)
+
+ # parameters for width
+ self.Ranges = []
+ self.layer2indexRange = []
+ for i, layer in enumerate(self.layers):
+ start_index = len(self.Ranges)
+ self.Ranges += layer.get_range()
+ self.layer2indexRange.append((start_index, len(self.Ranges)))
+
+ self.register_parameter(
+ "width_attentions",
+ nn.Parameter(torch.Tensor(len(self.Ranges), get_width_choices(None))),
+ )
+ self.register_parameter(
+ "depth_attentions",
+ nn.Parameter(torch.Tensor(len(layers), meta_depth_info["num"])),
+ )
+ nn.init.normal_(self.width_attentions, 0, 0.01)
+ nn.init.normal_(self.depth_attentions, 0, 0.01)
+ self.apply(initialize_resnet)
+
+ def arch_parameters(self, LR=None):
+ if LR is None:
+ return [self.width_attentions, self.depth_attentions]
+ else:
+ return [
+ {"params": self.width_attentions, "lr": LR},
+ {"params": self.depth_attentions, "lr": LR},
+ ]
+
+ def base_parameters(self):
+ return (
+ list(self.layers.parameters())
+ + list(self.avgpool.parameters())
+ + list(self.classifier.parameters())
+ )
+
+ def get_flop(self, mode, config_dict, extra_info):
+ if config_dict is not None:
+ config_dict = config_dict.copy()
+ # select channels
+ channels = [3]
+ for i, weight in enumerate(self.width_attentions):
+ if mode == "genotype":
+ with torch.no_grad():
+ probe = nn.functional.softmax(weight, dim=0)
+ C = self.Ranges[i][torch.argmax(probe).item()]
+ else:
+ raise ValueError("invalid mode : {:}".format(mode))
+ channels.append(C)
+ # select depth
+ if mode == "genotype":
+ with torch.no_grad():
+ depth_probs = nn.functional.softmax(self.depth_attentions, dim=1)
+ choices = torch.argmax(depth_probs, dim=1).cpu().tolist()
+ else:
+ raise ValueError("invalid mode : {:}".format(mode))
+ selected_layers = []
+ for choice, xvalue in zip(choices, self.depth_info_list):
+ xtemp = xvalue[1]["choices"][choice] - xvalue[1]["xstart"] + 1
+ selected_layers.append(xtemp)
+ flop = 0
+ for i, layer in enumerate(self.layers):
+ s, e = self.layer2indexRange[i]
+ xchl = tuple(channels[s : e + 1])
+ if i in self.depth_at_i:
+ xstagei, xatti = self.depth_at_i[i]
+ if xatti <= choices[xstagei]: # leave this depth
+ flop += layer.get_flops(xchl)
+ else:
+ flop += 0 # do not use this layer
+ else:
+ flop += layer.get_flops(xchl)
+ # the last fc layer
+ flop += channels[-1] * self.classifier.out_features
+ if config_dict is None:
+ return flop / 1e6
+ else:
+ config_dict["xchannels"] = channels
+ config_dict["xblocks"] = selected_layers
+ config_dict["super_type"] = "infer-shape"
+ config_dict["estimated_FLOP"] = flop / 1e6
+ return flop / 1e6, config_dict
+
+ def get_arch_info(self):
+ string = (
+ "for depth and width, there are {:} + {:} attention probabilities.".format(
+ len(self.depth_attentions), len(self.width_attentions)
+ )
+ )
+ string += "\n{:}".format(self.depth_info)
+ discrepancy = []
+ with torch.no_grad():
+ for i, att in enumerate(self.depth_attentions):
+ prob = nn.functional.softmax(att, dim=0)
+ prob = prob.cpu()
+ selc = prob.argmax().item()
+ prob = prob.tolist()
+ prob = ["{:.3f}".format(x) for x in prob]
+ xstring = "{:03d}/{:03d}-th : {:}".format(
+ i, len(self.depth_attentions), " ".join(prob)
+ )
+ logt = ["{:.4f}".format(x) for x in att.cpu().tolist()]
+ xstring += " || {:17s}".format(" ".join(logt))
+ prob = sorted([float(x) for x in prob])
+ disc = prob[-1] - prob[-2]
+ xstring += " || discrepancy={:.2f} || select={:}/{:}".format(
+ disc, selc, len(prob)
+ )
+ discrepancy.append(disc)
+ string += "\n{:}".format(xstring)
+ string += "\n-----------------------------------------------"
+ for i, att in enumerate(self.width_attentions):
+ prob = nn.functional.softmax(att, dim=0)
+ prob = prob.cpu()
+ selc = prob.argmax().item()
+ prob = prob.tolist()
+ prob = ["{:.3f}".format(x) for x in prob]
+ xstring = "{:03d}/{:03d}-th : {:}".format(
+ i, len(self.width_attentions), " ".join(prob)
+ )
+ logt = ["{:.3f}".format(x) for x in att.cpu().tolist()]
+ xstring += " || {:52s}".format(" ".join(logt))
+ prob = sorted([float(x) for x in prob])
+ disc = prob[-1] - prob[-2]
+ xstring += " || dis={:.2f} || select={:}/{:}".format(
+ disc, selc, len(prob)
+ )
+ discrepancy.append(disc)
+ string += "\n{:}".format(xstring)
+ return string, discrepancy
+
+ def set_tau(self, tau_max, tau_min, epoch_ratio):
+ assert (
+ epoch_ratio >= 0 and epoch_ratio <= 1
+ ), "invalid epoch-ratio : {:}".format(epoch_ratio)
+ tau = tau_min + (tau_max - tau_min) * (1 + math.cos(math.pi * epoch_ratio)) / 2
+ self.tau = tau
+
+ def get_message(self):
+ return self.message
+
+ def forward(self, inputs):
+ if self.search_mode == "basic":
+ return self.basic_forward(inputs)
+ elif self.search_mode == "search":
+ return self.search_forward(inputs)
+ else:
+ raise ValueError("invalid search_mode = {:}".format(self.search_mode))
+
+ def search_forward(self, inputs):
+ flop_width_probs = nn.functional.softmax(self.width_attentions, dim=1)
+ flop_depth_probs = nn.functional.softmax(self.depth_attentions, dim=1)
+ flop_depth_probs = torch.flip(
+ torch.cumsum(torch.flip(flop_depth_probs, [1]), 1), [1]
+ )
+ selected_widths, selected_width_probs = select2withP(
+ self.width_attentions, self.tau
+ )
+ selected_depth_probs = select2withP(self.depth_attentions, self.tau, True)
+ with torch.no_grad():
+ selected_widths = selected_widths.cpu()
+
+ x, last_channel_idx, expected_inC, flops = inputs, 0, 3, []
+ feature_maps = []
+ for i, layer in enumerate(self.layers):
+ selected_w_index = selected_widths[
+ last_channel_idx : last_channel_idx + layer.num_conv
+ ]
+ selected_w_probs = selected_width_probs[
+ last_channel_idx : last_channel_idx + layer.num_conv
+ ]
+ layer_prob = flop_width_probs[
+ last_channel_idx : last_channel_idx + layer.num_conv
+ ]
+ x, expected_inC, expected_flop = layer(
+ (x, expected_inC, layer_prob, selected_w_index, selected_w_probs)
+ )
+ feature_maps.append(x)
+ last_channel_idx += layer.num_conv
+ if i in self.depth_info: # aggregate the information
+ choices = self.depth_info[i]["choices"]
+ xstagei = self.depth_info[i]["stage"]
+ # print ('iL={:}, choices={:}, stage={:}, probs={:}'.format(i, choices, xstagei, selected_depth_probs[xstagei].cpu().tolist()))
+ # for A, W in zip(choices, selected_depth_probs[xstagei]):
+ # print('Size = {:}, W = {:}'.format(feature_maps[A].size(), W))
+ possible_tensors = []
+ max_C = max(feature_maps[A].size(1) for A in choices)
+ for tempi, A in enumerate(choices):
+ xtensor = ChannelWiseInter(feature_maps[A], max_C)
+ possible_tensors.append(xtensor)
+ weighted_sum = sum(
+ xtensor * W
+ for xtensor, W in zip(
+ possible_tensors, selected_depth_probs[xstagei]
+ )
+ )
+ x = weighted_sum
+
+ if i in self.depth_at_i:
+ xstagei, xatti = self.depth_at_i[i]
+ x_expected_flop = flop_depth_probs[xstagei, xatti] * expected_flop
+ else:
+ x_expected_flop = expected_flop
+ flops.append(x_expected_flop)
+ flops.append(expected_inC * (self.classifier.out_features * 1.0 / 1e6))
+ features = self.avgpool(x)
+ features = features.view(features.size(0), -1)
+ logits = linear_forward(features, self.classifier)
+ return logits, torch.stack([sum(flops)])
+
+ def basic_forward(self, inputs):
+ if self.InShape is None:
+ self.InShape = (inputs.size(-2), inputs.size(-1))
+ x = inputs
+ for i, layer in enumerate(self.layers):
+ x = layer(x)
+ features = self.avgpool(x)
+ features = features.view(features.size(0), -1)
+ logits = self.classifier(features)
+ return features, logits
diff --git a/AutoDL-Projects/xautodl/models/shape_searchs/SearchSimResNet_width.py b/AutoDL-Projects/xautodl/models/shape_searchs/SearchSimResNet_width.py
new file mode 100644
index 0000000..584ffef
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/shape_searchs/SearchSimResNet_width.py
@@ -0,0 +1,466 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019 #
+##################################################
+import math, torch
+import torch.nn as nn
+from ..initialization import initialize_resnet
+from ..SharedUtils import additive_func
+from .SoftSelect import select2withP, ChannelWiseInter
+from .SoftSelect import linear_forward
+from .SoftSelect import get_width_choices as get_choices
+
+
+def conv_forward(inputs, conv, choices):
+ iC = conv.in_channels
+ fill_size = list(inputs.size())
+ fill_size[1] = iC - fill_size[1]
+ filled = torch.zeros(fill_size, device=inputs.device)
+ xinputs = torch.cat((inputs, filled), dim=1)
+ outputs = conv(xinputs)
+ selecteds = [outputs[:, :oC] for oC in choices]
+ return selecteds
+
+
+class ConvBNReLU(nn.Module):
+ num_conv = 1
+
+ def __init__(
+ self, nIn, nOut, kernel, stride, padding, bias, has_avg, has_bn, has_relu
+ ):
+ super(ConvBNReLU, self).__init__()
+ self.InShape = None
+ self.OutShape = None
+ self.choices = get_choices(nOut)
+ self.register_buffer("choices_tensor", torch.Tensor(self.choices))
+
+ if has_avg:
+ self.avg = nn.AvgPool2d(kernel_size=2, stride=2, padding=0)
+ else:
+ self.avg = None
+ self.conv = nn.Conv2d(
+ nIn,
+ nOut,
+ kernel_size=kernel,
+ stride=stride,
+ padding=padding,
+ dilation=1,
+ groups=1,
+ bias=bias,
+ )
+ # if has_bn : self.bn = nn.BatchNorm2d(nOut)
+ # else : self.bn = None
+ self.has_bn = has_bn
+ self.BNs = nn.ModuleList()
+ for i, _out in enumerate(self.choices):
+ self.BNs.append(nn.BatchNorm2d(_out))
+ if has_relu:
+ self.relu = nn.ReLU(inplace=True)
+ else:
+ self.relu = None
+ self.in_dim = nIn
+ self.out_dim = nOut
+ self.search_mode = "basic"
+
+ def get_flops(self, channels, check_range=True, divide=1):
+ iC, oC = channels
+ if check_range:
+ assert (
+ iC <= self.conv.in_channels and oC <= self.conv.out_channels
+ ), "{:} vs {:} | {:} vs {:}".format(
+ iC, self.conv.in_channels, oC, self.conv.out_channels
+ )
+ assert (
+ isinstance(self.InShape, tuple) and len(self.InShape) == 2
+ ), "invalid in-shape : {:}".format(self.InShape)
+ assert (
+ isinstance(self.OutShape, tuple) and len(self.OutShape) == 2
+ ), "invalid out-shape : {:}".format(self.OutShape)
+ # conv_per_position_flops = self.conv.kernel_size[0] * self.conv.kernel_size[1] * iC * oC / self.conv.groups
+ conv_per_position_flops = (
+ self.conv.kernel_size[0] * self.conv.kernel_size[1] * 1.0 / self.conv.groups
+ )
+ all_positions = self.OutShape[0] * self.OutShape[1]
+ flops = (conv_per_position_flops * all_positions / divide) * iC * oC
+ if self.conv.bias is not None:
+ flops += all_positions / divide
+ return flops
+
+ def get_range(self):
+ return [self.choices]
+
+ def forward(self, inputs):
+ if self.search_mode == "basic":
+ return self.basic_forward(inputs)
+ elif self.search_mode == "search":
+ return self.search_forward(inputs)
+ else:
+ raise ValueError("invalid search_mode = {:}".format(self.search_mode))
+
+ def search_forward(self, tuple_inputs):
+ assert (
+ isinstance(tuple_inputs, tuple) and len(tuple_inputs) == 5
+ ), "invalid type input : {:}".format(type(tuple_inputs))
+ inputs, expected_inC, probability, index, prob = tuple_inputs
+ index, prob = torch.squeeze(index).tolist(), torch.squeeze(prob)
+ probability = torch.squeeze(probability)
+ assert len(index) == 2, "invalid length : {:}".format(index)
+ # compute expected flop
+ # coordinates = torch.arange(self.x_range[0], self.x_range[1]+1).type_as(probability)
+ expected_outC = (self.choices_tensor * probability).sum()
+ expected_flop = self.get_flops([expected_inC, expected_outC], False, 1e6)
+ if self.avg:
+ out = self.avg(inputs)
+ else:
+ out = inputs
+ # convolutional layer
+ out_convs = conv_forward(out, self.conv, [self.choices[i] for i in index])
+ out_bns = [self.BNs[idx](out_conv) for idx, out_conv in zip(index, out_convs)]
+ # merge
+ out_channel = max([x.size(1) for x in out_bns])
+ outA = ChannelWiseInter(out_bns[0], out_channel)
+ outB = ChannelWiseInter(out_bns[1], out_channel)
+ out = outA * prob[0] + outB * prob[1]
+ # out = additive_func(out_bns[0]*prob[0], out_bns[1]*prob[1])
+
+ if self.relu:
+ out = self.relu(out)
+ else:
+ out = out
+ return out, expected_outC, expected_flop
+
+ def basic_forward(self, inputs):
+ if self.avg:
+ out = self.avg(inputs)
+ else:
+ out = inputs
+ conv = self.conv(out)
+ if self.has_bn:
+ out = self.BNs[-1](conv)
+ else:
+ out = conv
+ if self.relu:
+ out = self.relu(out)
+ else:
+ out = out
+ if self.InShape is None:
+ self.InShape = (inputs.size(-2), inputs.size(-1))
+ self.OutShape = (out.size(-2), out.size(-1))
+ return out
+
+
+class SimBlock(nn.Module):
+ expansion = 1
+ num_conv = 1
+
+ def __init__(self, inplanes, planes, stride):
+ super(SimBlock, self).__init__()
+ assert stride == 1 or stride == 2, "invalid stride {:}".format(stride)
+ self.conv = ConvBNReLU(
+ inplanes,
+ planes,
+ 3,
+ stride,
+ 1,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=True,
+ )
+ if stride == 2:
+ self.downsample = ConvBNReLU(
+ inplanes,
+ planes,
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=True,
+ has_bn=False,
+ has_relu=False,
+ )
+ elif inplanes != planes:
+ self.downsample = ConvBNReLU(
+ inplanes,
+ planes,
+ 1,
+ 1,
+ 0,
+ False,
+ has_avg=False,
+ has_bn=True,
+ has_relu=False,
+ )
+ else:
+ self.downsample = None
+ self.out_dim = planes
+ self.search_mode = "basic"
+
+ def get_range(self):
+ return self.conv.get_range()
+
+ def get_flops(self, channels):
+ assert len(channels) == 2, "invalid channels : {:}".format(channels)
+ flop_A = self.conv.get_flops([channels[0], channels[1]])
+ if hasattr(self.downsample, "get_flops"):
+ flop_C = self.downsample.get_flops([channels[0], channels[-1]])
+ else:
+ flop_C = 0
+ if (
+ channels[0] != channels[-1] and self.downsample is None
+ ): # this short-cut will be added during the infer-train
+ flop_C = (
+ channels[0]
+ * channels[-1]
+ * self.conv.OutShape[0]
+ * self.conv.OutShape[1]
+ )
+ return flop_A + flop_C
+
+ def forward(self, inputs):
+ if self.search_mode == "basic":
+ return self.basic_forward(inputs)
+ elif self.search_mode == "search":
+ return self.search_forward(inputs)
+ else:
+ raise ValueError("invalid search_mode = {:}".format(self.search_mode))
+
+ def search_forward(self, tuple_inputs):
+ assert (
+ isinstance(tuple_inputs, tuple) and len(tuple_inputs) == 5
+ ), "invalid type input : {:}".format(type(tuple_inputs))
+ inputs, expected_inC, probability, indexes, probs = tuple_inputs
+ assert (
+ indexes.size(0) == 1 and probs.size(0) == 1 and probability.size(0) == 1
+ ), "invalid size : {:}, {:}, {:}".format(
+ indexes.size(), probs.size(), probability.size()
+ )
+ out, expected_next_inC, expected_flop = self.conv(
+ (inputs, expected_inC, probability[0], indexes[0], probs[0])
+ )
+ if self.downsample is not None:
+ residual, _, expected_flop_c = self.downsample(
+ (inputs, expected_inC, probability[-1], indexes[-1], probs[-1])
+ )
+ else:
+ residual, expected_flop_c = inputs, 0
+ out = additive_func(residual, out)
+ return (
+ nn.functional.relu(out, inplace=True),
+ expected_next_inC,
+ sum([expected_flop, expected_flop_c]),
+ )
+
+ def basic_forward(self, inputs):
+ basicblock = self.conv(inputs)
+ if self.downsample is not None:
+ residual = self.downsample(inputs)
+ else:
+ residual = inputs
+ out = additive_func(residual, basicblock)
+ return nn.functional.relu(out, inplace=True)
+
+
+class SearchWidthSimResNet(nn.Module):
+ def __init__(self, depth, num_classes):
+ super(SearchWidthSimResNet, self).__init__()
+
+ assert (
+ depth - 2
+ ) % 3 == 0, "depth should be one of 5, 8, 11, 14, ... instead of {:}".format(
+ depth
+ )
+ layer_blocks = (depth - 2) // 3
+ self.message = (
+ "SearchWidthSimResNet : Depth : {:} , Layers for each block : {:}".format(
+ depth, layer_blocks
+ )
+ )
+ self.num_classes = num_classes
+ self.channels = [16]
+ self.layers = nn.ModuleList(
+ [
+ ConvBNReLU(
+ 3, 16, 3, 1, 1, False, has_avg=False, has_bn=True, has_relu=True
+ )
+ ]
+ )
+ self.InShape = None
+ for stage in range(3):
+ for iL in range(layer_blocks):
+ iC = self.channels[-1]
+ planes = 16 * (2 ** stage)
+ stride = 2 if stage > 0 and iL == 0 else 1
+ module = SimBlock(iC, planes, stride)
+ self.channels.append(module.out_dim)
+ self.layers.append(module)
+ self.message += "\nstage={:}, ilayer={:02d}/{:02d}, block={:03d}, iC={:3d}, oC={:3d}, stride={:}".format(
+ stage,
+ iL,
+ layer_blocks,
+ len(self.layers) - 1,
+ iC,
+ module.out_dim,
+ stride,
+ )
+
+ self.avgpool = nn.AvgPool2d(8)
+ self.classifier = nn.Linear(module.out_dim, num_classes)
+ self.InShape = None
+ self.tau = -1
+ self.search_mode = "basic"
+ # assert sum(x.num_conv for x in self.layers) + 1 == depth, 'invalid depth check {:} vs {:}'.format(sum(x.num_conv for x in self.layers)+1, depth)
+
+ # parameters for width
+ self.Ranges = []
+ self.layer2indexRange = []
+ for i, layer in enumerate(self.layers):
+ start_index = len(self.Ranges)
+ self.Ranges += layer.get_range()
+ self.layer2indexRange.append((start_index, len(self.Ranges)))
+ assert len(self.Ranges) + 1 == depth, "invalid depth check {:} vs {:}".format(
+ len(self.Ranges) + 1, depth
+ )
+
+ self.register_parameter(
+ "width_attentions",
+ nn.Parameter(torch.Tensor(len(self.Ranges), get_choices(None))),
+ )
+ nn.init.normal_(self.width_attentions, 0, 0.01)
+ self.apply(initialize_resnet)
+
+ def arch_parameters(self):
+ return [self.width_attentions]
+
+ def base_parameters(self):
+ return (
+ list(self.layers.parameters())
+ + list(self.avgpool.parameters())
+ + list(self.classifier.parameters())
+ )
+
+ def get_flop(self, mode, config_dict, extra_info):
+ if config_dict is not None:
+ config_dict = config_dict.copy()
+ # weights = [F.softmax(x, dim=0) for x in self.width_attentions]
+ channels = [3]
+ for i, weight in enumerate(self.width_attentions):
+ if mode == "genotype":
+ with torch.no_grad():
+ probe = nn.functional.softmax(weight, dim=0)
+ C = self.Ranges[i][torch.argmax(probe).item()]
+ elif mode == "max":
+ C = self.Ranges[i][-1]
+ elif mode == "fix":
+ C = int(math.sqrt(extra_info) * self.Ranges[i][-1])
+ elif mode == "random":
+ assert isinstance(extra_info, float), "invalid extra_info : {:}".format(
+ extra_info
+ )
+ with torch.no_grad():
+ prob = nn.functional.softmax(weight, dim=0)
+ approximate_C = int(math.sqrt(extra_info) * self.Ranges[i][-1])
+ for j in range(prob.size(0)):
+ prob[j] = 1 / (
+ abs(j - (approximate_C - self.Ranges[i][j])) + 0.2
+ )
+ C = self.Ranges[i][torch.multinomial(prob, 1, False).item()]
+ else:
+ raise ValueError("invalid mode : {:}".format(mode))
+ channels.append(C)
+ flop = 0
+ for i, layer in enumerate(self.layers):
+ s, e = self.layer2indexRange[i]
+ xchl = tuple(channels[s : e + 1])
+ flop += layer.get_flops(xchl)
+ # the last fc layer
+ flop += channels[-1] * self.classifier.out_features
+ if config_dict is None:
+ return flop / 1e6
+ else:
+ config_dict["xchannels"] = channels
+ config_dict["super_type"] = "infer-width"
+ config_dict["estimated_FLOP"] = flop / 1e6
+ return flop / 1e6, config_dict
+
+ def get_arch_info(self):
+ string = "for width, there are {:} attention probabilities.".format(
+ len(self.width_attentions)
+ )
+ discrepancy = []
+ with torch.no_grad():
+ for i, att in enumerate(self.width_attentions):
+ prob = nn.functional.softmax(att, dim=0)
+ prob = prob.cpu()
+ selc = prob.argmax().item()
+ prob = prob.tolist()
+ prob = ["{:.3f}".format(x) for x in prob]
+ xstring = "{:03d}/{:03d}-th : {:}".format(
+ i, len(self.width_attentions), " ".join(prob)
+ )
+ logt = ["{:.3f}".format(x) for x in att.cpu().tolist()]
+ xstring += " || {:52s}".format(" ".join(logt))
+ prob = sorted([float(x) for x in prob])
+ disc = prob[-1] - prob[-2]
+ xstring += " || dis={:.2f} || select={:}/{:}".format(
+ disc, selc, len(prob)
+ )
+ discrepancy.append(disc)
+ string += "\n{:}".format(xstring)
+ return string, discrepancy
+
+ def set_tau(self, tau_max, tau_min, epoch_ratio):
+ assert (
+ epoch_ratio >= 0 and epoch_ratio <= 1
+ ), "invalid epoch-ratio : {:}".format(epoch_ratio)
+ tau = tau_min + (tau_max - tau_min) * (1 + math.cos(math.pi * epoch_ratio)) / 2
+ self.tau = tau
+
+ def get_message(self):
+ return self.message
+
+ def forward(self, inputs):
+ if self.search_mode == "basic":
+ return self.basic_forward(inputs)
+ elif self.search_mode == "search":
+ return self.search_forward(inputs)
+ else:
+ raise ValueError("invalid search_mode = {:}".format(self.search_mode))
+
+ def search_forward(self, inputs):
+ flop_probs = nn.functional.softmax(self.width_attentions, dim=1)
+ selected_widths, selected_probs = select2withP(self.width_attentions, self.tau)
+ with torch.no_grad():
+ selected_widths = selected_widths.cpu()
+
+ x, last_channel_idx, expected_inC, flops = inputs, 0, 3, []
+ for i, layer in enumerate(self.layers):
+ selected_w_index = selected_widths[
+ last_channel_idx : last_channel_idx + layer.num_conv
+ ]
+ selected_w_probs = selected_probs[
+ last_channel_idx : last_channel_idx + layer.num_conv
+ ]
+ layer_prob = flop_probs[
+ last_channel_idx : last_channel_idx + layer.num_conv
+ ]
+ x, expected_inC, expected_flop = layer(
+ (x, expected_inC, layer_prob, selected_w_index, selected_w_probs)
+ )
+ last_channel_idx += layer.num_conv
+ flops.append(expected_flop)
+ flops.append(expected_inC * (self.classifier.out_features * 1.0 / 1e6))
+ features = self.avgpool(x)
+ features = features.view(features.size(0), -1)
+ logits = linear_forward(features, self.classifier)
+ return logits, torch.stack([sum(flops)])
+
+ def basic_forward(self, inputs):
+ if self.InShape is None:
+ self.InShape = (inputs.size(-2), inputs.size(-1))
+ x = inputs
+ for i, layer in enumerate(self.layers):
+ x = layer(x)
+ features = self.avgpool(x)
+ features = features.view(features.size(0), -1)
+ logits = self.classifier(features)
+ return features, logits
diff --git a/AutoDL-Projects/xautodl/models/shape_searchs/SoftSelect.py b/AutoDL-Projects/xautodl/models/shape_searchs/SoftSelect.py
new file mode 100644
index 0000000..3cdfa45
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/shape_searchs/SoftSelect.py
@@ -0,0 +1,128 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019 #
+##################################################
+import math, torch
+import torch.nn as nn
+
+
+def select2withP(logits, tau, just_prob=False, num=2, eps=1e-7):
+ if tau <= 0:
+ new_logits = logits
+ probs = nn.functional.softmax(new_logits, dim=1)
+ else:
+ while True: # a trick to avoid the gumbels bug
+ gumbels = -torch.empty_like(logits).exponential_().log()
+ new_logits = (logits.log_softmax(dim=1) + gumbels) / tau
+ probs = nn.functional.softmax(new_logits, dim=1)
+ if (
+ (not torch.isinf(gumbels).any())
+ and (not torch.isinf(probs).any())
+ and (not torch.isnan(probs).any())
+ ):
+ break
+
+ if just_prob:
+ return probs
+
+ # with torch.no_grad(): # add eps for unexpected torch error
+ # probs = nn.functional.softmax(new_logits, dim=1)
+ # selected_index = torch.multinomial(probs + eps, 2, False)
+ with torch.no_grad(): # add eps for unexpected torch error
+ probs = probs.cpu()
+ selected_index = torch.multinomial(probs + eps, num, False).to(logits.device)
+ selected_logit = torch.gather(new_logits, 1, selected_index)
+ selcted_probs = nn.functional.softmax(selected_logit, dim=1)
+ return selected_index, selcted_probs
+
+
+def ChannelWiseInter(inputs, oC, mode="v2"):
+ if mode == "v1":
+ return ChannelWiseInterV1(inputs, oC)
+ elif mode == "v2":
+ return ChannelWiseInterV2(inputs, oC)
+ else:
+ raise ValueError("invalid mode : {:}".format(mode))
+
+
+def ChannelWiseInterV1(inputs, oC):
+ assert inputs.dim() == 4, "invalid dimension : {:}".format(inputs.size())
+
+ def start_index(a, b, c):
+ return int(math.floor(float(a * c) / b))
+
+ def end_index(a, b, c):
+ return int(math.ceil(float((a + 1) * c) / b))
+
+ batch, iC, H, W = inputs.size()
+ outputs = torch.zeros((batch, oC, H, W), dtype=inputs.dtype, device=inputs.device)
+ if iC == oC:
+ return inputs
+ for ot in range(oC):
+ istartT, iendT = start_index(ot, oC, iC), end_index(ot, oC, iC)
+ values = inputs[:, istartT:iendT].mean(dim=1)
+ outputs[:, ot, :, :] = values
+ return outputs
+
+
+def ChannelWiseInterV2(inputs, oC):
+ assert inputs.dim() == 4, "invalid dimension : {:}".format(inputs.size())
+ batch, C, H, W = inputs.size()
+ if C == oC:
+ return inputs
+ else:
+ return nn.functional.adaptive_avg_pool3d(inputs, (oC, H, W))
+ # inputs_5D = inputs.view(batch, 1, C, H, W)
+ # otputs_5D = nn.functional.interpolate(inputs_5D, (oC,H,W), None, 'area', None)
+ # otputs = otputs_5D.view(batch, oC, H, W)
+ # otputs_5D = nn.functional.interpolate(inputs_5D, (oC,H,W), None, 'trilinear', False)
+ # return otputs
+
+
+def linear_forward(inputs, linear):
+ if linear is None:
+ return inputs
+ iC = inputs.size(1)
+ weight = linear.weight[:, :iC]
+ if linear.bias is None:
+ bias = None
+ else:
+ bias = linear.bias
+ return nn.functional.linear(inputs, weight, bias)
+
+
+def get_width_choices(nOut):
+ xsrange = [0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
+ if nOut is None:
+ return len(xsrange)
+ else:
+ Xs = [int(nOut * i) for i in xsrange]
+ # xs = [ int(nOut * i // 10) for i in range(2, 11)]
+ # Xs = [x for i, x in enumerate(xs) if i+1 == len(xs) or xs[i+1] > x+1]
+ Xs = sorted(list(set(Xs)))
+ return tuple(Xs)
+
+
+def get_depth_choices(nDepth):
+ if nDepth is None:
+ return 3
+ else:
+ assert nDepth >= 3, "nDepth should be greater than 2 vs {:}".format(nDepth)
+ if nDepth == 1:
+ return (1, 1, 1)
+ elif nDepth == 2:
+ return (1, 1, 2)
+ elif nDepth >= 3:
+ return (nDepth // 3, nDepth * 2 // 3, nDepth)
+ else:
+ raise ValueError("invalid Depth : {:}".format(nDepth))
+
+
+def drop_path(x, drop_prob):
+ if drop_prob > 0.0:
+ keep_prob = 1.0 - drop_prob
+ mask = x.new_zeros(x.size(0), 1, 1, 1)
+ mask = mask.bernoulli_(keep_prob)
+ x = x * (mask / keep_prob)
+ # x.div_(keep_prob)
+ # x.mul_(mask)
+ return x
diff --git a/AutoDL-Projects/xautodl/models/shape_searchs/__init__.py b/AutoDL-Projects/xautodl/models/shape_searchs/__init__.py
new file mode 100644
index 0000000..15e2260
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/shape_searchs/__init__.py
@@ -0,0 +1,9 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019 #
+##################################################
+from .SearchCifarResNet_width import SearchWidthCifarResNet
+from .SearchCifarResNet_depth import SearchDepthCifarResNet
+from .SearchCifarResNet import SearchShapeCifarResNet
+from .SearchSimResNet_width import SearchWidthSimResNet
+from .SearchImagenetResNet import SearchShapeImagenetResNet
+from .generic_size_tiny_cell_model import GenericNAS301Model
diff --git a/AutoDL-Projects/xautodl/models/shape_searchs/generic_size_tiny_cell_model.py b/AutoDL-Projects/xautodl/models/shape_searchs/generic_size_tiny_cell_model.py
new file mode 100644
index 0000000..c53805d
--- /dev/null
+++ b/AutoDL-Projects/xautodl/models/shape_searchs/generic_size_tiny_cell_model.py
@@ -0,0 +1,209 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.01 #
+#####################################################
+# Here, we utilized three techniques to search for the number of channels:
+# - channel-wise interpolation from "Network Pruning via Transformable Architecture Search, NeurIPS 2019"
+# - masking + Gumbel-Softmax (mask_gumbel) from "FBNetV2: Differentiable Neural Architecture Search for Spatial and Channel Dimensions, CVPR 2020"
+# - masking + sampling (mask_rl) from "Can Weight Sharing Outperform Random Architecture Search? An Investigation With TuNAS, CVPR 2020"
+from typing import List, Text, Any
+import random, torch
+import torch.nn as nn
+
+from ..cell_operations import ResNetBasicblock
+from ..cell_infers.cells import InferCell
+from .SoftSelect import select2withP, ChannelWiseInter
+
+
+class GenericNAS301Model(nn.Module):
+ def __init__(
+ self,
+ candidate_Cs: List[int],
+ max_num_Cs: int,
+ genotype: Any,
+ num_classes: int,
+ affine: bool,
+ track_running_stats: bool,
+ ):
+ super(GenericNAS301Model, self).__init__()
+ self._max_num_Cs = max_num_Cs
+ self._candidate_Cs = candidate_Cs
+ if max_num_Cs % 3 != 2:
+ raise ValueError("invalid number of layers : {:}".format(max_num_Cs))
+ self._num_stage = N = max_num_Cs // 3
+ self._max_C = max(candidate_Cs)
+
+ stem = nn.Sequential(
+ nn.Conv2d(3, self._max_C, kernel_size=3, padding=1, bias=not affine),
+ nn.BatchNorm2d(
+ self._max_C, affine=affine, track_running_stats=track_running_stats
+ ),
+ )
+
+ layer_reductions = [False] * N + [True] + [False] * N + [True] + [False] * N
+
+ c_prev = self._max_C
+ self._cells = nn.ModuleList()
+ self._cells.append(stem)
+ for index, reduction in enumerate(layer_reductions):
+ if reduction:
+ cell = ResNetBasicblock(c_prev, self._max_C, 2, True)
+ else:
+ cell = InferCell(
+ genotype, c_prev, self._max_C, 1, affine, track_running_stats
+ )
+ self._cells.append(cell)
+ c_prev = cell.out_dim
+ self._num_layer = len(self._cells)
+
+ self.lastact = nn.Sequential(
+ nn.BatchNorm2d(
+ c_prev, affine=affine, track_running_stats=track_running_stats
+ ),
+ nn.ReLU(inplace=True),
+ )
+ self.global_pooling = nn.AdaptiveAvgPool2d(1)
+ self.classifier = nn.Linear(c_prev, num_classes)
+ # algorithm related
+ self.register_buffer("_tau", torch.zeros(1))
+ self._algo = None
+ self._warmup_ratio = None
+
+ def set_algo(self, algo: Text):
+ # used for searching
+ assert self._algo is None, "This functioin can only be called once."
+ assert algo in ["mask_gumbel", "mask_rl", "tas"], "invalid algo : {:}".format(
+ algo
+ )
+ self._algo = algo
+ self._arch_parameters = nn.Parameter(
+ 1e-3 * torch.randn(self._max_num_Cs, len(self._candidate_Cs))
+ )
+ # if algo == 'mask_gumbel' or algo == 'mask_rl':
+ self.register_buffer(
+ "_masks", torch.zeros(len(self._candidate_Cs), max(self._candidate_Cs))
+ )
+ for i in range(len(self._candidate_Cs)):
+ self._masks.data[i, : self._candidate_Cs[i]] = 1
+
+ @property
+ def tau(self):
+ return self._tau
+
+ def set_tau(self, tau):
+ self._tau.data[:] = tau
+
+ @property
+ def warmup_ratio(self):
+ return self._warmup_ratio
+
+ def set_warmup_ratio(self, ratio: float):
+ self._warmup_ratio = ratio
+
+ @property
+ def weights(self):
+ xlist = list(self._cells.parameters())
+ xlist += list(self.lastact.parameters())
+ xlist += list(self.global_pooling.parameters())
+ xlist += list(self.classifier.parameters())
+ return xlist
+
+ @property
+ def alphas(self):
+ return [self._arch_parameters]
+
+ def show_alphas(self):
+ with torch.no_grad():
+ return "arch-parameters :\n{:}".format(
+ nn.functional.softmax(self._arch_parameters, dim=-1).cpu()
+ )
+
+ @property
+ def random(self):
+ cs = []
+ for i in range(self._max_num_Cs):
+ index = random.randint(0, len(self._candidate_Cs) - 1)
+ cs.append(str(self._candidate_Cs[index]))
+ return ":".join(cs)
+
+ @property
+ def genotype(self):
+ cs = []
+ for i in range(self._max_num_Cs):
+ with torch.no_grad():
+ index = self._arch_parameters[i].argmax().item()
+ cs.append(str(self._candidate_Cs[index]))
+ return ":".join(cs)
+
+ def get_message(self) -> Text:
+ string = self.extra_repr()
+ for i, cell in enumerate(self._cells):
+ string += "\n {:02d}/{:02d} :: {:}".format(
+ i, len(self._cells), cell.extra_repr()
+ )
+ return string
+
+ def extra_repr(self):
+ return "{name}(candidates={_candidate_Cs}, num={_max_num_Cs}, N={_num_stage}, L={_num_layer})".format(
+ name=self.__class__.__name__, **self.__dict__
+ )
+
+ def forward(self, inputs):
+ feature = inputs
+
+ log_probs = []
+ for i, cell in enumerate(self._cells):
+ feature = cell(feature)
+ # apply different searching algorithms
+ idx = max(0, i - 1)
+ if self._warmup_ratio is not None:
+ if random.random() < self._warmup_ratio:
+ mask = self._masks[-1]
+ else:
+ mask = self._masks[random.randint(0, len(self._masks) - 1)]
+ feature = feature * mask.view(1, -1, 1, 1)
+ elif self._algo == "mask_gumbel":
+ weights = nn.functional.gumbel_softmax(
+ self._arch_parameters[idx : idx + 1], tau=self.tau, dim=-1
+ )
+ mask = torch.matmul(weights, self._masks).view(1, -1, 1, 1)
+ feature = feature * mask
+ elif self._algo == "tas":
+ selected_cs, selected_probs = select2withP(
+ self._arch_parameters[idx : idx + 1], self.tau, num=2
+ )
+ with torch.no_grad():
+ i1, i2 = selected_cs.cpu().view(-1).tolist()
+ c1, c2 = self._candidate_Cs[i1], self._candidate_Cs[i2]
+ out_channel = max(c1, c2)
+ out1 = ChannelWiseInter(feature[:, :c1], out_channel)
+ out2 = ChannelWiseInter(feature[:, :c2], out_channel)
+ out = out1 * selected_probs[0, 0] + out2 * selected_probs[0, 1]
+ if feature.shape[1] == out.shape[1]:
+ feature = out
+ else:
+ miss = torch.zeros(
+ feature.shape[0],
+ feature.shape[1] - out.shape[1],
+ feature.shape[2],
+ feature.shape[3],
+ device=feature.device,
+ )
+ feature = torch.cat((out, miss), dim=1)
+ elif self._algo == "mask_rl":
+ prob = nn.functional.softmax(
+ self._arch_parameters[idx : idx + 1], dim=-1
+ )
+ dist = torch.distributions.Categorical(prob)
+ action = dist.sample()
+ log_probs.append(dist.log_prob(action))
+ mask = self._masks[action.item()].view(1, -1, 1, 1)
+ feature = feature * mask
+ else:
+ raise ValueError("invalid algorithm : {:}".format(self._algo))
+
+ out = self.lastact(feature)
+ out = self.global_pooling(out)
+ out = out.view(out.size(0), -1)
+ logits = self.classifier(out)
+
+ return out, logits, log_probs
diff --git a/AutoDL-Projects/xautodl/nas_infer_model/DXYs/CifarNet.py b/AutoDL-Projects/xautodl/nas_infer_model/DXYs/CifarNet.py
new file mode 100644
index 0000000..753e6de
--- /dev/null
+++ b/AutoDL-Projects/xautodl/nas_infer_model/DXYs/CifarNet.py
@@ -0,0 +1,76 @@
+import torch
+import torch.nn as nn
+from .construct_utils import drop_path
+from .head_utils import CifarHEAD, AuxiliaryHeadCIFAR
+from .base_cells import InferCell
+
+
+class NetworkCIFAR(nn.Module):
+
+ def __init__(self, C, N, stem_multiplier, auxiliary, genotype, num_classes):
+ super(NetworkCIFAR, self).__init__()
+ self._C = C
+ self._layerN = N
+ self._stem_multiplier = stem_multiplier
+
+ C_curr = self._stem_multiplier * C
+ self.stem = CifarHEAD(C_curr)
+
+ layer_channels = [C ] * N + [C*2 ] + [C*2 ] * N + [C*4 ] + [C*4 ] * N
+ layer_reductions = [False] * N + [True] + [False] * N + [True] + [False] * N
+ block_indexs = [0 ] * N + [-1 ] + [1 ] * N + [-1 ] + [2 ] * N
+ block2index = {0:[], 1:[], 2:[]}
+
+ C_prev_prev, C_prev, C_curr = C_curr, C_curr, C
+ reduction_prev, spatial, dims = False, 1, []
+ self.auxiliary_index = None
+ self.auxiliary_head = None
+ self.cells = nn.ModuleList()
+ for index, (C_curr, reduction) in enumerate(zip(layer_channels, layer_reductions)):
+ cell = InferCell(genotype, C_prev_prev, C_prev, C_curr, reduction, reduction_prev)
+ reduction_prev = reduction
+ self.cells.append( cell )
+ C_prev_prev, C_prev = C_prev, cell._multiplier*C_curr
+ if reduction and C_curr == C*4:
+ if auxiliary:
+ self.auxiliary_head = AuxiliaryHeadCIFAR(C_prev, num_classes)
+ self.auxiliary_index = index
+
+ if reduction: spatial *= 2
+ dims.append( (C_prev, spatial) )
+
+ self._Layer= len(self.cells)
+
+
+ self.global_pooling = nn.AdaptiveAvgPool2d(1)
+ self.classifier = nn.Linear(C_prev, num_classes)
+ self.drop_path_prob = -1
+
+ def update_drop_path(self, drop_path_prob):
+ self.drop_path_prob = drop_path_prob
+
+ def auxiliary_param(self):
+ if self.auxiliary_head is None: return []
+ else: return list( self.auxiliary_head.parameters() )
+
+ def get_message(self):
+ return self.extra_repr()
+
+ def extra_repr(self):
+ return ('{name}(C={_C}, N={_layerN}, L={_Layer}, stem={_stem_multiplier}, drop-path={drop_path_prob})'.format(name=self.__class__.__name__, **self.__dict__))
+
+ def forward(self, inputs):
+ stem_feature, logits_aux = self.stem(inputs), None
+ cell_results = [stem_feature, stem_feature]
+ for i, cell in enumerate(self.cells):
+ cell_feature = cell(cell_results[-2], cell_results[-1], self.drop_path_prob)
+ cell_results.append( cell_feature )
+
+ if self.auxiliary_index is not None and i == self.auxiliary_index and self.training:
+ logits_aux = self.auxiliary_head( cell_results[-1] )
+ out = self.global_pooling( cell_results[-1] )
+ out = out.view(out.size(0), -1)
+ logits = self.classifier(out)
+
+ if logits_aux is None: return out, logits
+ else : return out, [logits, logits_aux]
diff --git a/AutoDL-Projects/xautodl/nas_infer_model/DXYs/ImageNet.py b/AutoDL-Projects/xautodl/nas_infer_model/DXYs/ImageNet.py
new file mode 100644
index 0000000..a3cd1dd
--- /dev/null
+++ b/AutoDL-Projects/xautodl/nas_infer_model/DXYs/ImageNet.py
@@ -0,0 +1,77 @@
+import torch
+import torch.nn as nn
+from .construct_utils import drop_path
+from .base_cells import InferCell
+from .head_utils import ImageNetHEAD, AuxiliaryHeadImageNet
+
+
+class NetworkImageNet(nn.Module):
+
+ def __init__(self, C, N, auxiliary, genotype, num_classes):
+ super(NetworkImageNet, self).__init__()
+ self._C = C
+ self._layerN = N
+ layer_channels = [C ] * N + [C*2 ] + [C*2 ] * N + [C*4 ] + [C*4] * N
+ layer_reductions = [False] * N + [True] + [False] * N + [True] + [False] * N
+ self.stem0 = nn.Sequential(
+ nn.Conv2d(3, C // 2, kernel_size=3, stride=2, padding=1, bias=False),
+ nn.BatchNorm2d(C // 2),
+ nn.ReLU(inplace=True),
+ nn.Conv2d(C // 2, C, 3, stride=2, padding=1, bias=False),
+ nn.BatchNorm2d(C),
+ )
+
+ self.stem1 = nn.Sequential(
+ nn.ReLU(inplace=True),
+ nn.Conv2d(C, C, 3, stride=2, padding=1, bias=False),
+ nn.BatchNorm2d(C),
+ )
+
+ C_prev_prev, C_prev, C_curr, reduction_prev = C, C, C, True
+
+ self.cells = nn.ModuleList()
+ self.auxiliary_index = None
+ for i, (C_curr, reduction) in enumerate(zip(layer_channels, layer_reductions)):
+ cell = InferCell(genotype, C_prev_prev, C_prev, C_curr, reduction, reduction_prev)
+ reduction_prev = reduction
+ self.cells += [cell]
+ C_prev_prev, C_prev = C_prev, cell._multiplier * C_curr
+ if reduction and C_curr == C*4:
+ C_to_auxiliary = C_prev
+ self.auxiliary_index = i
+
+ self._NNN = len(self.cells)
+ if auxiliary:
+ self.auxiliary_head = AuxiliaryHeadImageNet(C_to_auxiliary, num_classes)
+ else:
+ self.auxiliary_head = None
+ self.global_pooling = nn.AvgPool2d(7)
+ self.classifier = nn.Linear(C_prev, num_classes)
+ self.drop_path_prob = -1
+
+ def update_drop_path(self, drop_path_prob):
+ self.drop_path_prob = drop_path_prob
+
+ def extra_repr(self):
+ return ('{name}(C={_C}, N=[{_layerN}, {_NNN}], aux-index={auxiliary_index}, drop-path={drop_path_prob})'.format(name=self.__class__.__name__, **self.__dict__))
+
+ def get_message(self):
+ return self.extra_repr()
+
+ def auxiliary_param(self):
+ if self.auxiliary_head is None: return []
+ else: return list( self.auxiliary_head.parameters() )
+
+ def forward(self, inputs):
+ s0 = self.stem0(inputs)
+ s1 = self.stem1(s0)
+ logits_aux = None
+ for i, cell in enumerate(self.cells):
+ s0, s1 = s1, cell(s0, s1, self.drop_path_prob)
+ if i == self.auxiliary_index and self.auxiliary_head and self.training:
+ logits_aux = self.auxiliary_head(s1)
+ out = self.global_pooling(s1)
+ logits = self.classifier(out.view(out.size(0), -1))
+
+ if logits_aux is None: return out, logits
+ else : return out, [logits, logits_aux]
diff --git a/AutoDL-Projects/xautodl/nas_infer_model/DXYs/__init__.py b/AutoDL-Projects/xautodl/nas_infer_model/DXYs/__init__.py
new file mode 100644
index 0000000..78bcf6e
--- /dev/null
+++ b/AutoDL-Projects/xautodl/nas_infer_model/DXYs/__init__.py
@@ -0,0 +1,5 @@
+# Performance-Aware Template Network for One-Shot Neural Architecture Search
+from .CifarNet import NetworkCIFAR as CifarNet
+from .ImageNet import NetworkImageNet as ImageNet
+from .genotypes import Networks
+from .genotypes import build_genotype_from_dict
diff --git a/AutoDL-Projects/xautodl/nas_infer_model/DXYs/base_cells.py b/AutoDL-Projects/xautodl/nas_infer_model/DXYs/base_cells.py
new file mode 100644
index 0000000..287b4e4
--- /dev/null
+++ b/AutoDL-Projects/xautodl/nas_infer_model/DXYs/base_cells.py
@@ -0,0 +1,173 @@
+import math
+from copy import deepcopy
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+from .construct_utils import drop_path
+from ..operations import OPS, Identity, FactorizedReduce, ReLUConvBN
+
+
+class MixedOp(nn.Module):
+
+ def __init__(self, C, stride, PRIMITIVES):
+ super(MixedOp, self).__init__()
+ self._ops = nn.ModuleList()
+ self.name2idx = {}
+ for idx, primitive in enumerate(PRIMITIVES):
+ op = OPS[primitive](C, C, stride, False)
+ self._ops.append(op)
+ assert primitive not in self.name2idx, '{:} has already in'.format(primitive)
+ self.name2idx[primitive] = idx
+
+ def forward(self, x, weights, op_name):
+ if op_name is None:
+ if weights is None:
+ return [op(x) for op in self._ops]
+ else:
+ return sum(w * op(x) for w, op in zip(weights, self._ops))
+ else:
+ op_index = self.name2idx[op_name]
+ return self._ops[op_index](x)
+
+
+
+class SearchCell(nn.Module):
+
+ def __init__(self, steps, multiplier, C_prev_prev, C_prev, C, reduction, reduction_prev, PRIMITIVES, use_residual):
+ super(SearchCell, self).__init__()
+ self.reduction = reduction
+ self.PRIMITIVES = deepcopy(PRIMITIVES)
+
+ if reduction_prev:
+ self.preprocess0 = FactorizedReduce(C_prev_prev, C, 2, affine=False)
+ else:
+ self.preprocess0 = ReLUConvBN(C_prev_prev, C, 1, 1, 0, affine=False)
+ self.preprocess1 = ReLUConvBN(C_prev, C, 1, 1, 0, affine=False)
+ self._steps = steps
+ self._multiplier = multiplier
+ self._use_residual = use_residual
+
+ self._ops = nn.ModuleList()
+ for i in range(self._steps):
+ for j in range(2+i):
+ stride = 2 if reduction and j < 2 else 1
+ op = MixedOp(C, stride, self.PRIMITIVES)
+ self._ops.append(op)
+
+ def extra_repr(self):
+ return ('{name}(residual={_use_residual}, steps={_steps}, multiplier={_multiplier})'.format(name=self.__class__.__name__, **self.__dict__))
+
+ def forward(self, S0, S1, weights, connect, adjacency, drop_prob, modes):
+ if modes[0] is None:
+ if modes[1] == 'normal':
+ output = self.__forwardBoth(S0, S1, weights, connect, adjacency, drop_prob)
+ elif modes[1] == 'only_W':
+ output = self.__forwardOnlyW(S0, S1, drop_prob)
+ else:
+ test_genotype = modes[0]
+ if self.reduction: operations, concats = test_genotype.reduce, test_genotype.reduce_concat
+ else : operations, concats = test_genotype.normal, test_genotype.normal_concat
+ s0, s1 = self.preprocess0(S0), self.preprocess1(S1)
+ states, offset = [s0, s1], 0
+ assert self._steps == len(operations), '{:} vs. {:}'.format(self._steps, len(operations))
+ for i, (opA, opB) in enumerate(operations):
+ A = self._ops[offset + opA[1]](states[opA[1]], None, opA[0])
+ B = self._ops[offset + opB[1]](states[opB[1]], None, opB[0])
+ state = A + B
+ offset += len(states)
+ states.append(state)
+ output = torch.cat([states[i] for i in concats], dim=1)
+ if self._use_residual and S1.size() == output.size():
+ return S1 + output
+ else: return output
+
+ def __forwardBoth(self, S0, S1, weights, connect, adjacency, drop_prob):
+ s0, s1 = self.preprocess0(S0), self.preprocess1(S1)
+ states, offset = [s0, s1], 0
+ for i in range(self._steps):
+ clist = []
+ for j, h in enumerate(states):
+ x = self._ops[offset+j](h, weights[offset+j], None)
+ if self.training and drop_prob > 0.:
+ x = drop_path(x, math.pow(drop_prob, 1./len(states)))
+ clist.append( x )
+ connection = torch.mm(connect['{:}'.format(i)], adjacency[i]).squeeze(0)
+ state = sum(w * node for w, node in zip(connection, clist))
+ offset += len(states)
+ states.append(state)
+ return torch.cat(states[-self._multiplier:], dim=1)
+
+ def __forwardOnlyW(self, S0, S1, drop_prob):
+ s0, s1 = self.preprocess0(S0), self.preprocess1(S1)
+ states, offset = [s0, s1], 0
+ for i in range(self._steps):
+ clist = []
+ for j, h in enumerate(states):
+ xs = self._ops[offset+j](h, None, None)
+ clist += xs
+ if self.training and drop_prob > 0.:
+ xlist = [drop_path(x, math.pow(drop_prob, 1./len(states))) for x in clist]
+ else: xlist = clist
+ state = sum(xlist) * 2 / len(xlist)
+ offset += len(states)
+ states.append(state)
+ return torch.cat(states[-self._multiplier:], dim=1)
+
+
+
+class InferCell(nn.Module):
+
+ def __init__(self, genotype, C_prev_prev, C_prev, C, reduction, reduction_prev):
+ super(InferCell, self).__init__()
+ print(C_prev_prev, C_prev, C)
+
+ if reduction_prev is None:
+ self.preprocess0 = Identity()
+ elif reduction_prev:
+ self.preprocess0 = FactorizedReduce(C_prev_prev, C, 2)
+ else:
+ self.preprocess0 = ReLUConvBN(C_prev_prev, C, 1, 1, 0)
+ self.preprocess1 = ReLUConvBN(C_prev, C, 1, 1, 0)
+
+ if reduction: step_ops, concat = genotype.reduce, genotype.reduce_concat
+ else : step_ops, concat = genotype.normal, genotype.normal_concat
+ self._steps = len(step_ops)
+ self._concat = concat
+ self._multiplier = len(concat)
+ self._ops = nn.ModuleList()
+ self._indices = []
+ for operations in step_ops:
+ for name, index in operations:
+ stride = 2 if reduction and index < 2 else 1
+ if reduction_prev is None and index == 0:
+ op = OPS[name](C_prev_prev, C, stride, True)
+ else:
+ op = OPS[name](C , C, stride, True)
+ self._ops.append( op )
+ self._indices.append( index )
+
+ def extra_repr(self):
+ return ('{name}(steps={_steps}, concat={_concat})'.format(name=self.__class__.__name__, **self.__dict__))
+
+ def forward(self, S0, S1, drop_prob):
+ s0 = self.preprocess0(S0)
+ s1 = self.preprocess1(S1)
+
+ states = [s0, s1]
+ for i in range(self._steps):
+ h1 = states[self._indices[2*i]]
+ h2 = states[self._indices[2*i+1]]
+ op1 = self._ops[2*i]
+ op2 = self._ops[2*i+1]
+ h1 = op1(h1)
+ h2 = op2(h2)
+ if self.training and drop_prob > 0.:
+ if not isinstance(op1, Identity):
+ h1 = drop_path(h1, drop_prob)
+ if not isinstance(op2, Identity):
+ h2 = drop_path(h2, drop_prob)
+
+ state = h1 + h2
+ states += [state]
+ output = torch.cat([states[i] for i in self._concat], dim=1)
+ return output
diff --git a/AutoDL-Projects/xautodl/nas_infer_model/DXYs/construct_utils.py b/AutoDL-Projects/xautodl/nas_infer_model/DXYs/construct_utils.py
new file mode 100644
index 0000000..458aaf2
--- /dev/null
+++ b/AutoDL-Projects/xautodl/nas_infer_model/DXYs/construct_utils.py
@@ -0,0 +1,60 @@
+import torch
+import torch.nn.functional as F
+
+
+def drop_path(x, drop_prob):
+ if drop_prob > 0.:
+ keep_prob = 1. - drop_prob
+ mask = x.new_zeros(x.size(0), 1, 1, 1)
+ mask = mask.bernoulli_(keep_prob)
+ x = torch.div(x, keep_prob)
+ x.mul_(mask)
+ return x
+
+
+def return_alphas_str(basemodel):
+ if hasattr(basemodel, 'alphas_normal'):
+ string = 'normal [{:}] : \n-->>{:}'.format(basemodel.alphas_normal.size(), F.softmax(basemodel.alphas_normal, dim=-1) )
+ else: string = ''
+ if hasattr(basemodel, 'alphas_reduce'):
+ string = string + '\nreduce : {:}'.format( F.softmax(basemodel.alphas_reduce, dim=-1) )
+
+ if hasattr(basemodel, 'get_adjacency'):
+ adjacency = basemodel.get_adjacency()
+ for i in range( len(adjacency) ):
+ weight = F.softmax( basemodel.connect_normal[str(i)], dim=-1 )
+ adj = torch.mm(weight, adjacency[i]).view(-1)
+ adj = ['{:3.3f}'.format(x) for x in adj.cpu().tolist()]
+ string = string + '\nnormal--{:}-->{:}'.format(i, ', '.join(adj))
+ for i in range( len(adjacency) ):
+ weight = F.softmax( basemodel.connect_reduce[str(i)], dim=-1 )
+ adj = torch.mm(weight, adjacency[i]).view(-1)
+ adj = ['{:3.3f}'.format(x) for x in adj.cpu().tolist()]
+ string = string + '\nreduce--{:}-->{:}'.format(i, ', '.join(adj))
+
+ if hasattr(basemodel, 'alphas_connect'):
+ weight = F.softmax(basemodel.alphas_connect, dim=-1).cpu()
+ ZERO = ['{:.3f}'.format(x) for x in weight[:,0].tolist()]
+ IDEN = ['{:.3f}'.format(x) for x in weight[:,1].tolist()]
+ string = string + '\nconnect [{:}] : \n ->{:}\n ->{:}'.format( list(basemodel.alphas_connect.size()), ZERO, IDEN )
+ else:
+ string = string + '\nconnect = None'
+
+ if hasattr(basemodel, 'get_gcn_out'):
+ outputs = basemodel.get_gcn_out(True)
+ for i, output in enumerate(outputs):
+ string = string + '\nnormal:[{:}] : {:}'.format(i, F.softmax(output, dim=-1) )
+
+ return string
+
+
+def remove_duplicate_archs(all_archs):
+ archs = []
+ str_archs = ['{:}'.format(x) for x in all_archs]
+ for i, arch_x in enumerate(str_archs):
+ choose = True
+ for j in range(i):
+ if arch_x == str_archs[j]:
+ choose = False; break
+ if choose: archs.append(all_archs[i])
+ return archs
diff --git a/AutoDL-Projects/xautodl/nas_infer_model/DXYs/genotypes.py b/AutoDL-Projects/xautodl/nas_infer_model/DXYs/genotypes.py
new file mode 100644
index 0000000..d1b5c4d
--- /dev/null
+++ b/AutoDL-Projects/xautodl/nas_infer_model/DXYs/genotypes.py
@@ -0,0 +1,182 @@
+from collections import namedtuple
+
+Genotype = namedtuple('Genotype', 'normal normal_concat reduce reduce_concat connectN connects')
+#Genotype = namedtuple('Genotype', 'normal normal_concat reduce reduce_concat')
+
+PRIMITIVES_small = [
+ 'max_pool_3x3',
+ 'avg_pool_3x3',
+ 'skip_connect',
+ 'sep_conv_3x3',
+ 'sep_conv_5x5',
+ 'conv_3x1_1x3',
+]
+
+PRIMITIVES_large = [
+ 'max_pool_3x3',
+ 'avg_pool_3x3',
+ 'skip_connect',
+ 'sep_conv_3x3',
+ 'sep_conv_5x5',
+ 'dil_conv_3x3',
+ 'dil_conv_5x5',
+ 'conv_3x1_1x3',
+]
+
+PRIMITIVES_huge = [
+ 'skip_connect',
+ 'nor_conv_1x1',
+ 'max_pool_3x3',
+ 'avg_pool_3x3',
+ 'nor_conv_3x3',
+ 'sep_conv_3x3',
+ 'dil_conv_3x3',
+ 'conv_3x1_1x3',
+ 'sep_conv_5x5',
+ 'dil_conv_5x5',
+ 'sep_conv_7x7',
+ 'conv_7x1_1x7',
+ 'att_squeeze',
+]
+
+PRIMITIVES = {'small': PRIMITIVES_small,
+ 'large': PRIMITIVES_large,
+ 'huge' : PRIMITIVES_huge}
+
+NASNet = Genotype(
+ normal = [
+ (('sep_conv_5x5', 1), ('sep_conv_3x3', 0)),
+ (('sep_conv_5x5', 0), ('sep_conv_3x3', 0)),
+ (('avg_pool_3x3', 1), ('skip_connect', 0)),
+ (('avg_pool_3x3', 0), ('avg_pool_3x3', 0)),
+ (('sep_conv_3x3', 1), ('skip_connect', 1)),
+ ],
+ normal_concat = [2, 3, 4, 5, 6],
+ reduce = [
+ (('sep_conv_5x5', 1), ('sep_conv_7x7', 0)),
+ (('max_pool_3x3', 1), ('sep_conv_7x7', 0)),
+ (('avg_pool_3x3', 1), ('sep_conv_5x5', 0)),
+ (('skip_connect', 3), ('avg_pool_3x3', 2)),
+ (('sep_conv_3x3', 2), ('max_pool_3x3', 1)),
+ ],
+ reduce_concat = [4, 5, 6],
+ connectN=None, connects=None,
+)
+
+PNASNet = Genotype(
+ normal = [
+ (('sep_conv_5x5', 0), ('max_pool_3x3', 0)),
+ (('sep_conv_7x7', 1), ('max_pool_3x3', 1)),
+ (('sep_conv_5x5', 1), ('sep_conv_3x3', 1)),
+ (('sep_conv_3x3', 4), ('max_pool_3x3', 1)),
+ (('sep_conv_3x3', 0), ('skip_connect', 1)),
+ ],
+ normal_concat = [2, 3, 4, 5, 6],
+ reduce = [
+ (('sep_conv_5x5', 0), ('max_pool_3x3', 0)),
+ (('sep_conv_7x7', 1), ('max_pool_3x3', 1)),
+ (('sep_conv_5x5', 1), ('sep_conv_3x3', 1)),
+ (('sep_conv_3x3', 4), ('max_pool_3x3', 1)),
+ (('sep_conv_3x3', 0), ('skip_connect', 1)),
+ ],
+ reduce_concat = [2, 3, 4, 5, 6],
+ connectN=None, connects=None,
+)
+
+
+DARTS_V1 = Genotype(
+ normal=[
+ (('sep_conv_3x3', 1), ('sep_conv_3x3', 0)), # step 1
+ (('skip_connect', 0), ('sep_conv_3x3', 1)), # step 2
+ (('skip_connect', 0), ('sep_conv_3x3', 1)), # step 3
+ (('sep_conv_3x3', 0), ('skip_connect', 2)) # step 4
+ ],
+ normal_concat=[2, 3, 4, 5],
+ reduce=[
+ (('max_pool_3x3', 0), ('max_pool_3x3', 1)), # step 1
+ (('skip_connect', 2), ('max_pool_3x3', 0)), # step 2
+ (('max_pool_3x3', 0), ('skip_connect', 2)), # step 3
+ (('skip_connect', 2), ('avg_pool_3x3', 0)) # step 4
+ ],
+ reduce_concat=[2, 3, 4, 5],
+ connectN=None, connects=None,
+)
+
+# DARTS: Differentiable Architecture Search, ICLR 2019
+DARTS_V2 = Genotype(
+ normal=[
+ (('sep_conv_3x3', 0), ('sep_conv_3x3', 1)), # step 1
+ (('sep_conv_3x3', 0), ('sep_conv_3x3', 1)), # step 2
+ (('sep_conv_3x3', 1), ('skip_connect', 0)), # step 3
+ (('skip_connect', 0), ('dil_conv_3x3', 2)) # step 4
+ ],
+ normal_concat=[2, 3, 4, 5],
+ reduce=[
+ (('max_pool_3x3', 0), ('max_pool_3x3', 1)), # step 1
+ (('skip_connect', 2), ('max_pool_3x3', 1)), # step 2
+ (('max_pool_3x3', 0), ('skip_connect', 2)), # step 3
+ (('skip_connect', 2), ('max_pool_3x3', 1)) # step 4
+ ],
+ reduce_concat=[2, 3, 4, 5],
+ connectN=None, connects=None,
+)
+
+
+# One-Shot Neural Architecture Search via Self-Evaluated Template Network, ICCV 2019
+SETN = Genotype(
+ normal=[
+ (('skip_connect', 0), ('sep_conv_5x5', 1)),
+ (('sep_conv_5x5', 0), ('sep_conv_3x3', 1)),
+ (('sep_conv_5x5', 1), ('sep_conv_5x5', 3)),
+ (('max_pool_3x3', 1), ('conv_3x1_1x3', 4))],
+ normal_concat=[2, 3, 4, 5],
+ reduce=[
+ (('sep_conv_3x3', 0), ('sep_conv_5x5', 1)),
+ (('avg_pool_3x3', 0), ('sep_conv_5x5', 1)),
+ (('avg_pool_3x3', 0), ('sep_conv_5x5', 1)),
+ (('avg_pool_3x3', 0), ('skip_connect', 1))],
+ reduce_concat=[2, 3, 4, 5],
+ connectN=None, connects=None
+)
+
+
+# Searching for A Robust Neural Architecture in Four GPU Hours, CVPR 2019
+GDAS_V1 = Genotype(
+ normal=[
+ (('skip_connect', 0), ('skip_connect', 1)),
+ (('skip_connect', 0), ('sep_conv_5x5', 2)),
+ (('sep_conv_3x3', 3), ('skip_connect', 0)),
+ (('sep_conv_5x5', 4), ('sep_conv_3x3', 3))],
+ normal_concat=[2, 3, 4, 5],
+ reduce=[
+ (('sep_conv_5x5', 0), ('sep_conv_3x3', 1)),
+ (('sep_conv_5x5', 2), ('sep_conv_5x5', 1)),
+ (('dil_conv_5x5', 2), ('sep_conv_3x3', 1)),
+ (('sep_conv_5x5', 0), ('sep_conv_5x5', 1))],
+ reduce_concat=[2, 3, 4, 5],
+ connectN=None, connects=None
+)
+
+
+
+Networks = {'DARTS_V1': DARTS_V1,
+ 'DARTS_V2': DARTS_V2,
+ 'DARTS' : DARTS_V2,
+ 'NASNet' : NASNet,
+ 'GDAS_V1' : GDAS_V1,
+ 'PNASNet' : PNASNet,
+ 'SETN' : SETN,
+ }
+
+# This function will return a Genotype from a dict.
+def build_genotype_from_dict(xdict):
+ def remove_value(nodes):
+ return [tuple([(x[0], x[1]) for x in node]) for node in nodes]
+ genotype = Genotype(
+ normal=remove_value(xdict['normal']),
+ normal_concat=xdict['normal_concat'],
+ reduce=remove_value(xdict['reduce']),
+ reduce_concat=xdict['reduce_concat'],
+ connectN=None, connects=None
+ )
+ return genotype
diff --git a/AutoDL-Projects/xautodl/nas_infer_model/DXYs/head_utils.py b/AutoDL-Projects/xautodl/nas_infer_model/DXYs/head_utils.py
new file mode 100644
index 0000000..ac16e57
--- /dev/null
+++ b/AutoDL-Projects/xautodl/nas_infer_model/DXYs/head_utils.py
@@ -0,0 +1,71 @@
+import torch
+import torch.nn as nn
+
+
+class ImageNetHEAD(nn.Sequential):
+ def __init__(self, C, stride=2):
+ super(ImageNetHEAD, self).__init__()
+ self.add_module(
+ "conv1",
+ nn.Conv2d(3, C // 2, kernel_size=3, stride=2, padding=1, bias=False),
+ )
+ self.add_module("bn1", nn.BatchNorm2d(C // 2))
+ self.add_module("relu1", nn.ReLU(inplace=True))
+ self.add_module(
+ "conv2",
+ nn.Conv2d(C // 2, C, kernel_size=3, stride=stride, padding=1, bias=False),
+ )
+ self.add_module("bn2", nn.BatchNorm2d(C))
+
+
+class CifarHEAD(nn.Sequential):
+ def __init__(self, C):
+ super(CifarHEAD, self).__init__()
+ self.add_module("conv", nn.Conv2d(3, C, kernel_size=3, padding=1, bias=False))
+ self.add_module("bn", nn.BatchNorm2d(C))
+
+
+class AuxiliaryHeadCIFAR(nn.Module):
+ def __init__(self, C, num_classes):
+ """assuming input size 8x8"""
+ super(AuxiliaryHeadCIFAR, self).__init__()
+ self.features = nn.Sequential(
+ nn.ReLU(inplace=True),
+ nn.AvgPool2d(
+ 5, stride=3, padding=0, count_include_pad=False
+ ), # image size = 2 x 2
+ nn.Conv2d(C, 128, 1, bias=False),
+ nn.BatchNorm2d(128),
+ nn.ReLU(inplace=True),
+ nn.Conv2d(128, 768, 2, bias=False),
+ nn.BatchNorm2d(768),
+ nn.ReLU(inplace=True),
+ )
+ self.classifier = nn.Linear(768, num_classes)
+
+ def forward(self, x):
+ x = self.features(x)
+ x = self.classifier(x.view(x.size(0), -1))
+ return x
+
+
+class AuxiliaryHeadImageNet(nn.Module):
+ def __init__(self, C, num_classes):
+ """assuming input size 14x14"""
+ super(AuxiliaryHeadImageNet, self).__init__()
+ self.features = nn.Sequential(
+ nn.ReLU(inplace=True),
+ nn.AvgPool2d(5, stride=2, padding=0, count_include_pad=False),
+ nn.Conv2d(C, 128, 1, bias=False),
+ nn.BatchNorm2d(128),
+ nn.ReLU(inplace=True),
+ nn.Conv2d(128, 768, 2, bias=False),
+ nn.BatchNorm2d(768),
+ nn.ReLU(inplace=True),
+ )
+ self.classifier = nn.Linear(768, num_classes)
+
+ def forward(self, x):
+ x = self.features(x)
+ x = self.classifier(x.view(x.size(0), -1))
+ return x
diff --git a/AutoDL-Projects/xautodl/nas_infer_model/__init__.py b/AutoDL-Projects/xautodl/nas_infer_model/__init__.py
new file mode 100644
index 0000000..a152960
--- /dev/null
+++ b/AutoDL-Projects/xautodl/nas_infer_model/__init__.py
@@ -0,0 +1,51 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.01 #
+#####################################################
+# I write this package to make AutoDL-Projects to be compatible with the old GDAS projects.
+# Ideally, this package will be merged into lib/models/cell_infers in future.
+# Currently, this package is used to reproduce the results in GDAS (Searching for A Robust Neural Architecture in Four GPU Hours, CVPR 2019).
+##################################################
+
+import os, torch
+
+
+def obtain_nas_infer_model(config, extra_model_path=None):
+
+ if config.arch == "dxys":
+ from .DXYs import CifarNet, ImageNet, Networks
+ from .DXYs import build_genotype_from_dict
+
+ if config.genotype is None:
+ if extra_model_path is not None and not os.path.isfile(extra_model_path):
+ raise ValueError(
+ "When genotype in confiig is None, extra_model_path must be set as a path instead of {:}".format(
+ extra_model_path
+ )
+ )
+ xdata = torch.load(extra_model_path)
+ current_epoch = xdata["epoch"]
+ genotype_dict = xdata["genotypes"][current_epoch - 1]
+ genotype = build_genotype_from_dict(genotype_dict)
+ else:
+ genotype = Networks[config.genotype]
+ if config.dataset == "cifar":
+ return CifarNet(
+ config.ichannel,
+ config.layers,
+ config.stem_multi,
+ config.auxiliary,
+ genotype,
+ config.class_num,
+ )
+ elif config.dataset == "imagenet":
+ return ImageNet(
+ config.ichannel,
+ config.layers,
+ config.auxiliary,
+ genotype,
+ config.class_num,
+ )
+ else:
+ raise ValueError("invalid dataset : {:}".format(config.dataset))
+ else:
+ raise ValueError("invalid nas arch type : {:}".format(config.arch))
diff --git a/AutoDL-Projects/xautodl/nas_infer_model/operations.py b/AutoDL-Projects/xautodl/nas_infer_model/operations.py
new file mode 100644
index 0000000..825f2e3
--- /dev/null
+++ b/AutoDL-Projects/xautodl/nas_infer_model/operations.py
@@ -0,0 +1,183 @@
+##############################################################################################
+# This code is copied and modified from Hanxiao Liu's work (https://github.com/quark0/darts) #
+##############################################################################################
+import torch
+import torch.nn as nn
+
+OPS = {
+ 'none' : lambda C_in, C_out, stride, affine: Zero(stride),
+ 'avg_pool_3x3' : lambda C_in, C_out, stride, affine: POOLING(C_in, C_out, stride, 'avg'),
+ 'max_pool_3x3' : lambda C_in, C_out, stride, affine: POOLING(C_in, C_out, stride, 'max'),
+ 'nor_conv_7x7' : lambda C_in, C_out, stride, affine: ReLUConvBN(C_in, C_out, (7,7), (stride,stride), (3,3), affine),
+ 'nor_conv_3x3' : lambda C_in, C_out, stride, affine: ReLUConvBN(C_in, C_out, (3,3), (stride,stride), (1,1), affine),
+ 'nor_conv_1x1' : lambda C_in, C_out, stride, affine: ReLUConvBN(C_in, C_out, (1,1), (stride,stride), (0,0), affine),
+ 'skip_connect' : lambda C_in, C_out, stride, affine: Identity() if stride == 1 and C_in == C_out else FactorizedReduce(C_in, C_out, stride, affine),
+ 'sep_conv_3x3' : lambda C_in, C_out, stride, affine: SepConv(C_in, C_out, 3, stride, 1, affine=affine),
+ 'sep_conv_5x5' : lambda C_in, C_out, stride, affine: SepConv(C_in, C_out, 5, stride, 2, affine=affine),
+ 'sep_conv_7x7' : lambda C_in, C_out, stride, affine: SepConv(C_in, C_out, 7, stride, 3, affine=affine),
+ 'dil_conv_3x3' : lambda C_in, C_out, stride, affine: DilConv(C_in, C_out, 3, stride, 2, 2, affine=affine),
+ 'dil_conv_5x5' : lambda C_in, C_out, stride, affine: DilConv(C_in, C_out, 5, stride, 4, 2, affine=affine),
+ 'conv_7x1_1x7' : lambda C_in, C_out, stride, affine: Conv717(C_in, C_out, stride, affine),
+ 'conv_3x1_1x3' : lambda C_in, C_out, stride, affine: Conv313(C_in, C_out, stride, affine)
+}
+
+
+class POOLING(nn.Module):
+
+ def __init__(self, C_in, C_out, stride, mode):
+ super(POOLING, self).__init__()
+ if C_in == C_out:
+ self.preprocess = None
+ else:
+ self.preprocess = ReLUConvBN(C_in, C_out, 1, 1, 0)
+ if mode == 'avg' : self.op = nn.AvgPool2d(3, stride=stride, padding=1, count_include_pad=False)
+ elif mode == 'max': self.op = nn.MaxPool2d(3, stride=stride, padding=1)
+
+ def forward(self, inputs):
+ if self.preprocess is not None:
+ x = self.preprocess(inputs)
+ else: x = inputs
+ return self.op(x)
+
+
+class Conv313(nn.Module):
+
+ def __init__(self, C_in, C_out, stride, affine):
+ super(Conv313, self).__init__()
+ self.op = nn.Sequential(
+ nn.ReLU(inplace=False),
+ nn.Conv2d(C_in , C_out, (1,3), stride=(1, stride), padding=(0, 1), bias=False),
+ nn.Conv2d(C_out, C_out, (3,1), stride=(stride, 1), padding=(1, 0), bias=False),
+ nn.BatchNorm2d(C_out, affine=affine)
+ )
+
+ def forward(self, x):
+ return self.op(x)
+
+
+class Conv717(nn.Module):
+
+ def __init__(self, C_in, C_out, stride, affine):
+ super(Conv717, self).__init__()
+ self.op = nn.Sequential(
+ nn.ReLU(inplace=False),
+ nn.Conv2d(C_in , C_out, (1,7), stride=(1, stride), padding=(0, 3), bias=False),
+ nn.Conv2d(C_out, C_out, (7,1), stride=(stride, 1), padding=(3, 0), bias=False),
+ nn.BatchNorm2d(C_out, affine=affine)
+ )
+
+ def forward(self, x):
+ return self.op(x)
+
+
+class ReLUConvBN(nn.Module):
+
+ def __init__(self, C_in, C_out, kernel_size, stride, padding, affine=True):
+ super(ReLUConvBN, self).__init__()
+ self.op = nn.Sequential(
+ nn.ReLU(inplace=False),
+ nn.Conv2d(C_in, C_out, kernel_size, stride=stride, padding=padding, bias=False),
+ nn.BatchNorm2d(C_out, affine=affine)
+ )
+
+ def forward(self, x):
+ return self.op(x)
+
+
+class DilConv(nn.Module):
+
+ def __init__(self, C_in, C_out, kernel_size, stride, padding, dilation, affine=True):
+ super(DilConv, self).__init__()
+ self.op = nn.Sequential(
+ nn.ReLU(inplace=False),
+ nn.Conv2d(C_in, C_in, kernel_size=kernel_size, stride=stride, padding=padding, dilation=dilation, groups=C_in, bias=False),
+ nn.Conv2d(C_in, C_out, kernel_size=1, padding=0, bias=False),
+ nn.BatchNorm2d(C_out, affine=affine),
+ )
+
+ def forward(self, x):
+ return self.op(x)
+
+
+class SepConv(nn.Module):
+
+ def __init__(self, C_in, C_out, kernel_size, stride, padding, affine=True):
+ super(SepConv, self).__init__()
+ self.op = nn.Sequential(
+ nn.ReLU(inplace=False),
+ nn.Conv2d(C_in, C_in, kernel_size=kernel_size, stride=stride, padding=padding, groups=C_in, bias=False),
+ nn.Conv2d(C_in, C_in, kernel_size=1, padding=0, bias=False),
+ nn.BatchNorm2d(C_in, affine=affine),
+ nn.ReLU(inplace=False),
+ nn.Conv2d(C_in, C_in, kernel_size=kernel_size, stride= 1, padding=padding, groups=C_in, bias=False),
+ nn.Conv2d(C_in, C_out, kernel_size=1, padding=0, bias=False),
+ nn.BatchNorm2d(C_out, affine=affine),
+ )
+
+ def forward(self, x):
+ return self.op(x)
+
+
+class Identity(nn.Module):
+
+ def __init__(self):
+ super(Identity, self).__init__()
+
+ def forward(self, x):
+ return x
+
+
+class Zero(nn.Module):
+
+ def __init__(self, stride):
+ super(Zero, self).__init__()
+ self.stride = stride
+
+ def forward(self, x):
+ if self.stride == 1:
+ return x.mul(0.)
+ return x[:,:,::self.stride,::self.stride].mul(0.)
+
+ def extra_repr(self):
+ return 'stride={stride}'.format(**self.__dict__)
+
+
+class FactorizedReduce(nn.Module):
+
+ def __init__(self, C_in, C_out, stride, affine=True):
+ super(FactorizedReduce, self).__init__()
+ self.stride = stride
+ self.C_in = C_in
+ self.C_out = C_out
+ self.relu = nn.ReLU(inplace=False)
+ if stride == 2:
+ #assert C_out % 2 == 0, 'C_out : {:}'.format(C_out)
+ C_outs = [C_out // 2, C_out - C_out // 2]
+ self.convs = nn.ModuleList()
+ for i in range(2):
+ self.convs.append( nn.Conv2d(C_in, C_outs[i], 1, stride=stride, padding=0, bias=False) )
+ self.pad = nn.ConstantPad2d((0, 1, 0, 1), 0)
+ elif stride == 4:
+ assert C_out % 4 == 0, 'C_out : {:}'.format(C_out)
+ self.convs = nn.ModuleList()
+ for i in range(4):
+ self.convs.append( nn.Conv2d(C_in, C_out // 4, 1, stride=stride, padding=0, bias=False) )
+ self.pad = nn.ConstantPad2d((0, 3, 0, 3), 0)
+ else:
+ raise ValueError('Invalid stride : {:}'.format(stride))
+
+ self.bn = nn.BatchNorm2d(C_out, affine=affine)
+
+ def forward(self, x):
+ x = self.relu(x)
+ y = self.pad(x)
+ if self.stride == 2:
+ out = torch.cat([self.convs[0](x), self.convs[1](y[:,:,1:,1:])], dim=1)
+ else:
+ out = torch.cat([self.convs[0](x), self.convs[1](y[:,:,1:-2,1:-2]),
+ self.convs[2](y[:,:,2:-1,2:-1]), self.convs[3](y[:,:,3:,3:])], dim=1)
+ out = self.bn(out)
+ return out
+
+ def extra_repr(self):
+ return 'C_in={C_in}, C_out={C_out}, stride={stride}'.format(**self.__dict__)
diff --git a/AutoDL-Projects/xautodl/procedures/__init__.py b/AutoDL-Projects/xautodl/procedures/__init__.py
new file mode 100644
index 0000000..6b6a20f
--- /dev/null
+++ b/AutoDL-Projects/xautodl/procedures/__init__.py
@@ -0,0 +1,38 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019 #
+######################################################################
+# This folder is deprecated, which is re-organized in "xalgorithms". #
+######################################################################
+from .starts import prepare_seed
+from .starts import prepare_logger
+from .starts import get_machine_info
+from .starts import save_checkpoint
+from .starts import copy_checkpoint
+from .optimizers import get_optim_scheduler
+from .funcs_nasbench import evaluate_for_seed as bench_evaluate_for_seed
+from .funcs_nasbench import pure_evaluate as bench_pure_evaluate
+from .funcs_nasbench import get_nas_bench_loaders
+
+
+def get_procedures(procedure):
+ from .basic_main import basic_train, basic_valid
+ from .search_main import search_train, search_valid
+ from .search_main_v2 import search_train_v2
+ from .simple_KD_main import simple_KD_train, simple_KD_valid
+
+ train_funcs = {
+ "basic": basic_train,
+ "search": search_train,
+ "Simple-KD": simple_KD_train,
+ "search-v2": search_train_v2,
+ }
+ valid_funcs = {
+ "basic": basic_valid,
+ "search": search_valid,
+ "Simple-KD": simple_KD_valid,
+ "search-v2": search_valid,
+ }
+
+ train_func = train_funcs[procedure]
+ valid_func = valid_funcs[procedure]
+ return train_func, valid_func
diff --git a/AutoDL-Projects/xautodl/procedures/advanced_main.py b/AutoDL-Projects/xautodl/procedures/advanced_main.py
new file mode 100644
index 0000000..854fe63
--- /dev/null
+++ b/AutoDL-Projects/xautodl/procedures/advanced_main.py
@@ -0,0 +1,99 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020.04 #
+#####################################################
+# To be finished.
+#
+import os, sys, time, torch
+from typing import Optional, Text, Callable
+
+# modules in AutoDL
+from xautodl.log_utils import AverageMeter, time_string
+from .eval_funcs import obtain_accuracy
+
+
+def get_device(tensors):
+ if isinstance(tensors, (list, tuple)):
+ return get_device(tensors[0])
+ elif isinstance(tensors, dict):
+ for key, value in tensors.items():
+ return get_device(value)
+ else:
+ return tensors.device
+
+
+def basic_train_fn(
+ xloader,
+ network,
+ criterion,
+ optimizer,
+ metric,
+ logger,
+):
+ results = procedure(
+ xloader,
+ network,
+ criterion,
+ optimizer,
+ metric,
+ "train",
+ logger,
+ )
+ return results
+
+
+def basic_eval_fn(xloader, network, metric, logger):
+ with torch.no_grad():
+ results = procedure(
+ xloader,
+ network,
+ None,
+ None,
+ metric,
+ "valid",
+ logger,
+ )
+ return results
+
+
+def procedure(
+ xloader,
+ network,
+ criterion,
+ optimizer,
+ metric,
+ mode: Text,
+ logger_fn: Callable = None,
+):
+ data_time, batch_time = AverageMeter(), AverageMeter()
+ if mode.lower() == "train":
+ network.train()
+ elif mode.lower() == "valid":
+ network.eval()
+ else:
+ raise ValueError("The mode is not right : {:}".format(mode))
+
+ end = time.time()
+ for i, (inputs, targets) in enumerate(xloader):
+ # measure data loading time
+ data_time.update(time.time() - end)
+ # calculate prediction and loss
+
+ if mode == "train":
+ optimizer.zero_grad()
+
+ outputs = network(inputs)
+ targets = targets.to(get_device(outputs))
+
+ if mode == "train":
+ loss = criterion(outputs, targets)
+ loss.backward()
+ optimizer.step()
+
+ # record
+ with torch.no_grad():
+ results = metric(outputs, targets)
+
+ # measure elapsed time
+ batch_time.update(time.time() - end)
+ end = time.time()
+ return metric.get_info()
diff --git a/AutoDL-Projects/xautodl/procedures/basic_main.py b/AutoDL-Projects/xautodl/procedures/basic_main.py
new file mode 100644
index 0000000..1d74978
--- /dev/null
+++ b/AutoDL-Projects/xautodl/procedures/basic_main.py
@@ -0,0 +1,154 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019 #
+##################################################
+import os, sys, time, torch
+
+# modules in AutoDL
+from xautodl.log_utils import AverageMeter, time_string
+from .eval_funcs import obtain_accuracy
+
+
+def basic_train(
+ xloader,
+ network,
+ criterion,
+ scheduler,
+ optimizer,
+ optim_config,
+ extra_info,
+ print_freq,
+ logger,
+):
+ loss, acc1, acc5 = procedure(
+ xloader,
+ network,
+ criterion,
+ scheduler,
+ optimizer,
+ "train",
+ optim_config,
+ extra_info,
+ print_freq,
+ logger,
+ )
+ return loss, acc1, acc5
+
+
+def basic_valid(
+ xloader, network, criterion, optim_config, extra_info, print_freq, logger
+):
+ with torch.no_grad():
+ loss, acc1, acc5 = procedure(
+ xloader,
+ network,
+ criterion,
+ None,
+ None,
+ "valid",
+ None,
+ extra_info,
+ print_freq,
+ logger,
+ )
+ return loss, acc1, acc5
+
+
+def procedure(
+ xloader,
+ network,
+ criterion,
+ scheduler,
+ optimizer,
+ mode,
+ config,
+ extra_info,
+ print_freq,
+ logger,
+):
+ data_time, batch_time, losses, top1, top5 = (
+ AverageMeter(),
+ AverageMeter(),
+ AverageMeter(),
+ AverageMeter(),
+ AverageMeter(),
+ )
+ if mode == "train":
+ network.train()
+ elif mode == "valid":
+ network.eval()
+ else:
+ raise ValueError("The mode is not right : {:}".format(mode))
+
+ # logger.log('[{:5s}] config :: auxiliary={:}, message={:}'.format(mode, config.auxiliary if hasattr(config, 'auxiliary') else -1, network.module.get_message()))
+ logger.log(
+ "[{:5s}] config :: auxiliary={:}".format(
+ mode, config.auxiliary if hasattr(config, "auxiliary") else -1
+ )
+ )
+ end = time.time()
+ for i, (inputs, targets) in enumerate(xloader):
+ if mode == "train":
+ scheduler.update(None, 1.0 * i / len(xloader))
+ # measure data loading time
+ data_time.update(time.time() - end)
+ # calculate prediction and loss
+ targets = targets.cuda(non_blocking=True)
+
+ if mode == "train":
+ optimizer.zero_grad()
+
+ features, logits = network(inputs)
+ if isinstance(logits, list):
+ assert len(logits) == 2, "logits must has {:} items instead of {:}".format(
+ 2, len(logits)
+ )
+ logits, logits_aux = logits
+ else:
+ logits, logits_aux = logits, None
+ loss = criterion(logits, targets)
+ if config is not None and hasattr(config, "auxiliary") and config.auxiliary > 0:
+ loss_aux = criterion(logits_aux, targets)
+ loss += config.auxiliary * loss_aux
+
+ if mode == "train":
+ loss.backward()
+ optimizer.step()
+
+ # record
+ prec1, prec5 = obtain_accuracy(logits.data, targets.data, topk=(1, 5))
+ losses.update(loss.item(), inputs.size(0))
+ top1.update(prec1.item(), inputs.size(0))
+ top5.update(prec5.item(), inputs.size(0))
+
+ # measure elapsed time
+ batch_time.update(time.time() - end)
+ end = time.time()
+
+ if i % print_freq == 0 or (i + 1) == len(xloader):
+ Sstr = (
+ " {:5s} ".format(mode.upper())
+ + time_string()
+ + " [{:}][{:03d}/{:03d}]".format(extra_info, i, len(xloader))
+ )
+ if scheduler is not None:
+ Sstr += " {:}".format(scheduler.get_min_info())
+ Tstr = "Time {batch_time.val:.2f} ({batch_time.avg:.2f}) Data {data_time.val:.2f} ({data_time.avg:.2f})".format(
+ batch_time=batch_time, data_time=data_time
+ )
+ Lstr = "Loss {loss.val:.3f} ({loss.avg:.3f}) Prec@1 {top1.val:.2f} ({top1.avg:.2f}) Prec@5 {top5.val:.2f} ({top5.avg:.2f})".format(
+ loss=losses, top1=top1, top5=top5
+ )
+ Istr = "Size={:}".format(list(inputs.size()))
+ logger.log(Sstr + " " + Tstr + " " + Lstr + " " + Istr)
+
+ logger.log(
+ " **{mode:5s}** Prec@1 {top1.avg:.2f} Prec@5 {top5.avg:.2f} Error@1 {error1:.2f} Error@5 {error5:.2f} Loss:{loss:.3f}".format(
+ mode=mode.upper(),
+ top1=top1,
+ top5=top5,
+ error1=100 - top1.avg,
+ error5=100 - top5.avg,
+ loss=losses.avg,
+ )
+ )
+ return losses.avg, top1.avg, top5.avg
diff --git a/AutoDL-Projects/xautodl/procedures/eval_funcs.py b/AutoDL-Projects/xautodl/procedures/eval_funcs.py
new file mode 100644
index 0000000..006ba35
--- /dev/null
+++ b/AutoDL-Projects/xautodl/procedures/eval_funcs.py
@@ -0,0 +1,20 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020.04 #
+#####################################################
+import abc
+
+
+def obtain_accuracy(output, target, topk=(1,)):
+ """Computes the precision@k for the specified values of k"""
+ maxk = max(topk)
+ batch_size = target.size(0)
+
+ _, pred = output.topk(maxk, 1, True, True)
+ pred = pred.t()
+ correct = pred.eq(target.view(1, -1).expand_as(pred))
+
+ res = []
+ for k in topk:
+ correct_k = correct[:k].contiguous().view(-1).float().sum(0, keepdim=True)
+ res.append(correct_k.mul_(100.0 / batch_size))
+ return res
diff --git a/AutoDL-Projects/xautodl/procedures/funcs_nasbench.py b/AutoDL-Projects/xautodl/procedures/funcs_nasbench.py
new file mode 100644
index 0000000..dfe69d3
--- /dev/null
+++ b/AutoDL-Projects/xautodl/procedures/funcs_nasbench.py
@@ -0,0 +1,437 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.08 #
+#####################################################
+import os, time, copy, torch, pathlib
+
+from xautodl import datasets
+from xautodl.config_utils import load_config
+from xautodl.procedures import prepare_seed, get_optim_scheduler
+from xautodl.log_utils import AverageMeter, time_string, convert_secs2time
+from xautodl.models import get_cell_based_tiny_net
+from xautodl.utils import get_model_infos
+from xautodl.procedures.eval_funcs import obtain_accuracy
+
+
+__all__ = ["evaluate_for_seed", "pure_evaluate", "get_nas_bench_loaders"]
+
+
+def pure_evaluate(xloader, network, criterion=torch.nn.CrossEntropyLoss()):
+ data_time, batch_time, batch = AverageMeter(), AverageMeter(), None
+ losses, top1, top5 = AverageMeter(), AverageMeter(), AverageMeter()
+ latencies, device = [], torch.cuda.current_device()
+ network.eval()
+ with torch.no_grad():
+ end = time.time()
+ for i, (inputs, targets) in enumerate(xloader):
+ targets = targets.cuda(device=device, non_blocking=True)
+ inputs = inputs.cuda(device=device, non_blocking=True)
+ data_time.update(time.time() - end)
+ # forward
+ features, logits = network(inputs)
+ loss = criterion(logits, targets)
+ batch_time.update(time.time() - end)
+ if batch is None or batch == inputs.size(0):
+ batch = inputs.size(0)
+ latencies.append(batch_time.val - data_time.val)
+ # record loss and accuracy
+ prec1, prec5 = obtain_accuracy(logits.data, targets.data, topk=(1, 5))
+ losses.update(loss.item(), inputs.size(0))
+ top1.update(prec1.item(), inputs.size(0))
+ top5.update(prec5.item(), inputs.size(0))
+ end = time.time()
+ if len(latencies) > 2:
+ latencies = latencies[1:]
+ return losses.avg, top1.avg, top5.avg, latencies
+
+
+def procedure(xloader, network, criterion, scheduler, optimizer, mode: str):
+ losses, top1, top5 = AverageMeter(), AverageMeter(), AverageMeter()
+ if mode == "train":
+ network.train()
+ elif mode == "valid":
+ network.eval()
+ else:
+ raise ValueError("The mode is not right : {:}".format(mode))
+ device = torch.cuda.current_device()
+ data_time, batch_time, end = AverageMeter(), AverageMeter(), time.time()
+ for i, (inputs, targets) in enumerate(xloader):
+ if mode == "train":
+ scheduler.update(None, 1.0 * i / len(xloader))
+
+ targets = targets.cuda(device=device, non_blocking=True)
+ if mode == "train":
+ optimizer.zero_grad()
+ # forward
+ features, logits = network(inputs)
+ loss = criterion(logits, targets)
+ # backward
+ if mode == "train":
+ loss.backward()
+ optimizer.step()
+ # record loss and accuracy
+ prec1, prec5 = obtain_accuracy(logits.data, targets.data, topk=(1, 5))
+ losses.update(loss.item(), inputs.size(0))
+ top1.update(prec1.item(), inputs.size(0))
+ top5.update(prec5.item(), inputs.size(0))
+ # count time
+ batch_time.update(time.time() - end)
+ end = time.time()
+ return losses.avg, top1.avg, top5.avg, batch_time.sum
+
+
+def evaluate_for_seed(
+ arch_config, opt_config, train_loader, valid_loaders, seed: int, logger
+):
+ """A modular function to train and evaluate a single network, using the given random seed and optimization config with the provided loaders."""
+ prepare_seed(seed) # random seed
+ net = get_cell_based_tiny_net(arch_config)
+ # net = TinyNetwork(arch_config['channel'], arch_config['num_cells'], arch, config.class_num)
+ flop, param = get_model_infos(net, opt_config.xshape)
+ logger.log("Network : {:}".format(net.get_message()), False)
+ logger.log(
+ "{:} Seed-------------------------- {:} --------------------------".format(
+ time_string(), seed
+ )
+ )
+ logger.log("FLOP = {:} MB, Param = {:} MB".format(flop, param))
+ # train and valid
+ optimizer, scheduler, criterion = get_optim_scheduler(net.parameters(), opt_config)
+ default_device = torch.cuda.current_device()
+ network = torch.nn.DataParallel(net, device_ids=[default_device]).cuda(
+ device=default_device
+ )
+ criterion = criterion.cuda(device=default_device)
+ # start training
+ start_time, epoch_time, total_epoch = (
+ time.time(),
+ AverageMeter(),
+ opt_config.epochs + opt_config.warmup,
+ )
+ (
+ train_losses,
+ train_acc1es,
+ train_acc5es,
+ valid_losses,
+ valid_acc1es,
+ valid_acc5es,
+ ) = ({}, {}, {}, {}, {}, {})
+ train_times, valid_times, lrs = {}, {}, {}
+ for epoch in range(total_epoch):
+ scheduler.update(epoch, 0.0)
+ lr = min(scheduler.get_lr())
+ train_loss, train_acc1, train_acc5, train_tm = procedure(
+ train_loader, network, criterion, scheduler, optimizer, "train"
+ )
+ train_losses[epoch] = train_loss
+ train_acc1es[epoch] = train_acc1
+ train_acc5es[epoch] = train_acc5
+ train_times[epoch] = train_tm
+ lrs[epoch] = lr
+ with torch.no_grad():
+ for key, xloder in valid_loaders.items():
+ valid_loss, valid_acc1, valid_acc5, valid_tm = procedure(
+ xloder, network, criterion, None, None, "valid"
+ )
+ valid_losses["{:}@{:}".format(key, epoch)] = valid_loss
+ valid_acc1es["{:}@{:}".format(key, epoch)] = valid_acc1
+ valid_acc5es["{:}@{:}".format(key, epoch)] = valid_acc5
+ valid_times["{:}@{:}".format(key, epoch)] = valid_tm
+
+ # measure elapsed time
+ epoch_time.update(time.time() - start_time)
+ start_time = time.time()
+ need_time = "Time Left: {:}".format(
+ convert_secs2time(epoch_time.avg * (total_epoch - epoch - 1), True)
+ )
+ logger.log(
+ "{:} {:} epoch={:03d}/{:03d} :: Train [loss={:.5f}, acc@1={:.2f}%, acc@5={:.2f}%] Valid [loss={:.5f}, acc@1={:.2f}%, acc@5={:.2f}%], lr={:}".format(
+ time_string(),
+ need_time,
+ epoch,
+ total_epoch,
+ train_loss,
+ train_acc1,
+ train_acc5,
+ valid_loss,
+ valid_acc1,
+ valid_acc5,
+ lr,
+ )
+ )
+ info_seed = {
+ "flop": flop,
+ "param": param,
+ "arch_config": arch_config._asdict(),
+ "opt_config": opt_config._asdict(),
+ "total_epoch": total_epoch,
+ "train_losses": train_losses,
+ "train_acc1es": train_acc1es,
+ "train_acc5es": train_acc5es,
+ "train_times": train_times,
+ "valid_losses": valid_losses,
+ "valid_acc1es": valid_acc1es,
+ "valid_acc5es": valid_acc5es,
+ "valid_times": valid_times,
+ "learning_rates": lrs,
+ "net_state_dict": net.state_dict(),
+ "net_string": "{:}".format(net),
+ "finish-train": True,
+ }
+ return info_seed
+
+
+def get_nas_bench_loaders(workers):
+
+ torch.set_num_threads(workers)
+
+ root_dir = (pathlib.Path(__file__).parent / ".." / "..").resolve()
+ torch_dir = pathlib.Path(os.environ["TORCH_HOME"])
+ # cifar
+ cifar_config_path = root_dir / "configs" / "nas-benchmark" / "CIFAR.config"
+ cifar_config = load_config(cifar_config_path, None, None)
+ get_datasets = datasets.get_datasets # a function to return the dataset
+ break_line = "-" * 150
+ print("{:} Create data-loader for all datasets".format(time_string()))
+ print(break_line)
+ TRAIN_CIFAR10, VALID_CIFAR10, xshape, class_num = get_datasets(
+ "cifar10", str(torch_dir / "cifar.python"), -1
+ )
+ print(
+ "original CIFAR-10 : {:} training images and {:} test images : {:} input shape : {:} number of classes".format(
+ len(TRAIN_CIFAR10), len(VALID_CIFAR10), xshape, class_num
+ )
+ )
+ cifar10_splits = load_config(
+ root_dir / "configs" / "nas-benchmark" / "cifar-split.txt", None, None
+ )
+ assert cifar10_splits.train[:10] == [
+ 0,
+ 5,
+ 7,
+ 11,
+ 13,
+ 15,
+ 16,
+ 17,
+ 20,
+ 24,
+ ] and cifar10_splits.valid[:10] == [
+ 1,
+ 2,
+ 3,
+ 4,
+ 6,
+ 8,
+ 9,
+ 10,
+ 12,
+ 14,
+ ]
+ temp_dataset = copy.deepcopy(TRAIN_CIFAR10)
+ temp_dataset.transform = VALID_CIFAR10.transform
+ # data loader
+ trainval_cifar10_loader = torch.utils.data.DataLoader(
+ TRAIN_CIFAR10,
+ batch_size=cifar_config.batch_size,
+ shuffle=True,
+ num_workers=workers,
+ pin_memory=True,
+ )
+ train_cifar10_loader = torch.utils.data.DataLoader(
+ TRAIN_CIFAR10,
+ batch_size=cifar_config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(cifar10_splits.train),
+ num_workers=workers,
+ pin_memory=True,
+ )
+ valid_cifar10_loader = torch.utils.data.DataLoader(
+ temp_dataset,
+ batch_size=cifar_config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(cifar10_splits.valid),
+ num_workers=workers,
+ pin_memory=True,
+ )
+ test__cifar10_loader = torch.utils.data.DataLoader(
+ VALID_CIFAR10,
+ batch_size=cifar_config.batch_size,
+ shuffle=False,
+ num_workers=workers,
+ pin_memory=True,
+ )
+ print(
+ "CIFAR-10 : trval-loader has {:3d} batch with {:} per batch".format(
+ len(trainval_cifar10_loader), cifar_config.batch_size
+ )
+ )
+ print(
+ "CIFAR-10 : train-loader has {:3d} batch with {:} per batch".format(
+ len(train_cifar10_loader), cifar_config.batch_size
+ )
+ )
+ print(
+ "CIFAR-10 : valid-loader has {:3d} batch with {:} per batch".format(
+ len(valid_cifar10_loader), cifar_config.batch_size
+ )
+ )
+ print(
+ "CIFAR-10 : test--loader has {:3d} batch with {:} per batch".format(
+ len(test__cifar10_loader), cifar_config.batch_size
+ )
+ )
+ print(break_line)
+ # CIFAR-100
+ TRAIN_CIFAR100, VALID_CIFAR100, xshape, class_num = get_datasets(
+ "cifar100", str(torch_dir / "cifar.python"), -1
+ )
+ print(
+ "original CIFAR-100: {:} training images and {:} test images : {:} input shape : {:} number of classes".format(
+ len(TRAIN_CIFAR100), len(VALID_CIFAR100), xshape, class_num
+ )
+ )
+ cifar100_splits = load_config(
+ root_dir / "configs" / "nas-benchmark" / "cifar100-test-split.txt", None, None
+ )
+ assert cifar100_splits.xvalid[:10] == [
+ 1,
+ 3,
+ 4,
+ 5,
+ 8,
+ 10,
+ 13,
+ 14,
+ 15,
+ 16,
+ ] and cifar100_splits.xtest[:10] == [
+ 0,
+ 2,
+ 6,
+ 7,
+ 9,
+ 11,
+ 12,
+ 17,
+ 20,
+ 24,
+ ]
+ train_cifar100_loader = torch.utils.data.DataLoader(
+ TRAIN_CIFAR100,
+ batch_size=cifar_config.batch_size,
+ shuffle=True,
+ num_workers=workers,
+ pin_memory=True,
+ )
+ valid_cifar100_loader = torch.utils.data.DataLoader(
+ VALID_CIFAR100,
+ batch_size=cifar_config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(cifar100_splits.xvalid),
+ num_workers=workers,
+ pin_memory=True,
+ )
+ test__cifar100_loader = torch.utils.data.DataLoader(
+ VALID_CIFAR100,
+ batch_size=cifar_config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(cifar100_splits.xtest),
+ num_workers=workers,
+ pin_memory=True,
+ )
+ print(
+ "CIFAR-100 : train-loader has {:3d} batch".format(len(train_cifar100_loader))
+ )
+ print(
+ "CIFAR-100 : valid-loader has {:3d} batch".format(len(valid_cifar100_loader))
+ )
+ print(
+ "CIFAR-100 : test--loader has {:3d} batch".format(len(test__cifar100_loader))
+ )
+ print(break_line)
+
+ imagenet16_config_path = "configs/nas-benchmark/ImageNet-16.config"
+ imagenet16_config = load_config(imagenet16_config_path, None, None)
+ TRAIN_ImageNet16_120, VALID_ImageNet16_120, xshape, class_num = get_datasets(
+ "ImageNet16-120", str(torch_dir / "cifar.python" / "ImageNet16"), -1
+ )
+ print(
+ "original TRAIN_ImageNet16_120: {:} training images and {:} test images : {:} input shape : {:} number of classes".format(
+ len(TRAIN_ImageNet16_120), len(VALID_ImageNet16_120), xshape, class_num
+ )
+ )
+ imagenet_splits = load_config(
+ root_dir / "configs" / "nas-benchmark" / "imagenet-16-120-test-split.txt",
+ None,
+ None,
+ )
+ assert imagenet_splits.xvalid[:10] == [
+ 1,
+ 2,
+ 3,
+ 6,
+ 7,
+ 8,
+ 9,
+ 12,
+ 16,
+ 18,
+ ] and imagenet_splits.xtest[:10] == [
+ 0,
+ 4,
+ 5,
+ 10,
+ 11,
+ 13,
+ 14,
+ 15,
+ 17,
+ 20,
+ ]
+ train_imagenet_loader = torch.utils.data.DataLoader(
+ TRAIN_ImageNet16_120,
+ batch_size=imagenet16_config.batch_size,
+ shuffle=True,
+ num_workers=workers,
+ pin_memory=True,
+ )
+ valid_imagenet_loader = torch.utils.data.DataLoader(
+ VALID_ImageNet16_120,
+ batch_size=imagenet16_config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(imagenet_splits.xvalid),
+ num_workers=workers,
+ pin_memory=True,
+ )
+ test__imagenet_loader = torch.utils.data.DataLoader(
+ VALID_ImageNet16_120,
+ batch_size=imagenet16_config.batch_size,
+ sampler=torch.utils.data.sampler.SubsetRandomSampler(imagenet_splits.xtest),
+ num_workers=workers,
+ pin_memory=True,
+ )
+ print(
+ "ImageNet-16-120 : train-loader has {:3d} batch with {:} per batch".format(
+ len(train_imagenet_loader), imagenet16_config.batch_size
+ )
+ )
+ print(
+ "ImageNet-16-120 : valid-loader has {:3d} batch with {:} per batch".format(
+ len(valid_imagenet_loader), imagenet16_config.batch_size
+ )
+ )
+ print(
+ "ImageNet-16-120 : test--loader has {:3d} batch with {:} per batch".format(
+ len(test__imagenet_loader), imagenet16_config.batch_size
+ )
+ )
+
+ # 'cifar10', 'cifar100', 'ImageNet16-120'
+ loaders = {
+ "cifar10@trainval": trainval_cifar10_loader,
+ "cifar10@train": train_cifar10_loader,
+ "cifar10@valid": valid_cifar10_loader,
+ "cifar10@test": test__cifar10_loader,
+ "cifar100@train": train_cifar100_loader,
+ "cifar100@valid": valid_cifar100_loader,
+ "cifar100@test": test__cifar100_loader,
+ "ImageNet16-120@train": train_imagenet_loader,
+ "ImageNet16-120@valid": valid_imagenet_loader,
+ "ImageNet16-120@test": test__imagenet_loader,
+ }
+ return loaders
diff --git a/AutoDL-Projects/xautodl/procedures/metric_utils.py b/AutoDL-Projects/xautodl/procedures/metric_utils.py
new file mode 100644
index 0000000..28b2cff
--- /dev/null
+++ b/AutoDL-Projects/xautodl/procedures/metric_utils.py
@@ -0,0 +1,166 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020.04 #
+#####################################################
+import abc
+import numpy as np
+import torch
+
+
+class AverageMeter(object):
+ """Computes and stores the average and current value"""
+
+ def __init__(self):
+ self.reset()
+
+ def reset(self):
+ self.val = 0.0
+ self.avg = 0.0
+ self.sum = 0.0
+ self.count = 0.0
+
+ def update(self, val, n=1):
+ self.val = val
+ self.sum += val * n
+ self.count += n
+ self.avg = self.sum / self.count
+
+ def __repr__(self):
+ return "{name}(val={val}, avg={avg}, count={count})".format(
+ name=self.__class__.__name__, **self.__dict__
+ )
+
+
+class Metric(abc.ABC):
+ """The default meta metric class."""
+
+ def __init__(self):
+ self.reset()
+
+ def reset(self):
+ raise NotImplementedError
+
+ def __call__(self, predictions, targets):
+ raise NotImplementedError
+
+ def get_info(self):
+ raise NotImplementedError
+
+ def __repr__(self):
+ return "{name}({inner})".format(
+ name=self.__class__.__name__, inner=self.inner_repr()
+ )
+
+ def inner_repr(self):
+ return ""
+
+
+class ComposeMetric(Metric):
+ """The composed metric class."""
+
+ def __init__(self, *metric_list):
+ self.reset()
+ for metric in metric_list:
+ self.append(metric)
+
+ def reset(self):
+ self._metric_list = []
+
+ def append(self, metric):
+ if not isinstance(metric, Metric):
+ raise ValueError(
+ "The input metric is not correct: {:}".format(type(metric))
+ )
+ self._metric_list.append(metric)
+
+ def __len__(self):
+ return len(self._metric_list)
+
+ def __call__(self, predictions, targets):
+ results = list()
+ for metric in self._metric_list:
+ results.append(metric(predictions, targets))
+ return results
+
+ def get_info(self):
+ results = dict()
+ for metric in self._metric_list:
+ for key, value in metric.get_info().items():
+ results[key] = value
+ return results
+
+ def inner_repr(self):
+ xlist = []
+ for metric in self._metric_list:
+ xlist.append(str(metric))
+ return ",".join(xlist)
+
+
+class MSEMetric(Metric):
+ """The metric for mse."""
+
+ def __init__(self, ignore_batch):
+ super(MSEMetric, self).__init__()
+ self._ignore_batch = ignore_batch
+
+ def reset(self):
+ self._mse = AverageMeter()
+
+ def __call__(self, predictions, targets):
+ if isinstance(predictions, torch.Tensor) and isinstance(targets, torch.Tensor):
+ loss = torch.nn.functional.mse_loss(predictions.data, targets.data).item()
+ if self._ignore_batch:
+ self._mse.update(loss, 1)
+ else:
+ self._mse.update(loss, predictions.shape[0])
+ return loss
+ else:
+ raise NotImplementedError
+
+ def get_info(self):
+ return {"mse": self._mse.avg, "score": self._mse.avg}
+
+
+class Top1AccMetric(Metric):
+ """The metric for the top-1 accuracy."""
+
+ def __init__(self, ignore_batch):
+ super(Top1AccMetric, self).__init__()
+ self._ignore_batch = ignore_batch
+
+ def reset(self):
+ self._accuracy = AverageMeter()
+
+ def __call__(self, predictions, targets):
+ if isinstance(predictions, torch.Tensor) and isinstance(targets, torch.Tensor):
+ max_prob_indexes = torch.argmax(predictions, dim=-1)
+ corrects = torch.eq(max_prob_indexes, targets)
+ accuracy = corrects.float().mean().float()
+ if self._ignore_batch:
+ self._accuracy.update(accuracy, 1)
+ else: # [TODO] for 3-d tensor
+ self._accuracy.update(accuracy, predictions.shape[0])
+ return accuracy
+ else:
+ raise NotImplementedError
+
+ def get_info(self):
+ return {"accuracy": self._accuracy.avg, "score": self._accuracy.avg * 100}
+
+
+class SaveMetric(Metric):
+ """The metric for mse."""
+
+ def reset(self):
+ self._predicts = []
+
+ def __call__(self, predictions, targets=None):
+ if isinstance(predictions, torch.Tensor):
+ predicts = predictions.cpu().numpy()
+ self._predicts.append(predicts)
+ return predicts
+ else:
+ raise NotImplementedError
+
+ def get_info(self):
+ all_predicts = np.concatenate(self._predicts)
+ return {"predictions": all_predicts}
diff --git a/AutoDL-Projects/xautodl/procedures/optimizers.py b/AutoDL-Projects/xautodl/procedures/optimizers.py
new file mode 100644
index 0000000..813ba8d
--- /dev/null
+++ b/AutoDL-Projects/xautodl/procedures/optimizers.py
@@ -0,0 +1,263 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.01 #
+#####################################################
+import math, torch
+import torch.nn as nn
+from bisect import bisect_right
+from torch.optim import Optimizer
+
+
+class _LRScheduler(object):
+ def __init__(self, optimizer, warmup_epochs, epochs):
+ if not isinstance(optimizer, Optimizer):
+ raise TypeError("{:} is not an Optimizer".format(type(optimizer).__name__))
+ self.optimizer = optimizer
+ for group in optimizer.param_groups:
+ group.setdefault("initial_lr", group["lr"])
+ self.base_lrs = list(
+ map(lambda group: group["initial_lr"], optimizer.param_groups)
+ )
+ self.max_epochs = epochs
+ self.warmup_epochs = warmup_epochs
+ self.current_epoch = 0
+ self.current_iter = 0
+
+ def extra_repr(self):
+ return ""
+
+ def __repr__(self):
+ return "{name}(warmup={warmup_epochs}, max-epoch={max_epochs}, current::epoch={current_epoch}, iter={current_iter:.2f}".format(
+ name=self.__class__.__name__, **self.__dict__
+ ) + ", {:})".format(
+ self.extra_repr()
+ )
+
+ def state_dict(self):
+ return {
+ key: value for key, value in self.__dict__.items() if key != "optimizer"
+ }
+
+ def load_state_dict(self, state_dict):
+ self.__dict__.update(state_dict)
+
+ def get_lr(self):
+ raise NotImplementedError
+
+ def get_min_info(self):
+ lrs = self.get_lr()
+ return "#LR=[{:.6f}~{:.6f}] epoch={:03d}, iter={:4.2f}#".format(
+ min(lrs), max(lrs), self.current_epoch, self.current_iter
+ )
+
+ def get_min_lr(self):
+ return min(self.get_lr())
+
+ def update(self, cur_epoch, cur_iter):
+ if cur_epoch is not None:
+ assert (
+ isinstance(cur_epoch, int) and cur_epoch >= 0
+ ), "invalid cur-epoch : {:}".format(cur_epoch)
+ self.current_epoch = cur_epoch
+ if cur_iter is not None:
+ assert (
+ isinstance(cur_iter, float) and cur_iter >= 0
+ ), "invalid cur-iter : {:}".format(cur_iter)
+ self.current_iter = cur_iter
+ for param_group, lr in zip(self.optimizer.param_groups, self.get_lr()):
+ param_group["lr"] = lr
+
+
+class CosineAnnealingLR(_LRScheduler):
+ def __init__(self, optimizer, warmup_epochs, epochs, T_max, eta_min):
+ self.T_max = T_max
+ self.eta_min = eta_min
+ super(CosineAnnealingLR, self).__init__(optimizer, warmup_epochs, epochs)
+
+ def extra_repr(self):
+ return "type={:}, T-max={:}, eta-min={:}".format(
+ "cosine", self.T_max, self.eta_min
+ )
+
+ def get_lr(self):
+ lrs = []
+ for base_lr in self.base_lrs:
+ if (
+ self.current_epoch >= self.warmup_epochs
+ and self.current_epoch < self.max_epochs
+ ):
+ last_epoch = self.current_epoch - self.warmup_epochs
+ # if last_epoch < self.T_max:
+ # if last_epoch < self.max_epochs:
+ lr = (
+ self.eta_min
+ + (base_lr - self.eta_min)
+ * (1 + math.cos(math.pi * last_epoch / self.T_max))
+ / 2
+ )
+ # else:
+ # lr = self.eta_min + (base_lr - self.eta_min) * (1 + math.cos(math.pi * (self.T_max-1.0) / self.T_max)) / 2
+ elif self.current_epoch >= self.max_epochs:
+ lr = self.eta_min
+ else:
+ lr = (
+ self.current_epoch / self.warmup_epochs
+ + self.current_iter / self.warmup_epochs
+ ) * base_lr
+ lrs.append(lr)
+ return lrs
+
+
+class MultiStepLR(_LRScheduler):
+ def __init__(self, optimizer, warmup_epochs, epochs, milestones, gammas):
+ assert len(milestones) == len(gammas), "invalid {:} vs {:}".format(
+ len(milestones), len(gammas)
+ )
+ self.milestones = milestones
+ self.gammas = gammas
+ super(MultiStepLR, self).__init__(optimizer, warmup_epochs, epochs)
+
+ def extra_repr(self):
+ return "type={:}, milestones={:}, gammas={:}, base-lrs={:}".format(
+ "multistep", self.milestones, self.gammas, self.base_lrs
+ )
+
+ def get_lr(self):
+ lrs = []
+ for base_lr in self.base_lrs:
+ if self.current_epoch >= self.warmup_epochs:
+ last_epoch = self.current_epoch - self.warmup_epochs
+ idx = bisect_right(self.milestones, last_epoch)
+ lr = base_lr
+ for x in self.gammas[:idx]:
+ lr *= x
+ else:
+ lr = (
+ self.current_epoch / self.warmup_epochs
+ + self.current_iter / self.warmup_epochs
+ ) * base_lr
+ lrs.append(lr)
+ return lrs
+
+
+class ExponentialLR(_LRScheduler):
+ def __init__(self, optimizer, warmup_epochs, epochs, gamma):
+ self.gamma = gamma
+ super(ExponentialLR, self).__init__(optimizer, warmup_epochs, epochs)
+
+ def extra_repr(self):
+ return "type={:}, gamma={:}, base-lrs={:}".format(
+ "exponential", self.gamma, self.base_lrs
+ )
+
+ def get_lr(self):
+ lrs = []
+ for base_lr in self.base_lrs:
+ if self.current_epoch >= self.warmup_epochs:
+ last_epoch = self.current_epoch - self.warmup_epochs
+ assert last_epoch >= 0, "invalid last_epoch : {:}".format(last_epoch)
+ lr = base_lr * (self.gamma**last_epoch)
+ else:
+ lr = (
+ self.current_epoch / self.warmup_epochs
+ + self.current_iter / self.warmup_epochs
+ ) * base_lr
+ lrs.append(lr)
+ return lrs
+
+
+class LinearLR(_LRScheduler):
+ def __init__(self, optimizer, warmup_epochs, epochs, max_LR, min_LR):
+ self.max_LR = max_LR
+ self.min_LR = min_LR
+ super(LinearLR, self).__init__(optimizer, warmup_epochs, epochs)
+
+ def extra_repr(self):
+ return "type={:}, max_LR={:}, min_LR={:}, base-lrs={:}".format(
+ "LinearLR", self.max_LR, self.min_LR, self.base_lrs
+ )
+
+ def get_lr(self):
+ lrs = []
+ for base_lr in self.base_lrs:
+ if self.current_epoch >= self.warmup_epochs:
+ last_epoch = self.current_epoch - self.warmup_epochs
+ assert last_epoch >= 0, "invalid last_epoch : {:}".format(last_epoch)
+ ratio = (
+ (self.max_LR - self.min_LR)
+ * last_epoch
+ / self.max_epochs
+ / self.max_LR
+ )
+ lr = base_lr * (1 - ratio)
+ else:
+ lr = (
+ self.current_epoch / self.warmup_epochs
+ + self.current_iter / self.warmup_epochs
+ ) * base_lr
+ lrs.append(lr)
+ return lrs
+
+
+class CrossEntropyLabelSmooth(nn.Module):
+ def __init__(self, num_classes, epsilon):
+ super(CrossEntropyLabelSmooth, self).__init__()
+ self.num_classes = num_classes
+ self.epsilon = epsilon
+ self.logsoftmax = nn.LogSoftmax(dim=1)
+
+ def forward(self, inputs, targets):
+ log_probs = self.logsoftmax(inputs)
+ targets = torch.zeros_like(log_probs).scatter_(1, targets.unsqueeze(1), 1)
+ targets = (1 - self.epsilon) * targets + self.epsilon / self.num_classes
+ loss = (-targets * log_probs).mean(0).sum()
+ return loss
+
+
+def get_optim_scheduler(parameters, config):
+ assert (
+ hasattr(config, "optim")
+ and hasattr(config, "scheduler")
+ and hasattr(config, "criterion")
+ ), "config must have optim / scheduler / criterion keys instead of {:}".format(
+ config
+ )
+ if config.optim == "SGD":
+ optim = torch.optim.SGD(
+ parameters,
+ config.LR,
+ momentum=config.momentum,
+ weight_decay=config.decay,
+ nesterov=config.nesterov,
+ )
+ elif config.optim == "RMSprop":
+ optim = torch.optim.RMSprop(
+ parameters, config.LR, momentum=config.momentum, weight_decay=config.decay
+ )
+ else:
+ raise ValueError("invalid optim : {:}".format(config.optim))
+
+ if config.scheduler == "cos":
+ T_max = getattr(config, "T_max", config.epochs)
+ scheduler = CosineAnnealingLR(
+ optim, config.warmup, config.epochs, T_max, config.eta_min
+ )
+ elif config.scheduler == "multistep":
+ scheduler = MultiStepLR(
+ optim, config.warmup, config.epochs, config.milestones, config.gammas
+ )
+ elif config.scheduler == "exponential":
+ scheduler = ExponentialLR(optim, config.warmup, config.epochs, config.gamma)
+ elif config.scheduler == "linear":
+ scheduler = LinearLR(
+ optim, config.warmup, config.epochs, config.LR, config.LR_min
+ )
+ else:
+ raise ValueError("invalid scheduler : {:}".format(config.scheduler))
+
+ if config.criterion == "Softmax":
+ criterion = torch.nn.CrossEntropyLoss()
+ elif config.criterion == "SmoothSoftmax":
+ criterion = CrossEntropyLabelSmooth(config.class_num, config.label_smooth)
+ else:
+ raise ValueError("invalid criterion : {:}".format(config.criterion))
+ return optim, scheduler, criterion
diff --git a/AutoDL-Projects/xautodl/procedures/q_exps.py b/AutoDL-Projects/xautodl/procedures/q_exps.py
new file mode 100644
index 0000000..22bf248
--- /dev/null
+++ b/AutoDL-Projects/xautodl/procedures/q_exps.py
@@ -0,0 +1,150 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.02 #
+#####################################################
+
+import inspect
+import os
+import pprint
+import logging
+from copy import deepcopy
+
+import qlib
+from qlib.utils import init_instance_by_config
+from qlib.workflow import R
+from qlib.utils import flatten_dict
+from qlib.log import get_module_logger
+
+
+def set_log_basic_config(filename=None, format=None, level=None):
+ """
+ Set the basic configuration for the logging system.
+ See details at https://docs.python.org/3/library/logging.html#logging.basicConfig
+ :param filename: str or None
+ The path to save the logs.
+ :param format: the logging format
+ :param level: int
+ :return: Logger
+ Logger object.
+ """
+ from qlib.config import C
+
+ if level is None:
+ level = C.logging_level
+
+ if format is None:
+ format = C.logging_config["formatters"]["logger_format"]["format"]
+
+ # Remove all handlers associated with the root logger object.
+ for handler in logging.root.handlers[:]:
+ logging.root.removeHandler(handler)
+ logging.basicConfig(filename=filename, format=format, level=level)
+
+
+def update_gpu(config, gpu):
+ config = deepcopy(config)
+ if "task" in config and "model" in config["task"]:
+ if "GPU" in config["task"]["model"]:
+ config["task"]["model"]["GPU"] = gpu
+ elif (
+ "kwargs" in config["task"]["model"]
+ and "GPU" in config["task"]["model"]["kwargs"]
+ ):
+ config["task"]["model"]["kwargs"]["GPU"] = gpu
+ elif "model" in config:
+ if "GPU" in config["model"]:
+ config["model"]["GPU"] = gpu
+ elif "kwargs" in config["model"] and "GPU" in config["model"]["kwargs"]:
+ config["model"]["kwargs"]["GPU"] = gpu
+ elif "kwargs" in config and "GPU" in config["kwargs"]:
+ config["kwargs"]["GPU"] = gpu
+ elif "GPU" in config:
+ config["GPU"] = gpu
+ return config
+
+
+def update_market(config, market):
+ config = deepcopy(config.copy())
+ config["market"] = market
+ config["data_handler_config"]["instruments"] = market
+ return config
+
+
+def run_exp(
+ task_config,
+ dataset,
+ experiment_name,
+ recorder_name,
+ uri,
+ model_obj_name="model.pkl",
+):
+
+ model = init_instance_by_config(task_config["model"])
+ model_fit_kwargs = dict(dataset=dataset)
+
+ # Let's start the experiment.
+ with R.start(
+ experiment_name=experiment_name,
+ recorder_name=recorder_name,
+ uri=uri,
+ resume=True,
+ ):
+ # Setup log
+ recorder_root_dir = R.get_recorder().get_local_dir()
+ log_file = os.path.join(recorder_root_dir, "{:}.log".format(experiment_name))
+
+ set_log_basic_config(log_file)
+ logger = get_module_logger("q.run_exp")
+ logger.info("task_config::\n{:}".format(pprint.pformat(task_config, indent=2)))
+ logger.info("[{:}] - [{:}]: {:}".format(experiment_name, recorder_name, uri))
+ logger.info("dataset={:}".format(dataset))
+
+ # Train model
+ try:
+ if hasattr(model, "to"): # Recoverable model
+ ori_device = model.device
+ model = R.load_object(model_obj_name)
+ model.to(ori_device)
+ else:
+ model = R.load_object(model_obj_name)
+ logger.info("[Find existing object from {:}]".format(model_obj_name))
+ except OSError:
+ R.log_params(**flatten_dict(update_gpu(task_config, None)))
+ if "save_path" in inspect.getfullargspec(model.fit).args:
+ model_fit_kwargs["save_path"] = os.path.join(
+ recorder_root_dir, "model.ckp"
+ )
+ elif "save_dir" in inspect.getfullargspec(model.fit).args:
+ model_fit_kwargs["save_dir"] = os.path.join(
+ recorder_root_dir, "model-ckps"
+ )
+ model.fit(**model_fit_kwargs)
+ # remove model to CPU for saving
+ if hasattr(model, "to"):
+ old_device = model.device
+ model.to("cpu")
+ R.save_objects(**{model_obj_name: model})
+ model.to(old_device)
+ else:
+ R.save_objects(**{model_obj_name: model})
+ except Exception as e:
+ raise ValueError("Something wrong: {:}".format(e))
+ # Get the recorder
+ recorder = R.get_recorder()
+
+ # Generate records: prediction, backtest, and analysis
+ for record in task_config["record"]:
+ record = deepcopy(record)
+ if record["class"] == "MultiSegRecord":
+ record["kwargs"] = dict(model=model, dataset=dataset, recorder=recorder)
+ sr = init_instance_by_config(record)
+ sr.generate(**record["generate_kwargs"])
+ elif record["class"] == "SignalRecord":
+ srconf = {"model": model, "dataset": dataset, "recorder": recorder}
+ record["kwargs"].update(srconf)
+ sr = init_instance_by_config(record)
+ sr.generate()
+ else:
+ rconf = {"recorder": recorder}
+ record["kwargs"].update(rconf)
+ ar = init_instance_by_config(record)
+ ar.generate()
diff --git a/AutoDL-Projects/xautodl/procedures/search_main.py b/AutoDL-Projects/xautodl/procedures/search_main.py
new file mode 100644
index 0000000..920ddbd
--- /dev/null
+++ b/AutoDL-Projects/xautodl/procedures/search_main.py
@@ -0,0 +1,199 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019 #
+##################################################
+import os, sys, time, torch
+
+from xautodl.log_utils import AverageMeter, time_string
+from xautodl.models import change_key
+
+from .eval_funcs import obtain_accuracy
+
+
+def get_flop_loss(expected_flop, flop_cur, flop_need, flop_tolerant):
+ expected_flop = torch.mean(expected_flop)
+
+ if flop_cur < flop_need - flop_tolerant: # Too Small FLOP
+ loss = -torch.log(expected_flop)
+ # elif flop_cur > flop_need + flop_tolerant: # Too Large FLOP
+ elif flop_cur > flop_need: # Too Large FLOP
+ loss = torch.log(expected_flop)
+ else: # Required FLOP
+ loss = None
+ if loss is None:
+ return 0, 0
+ else:
+ return loss, loss.item()
+
+
+def search_train(
+ search_loader,
+ network,
+ criterion,
+ scheduler,
+ base_optimizer,
+ arch_optimizer,
+ optim_config,
+ extra_info,
+ print_freq,
+ logger,
+):
+ data_time, batch_time = AverageMeter(), AverageMeter()
+ base_losses, arch_losses, top1, top5 = (
+ AverageMeter(),
+ AverageMeter(),
+ AverageMeter(),
+ AverageMeter(),
+ )
+ arch_cls_losses, arch_flop_losses = AverageMeter(), AverageMeter()
+ epoch_str, flop_need, flop_weight, flop_tolerant = (
+ extra_info["epoch-str"],
+ extra_info["FLOP-exp"],
+ extra_info["FLOP-weight"],
+ extra_info["FLOP-tolerant"],
+ )
+
+ network.train()
+ logger.log(
+ "[Search] : {:}, FLOP-Require={:.2f} MB, FLOP-WEIGHT={:.2f}".format(
+ epoch_str, flop_need, flop_weight
+ )
+ )
+ end = time.time()
+ network.apply(change_key("search_mode", "search"))
+ for step, (base_inputs, base_targets, arch_inputs, arch_targets) in enumerate(
+ search_loader
+ ):
+ scheduler.update(None, 1.0 * step / len(search_loader))
+ # calculate prediction and loss
+ base_targets = base_targets.cuda(non_blocking=True)
+ arch_targets = arch_targets.cuda(non_blocking=True)
+ # measure data loading time
+ data_time.update(time.time() - end)
+
+ # update the weights
+ base_optimizer.zero_grad()
+ logits, expected_flop = network(base_inputs)
+ # network.apply( change_key('search_mode', 'basic') )
+ # features, logits = network(base_inputs)
+ base_loss = criterion(logits, base_targets)
+ base_loss.backward()
+ base_optimizer.step()
+ # record
+ prec1, prec5 = obtain_accuracy(logits.data, base_targets.data, topk=(1, 5))
+ base_losses.update(base_loss.item(), base_inputs.size(0))
+ top1.update(prec1.item(), base_inputs.size(0))
+ top5.update(prec5.item(), base_inputs.size(0))
+
+ # update the architecture
+ arch_optimizer.zero_grad()
+ logits, expected_flop = network(arch_inputs)
+ flop_cur = network.module.get_flop("genotype", None, None)
+ flop_loss, flop_loss_scale = get_flop_loss(
+ expected_flop, flop_cur, flop_need, flop_tolerant
+ )
+ acls_loss = criterion(logits, arch_targets)
+ arch_loss = acls_loss + flop_loss * flop_weight
+ arch_loss.backward()
+ arch_optimizer.step()
+
+ # record
+ arch_losses.update(arch_loss.item(), arch_inputs.size(0))
+ arch_flop_losses.update(flop_loss_scale, arch_inputs.size(0))
+ arch_cls_losses.update(acls_loss.item(), arch_inputs.size(0))
+
+ # measure elapsed time
+ batch_time.update(time.time() - end)
+ end = time.time()
+ if step % print_freq == 0 or (step + 1) == len(search_loader):
+ Sstr = (
+ "**TRAIN** "
+ + time_string()
+ + " [{:}][{:03d}/{:03d}]".format(epoch_str, step, len(search_loader))
+ )
+ Tstr = "Time {batch_time.val:.2f} ({batch_time.avg:.2f}) Data {data_time.val:.2f} ({data_time.avg:.2f})".format(
+ batch_time=batch_time, data_time=data_time
+ )
+ Lstr = "Base-Loss {loss.val:.3f} ({loss.avg:.3f}) Prec@1 {top1.val:.2f} ({top1.avg:.2f}) Prec@5 {top5.val:.2f} ({top5.avg:.2f})".format(
+ loss=base_losses, top1=top1, top5=top5
+ )
+ Vstr = "Acls-loss {aloss.val:.3f} ({aloss.avg:.3f}) FLOP-Loss {floss.val:.3f} ({floss.avg:.3f}) Arch-Loss {loss.val:.3f} ({loss.avg:.3f})".format(
+ aloss=arch_cls_losses, floss=arch_flop_losses, loss=arch_losses
+ )
+ logger.log(Sstr + " " + Tstr + " " + Lstr + " " + Vstr)
+ # Istr = 'Bsz={:} Asz={:}'.format(list(base_inputs.size()), list(arch_inputs.size()))
+ # logger.log(Sstr + ' ' + Tstr + ' ' + Lstr + ' ' + Vstr + ' ' + Istr)
+ # print(network.module.get_arch_info())
+ # print(network.module.width_attentions[0])
+ # print(network.module.width_attentions[1])
+
+ logger.log(
+ " **TRAIN** Prec@1 {top1.avg:.2f} Prec@5 {top5.avg:.2f} Error@1 {error1:.2f} Error@5 {error5:.2f} Base-Loss:{baseloss:.3f}, Arch-Loss={archloss:.3f}".format(
+ top1=top1,
+ top5=top5,
+ error1=100 - top1.avg,
+ error5=100 - top5.avg,
+ baseloss=base_losses.avg,
+ archloss=arch_losses.avg,
+ )
+ )
+ return base_losses.avg, arch_losses.avg, top1.avg, top5.avg
+
+
+def search_valid(xloader, network, criterion, extra_info, print_freq, logger):
+ data_time, batch_time, losses, top1, top5 = (
+ AverageMeter(),
+ AverageMeter(),
+ AverageMeter(),
+ AverageMeter(),
+ AverageMeter(),
+ )
+
+ network.eval()
+ network.apply(change_key("search_mode", "search"))
+ end = time.time()
+ # logger.log('Starting evaluating {:}'.format(epoch_info))
+ with torch.no_grad():
+ for i, (inputs, targets) in enumerate(xloader):
+ # measure data loading time
+ data_time.update(time.time() - end)
+ # calculate prediction and loss
+ targets = targets.cuda(non_blocking=True)
+
+ logits, expected_flop = network(inputs)
+ loss = criterion(logits, targets)
+ # record
+ prec1, prec5 = obtain_accuracy(logits.data, targets.data, topk=(1, 5))
+ losses.update(loss.item(), inputs.size(0))
+ top1.update(prec1.item(), inputs.size(0))
+ top5.update(prec5.item(), inputs.size(0))
+
+ # measure elapsed time
+ batch_time.update(time.time() - end)
+ end = time.time()
+
+ if i % print_freq == 0 or (i + 1) == len(xloader):
+ Sstr = (
+ "**VALID** "
+ + time_string()
+ + " [{:}][{:03d}/{:03d}]".format(extra_info, i, len(xloader))
+ )
+ Tstr = "Time {batch_time.val:.2f} ({batch_time.avg:.2f}) Data {data_time.val:.2f} ({data_time.avg:.2f})".format(
+ batch_time=batch_time, data_time=data_time
+ )
+ Lstr = "Loss {loss.val:.3f} ({loss.avg:.3f}) Prec@1 {top1.val:.2f} ({top1.avg:.2f}) Prec@5 {top5.val:.2f} ({top5.avg:.2f})".format(
+ loss=losses, top1=top1, top5=top5
+ )
+ Istr = "Size={:}".format(list(inputs.size()))
+ logger.log(Sstr + " " + Tstr + " " + Lstr + " " + Istr)
+
+ logger.log(
+ " **VALID** Prec@1 {top1.avg:.2f} Prec@5 {top5.avg:.2f} Error@1 {error1:.2f} Error@5 {error5:.2f} Loss:{loss:.3f}".format(
+ top1=top1,
+ top5=top5,
+ error1=100 - top1.avg,
+ error5=100 - top5.avg,
+ loss=losses.avg,
+ )
+ )
+
+ return losses.avg, top1.avg, top5.avg
diff --git a/AutoDL-Projects/xautodl/procedures/search_main_v2.py b/AutoDL-Projects/xautodl/procedures/search_main_v2.py
new file mode 100644
index 0000000..14ab16c
--- /dev/null
+++ b/AutoDL-Projects/xautodl/procedures/search_main_v2.py
@@ -0,0 +1,139 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019 #
+##################################################
+import os, sys, time, torch
+
+# modules in AutoDL
+from xautodl.log_utils import AverageMeter, time_string
+from xautodl.models import change_key
+from .eval_funcs import obtain_accuracy
+
+
+def get_flop_loss(expected_flop, flop_cur, flop_need, flop_tolerant):
+ expected_flop = torch.mean(expected_flop)
+
+ if flop_cur < flop_need - flop_tolerant: # Too Small FLOP
+ loss = -torch.log(expected_flop)
+ # elif flop_cur > flop_need + flop_tolerant: # Too Large FLOP
+ elif flop_cur > flop_need: # Too Large FLOP
+ loss = torch.log(expected_flop)
+ else: # Required FLOP
+ loss = None
+ if loss is None:
+ return 0, 0
+ else:
+ return loss, loss.item()
+
+
+def search_train_v2(
+ search_loader,
+ network,
+ criterion,
+ scheduler,
+ base_optimizer,
+ arch_optimizer,
+ optim_config,
+ extra_info,
+ print_freq,
+ logger,
+):
+ data_time, batch_time = AverageMeter(), AverageMeter()
+ base_losses, arch_losses, top1, top5 = (
+ AverageMeter(),
+ AverageMeter(),
+ AverageMeter(),
+ AverageMeter(),
+ )
+ arch_cls_losses, arch_flop_losses = AverageMeter(), AverageMeter()
+ epoch_str, flop_need, flop_weight, flop_tolerant = (
+ extra_info["epoch-str"],
+ extra_info["FLOP-exp"],
+ extra_info["FLOP-weight"],
+ extra_info["FLOP-tolerant"],
+ )
+
+ network.train()
+ logger.log(
+ "[Search] : {:}, FLOP-Require={:.2f} MB, FLOP-WEIGHT={:.2f}".format(
+ epoch_str, flop_need, flop_weight
+ )
+ )
+ end = time.time()
+ network.apply(change_key("search_mode", "search"))
+ for step, (base_inputs, base_targets, arch_inputs, arch_targets) in enumerate(
+ search_loader
+ ):
+ scheduler.update(None, 1.0 * step / len(search_loader))
+ # calculate prediction and loss
+ base_targets = base_targets.cuda(non_blocking=True)
+ arch_targets = arch_targets.cuda(non_blocking=True)
+ # measure data loading time
+ data_time.update(time.time() - end)
+
+ # update the weights
+ base_optimizer.zero_grad()
+ logits, expected_flop = network(base_inputs)
+ base_loss = criterion(logits, base_targets)
+ base_loss.backward()
+ base_optimizer.step()
+ # record
+ prec1, prec5 = obtain_accuracy(logits.data, base_targets.data, topk=(1, 5))
+ base_losses.update(base_loss.item(), base_inputs.size(0))
+ top1.update(prec1.item(), base_inputs.size(0))
+ top5.update(prec5.item(), base_inputs.size(0))
+
+ # update the architecture
+ arch_optimizer.zero_grad()
+ logits, expected_flop = network(arch_inputs)
+ flop_cur = network.module.get_flop("genotype", None, None)
+ flop_loss, flop_loss_scale = get_flop_loss(
+ expected_flop, flop_cur, flop_need, flop_tolerant
+ )
+ acls_loss = criterion(logits, arch_targets)
+ arch_loss = acls_loss + flop_loss * flop_weight
+ arch_loss.backward()
+ arch_optimizer.step()
+
+ # record
+ arch_losses.update(arch_loss.item(), arch_inputs.size(0))
+ arch_flop_losses.update(flop_loss_scale, arch_inputs.size(0))
+ arch_cls_losses.update(acls_loss.item(), arch_inputs.size(0))
+
+ # measure elapsed time
+ batch_time.update(time.time() - end)
+ end = time.time()
+ if step % print_freq == 0 or (step + 1) == len(search_loader):
+ Sstr = (
+ "**TRAIN** "
+ + time_string()
+ + " [{:}][{:03d}/{:03d}]".format(epoch_str, step, len(search_loader))
+ )
+ Tstr = "Time {batch_time.val:.2f} ({batch_time.avg:.2f}) Data {data_time.val:.2f} ({data_time.avg:.2f})".format(
+ batch_time=batch_time, data_time=data_time
+ )
+ Lstr = "Base-Loss {loss.val:.3f} ({loss.avg:.3f}) Prec@1 {top1.val:.2f} ({top1.avg:.2f}) Prec@5 {top5.val:.2f} ({top5.avg:.2f})".format(
+ loss=base_losses, top1=top1, top5=top5
+ )
+ Vstr = "Acls-loss {aloss.val:.3f} ({aloss.avg:.3f}) FLOP-Loss {floss.val:.3f} ({floss.avg:.3f}) Arch-Loss {loss.val:.3f} ({loss.avg:.3f})".format(
+ aloss=arch_cls_losses, floss=arch_flop_losses, loss=arch_losses
+ )
+ logger.log(Sstr + " " + Tstr + " " + Lstr + " " + Vstr)
+ # num_bytes = torch.cuda.max_memory_allocated( next(network.parameters()).device ) * 1.0
+ # logger.log(Sstr + ' ' + Tstr + ' ' + Lstr + ' ' + Vstr + ' GPU={:.2f}MB'.format(num_bytes/1e6))
+ # Istr = 'Bsz={:} Asz={:}'.format(list(base_inputs.size()), list(arch_inputs.size()))
+ # logger.log(Sstr + ' ' + Tstr + ' ' + Lstr + ' ' + Vstr + ' ' + Istr)
+ # print(network.module.get_arch_info())
+ # print(network.module.width_attentions[0])
+ # print(network.module.width_attentions[1])
+
+ logger.log(
+ " **TRAIN** Prec@1 {top1.avg:.2f} Prec@5 {top5.avg:.2f} Error@1 {error1:.2f} Error@5 {error5:.2f} Base-Loss:{baseloss:.3f}, Arch-Loss={archloss:.3f}".format(
+ top1=top1,
+ top5=top5,
+ error1=100 - top1.avg,
+ error5=100 - top5.avg,
+ baseloss=base_losses.avg,
+ archloss=arch_losses.avg,
+ )
+ )
+ return base_losses.avg, arch_losses.avg, top1.avg, top5.avg
diff --git a/AutoDL-Projects/xautodl/procedures/simple_KD_main.py b/AutoDL-Projects/xautodl/procedures/simple_KD_main.py
new file mode 100644
index 0000000..0d31431
--- /dev/null
+++ b/AutoDL-Projects/xautodl/procedures/simple_KD_main.py
@@ -0,0 +1,204 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.01 #
+#####################################################
+import os, sys, time, torch
+import torch.nn.functional as F
+
+# modules in AutoDL
+from xautodl.log_utils import AverageMeter, time_string
+from .eval_funcs import obtain_accuracy
+
+
+def simple_KD_train(
+ xloader,
+ teacher,
+ network,
+ criterion,
+ scheduler,
+ optimizer,
+ optim_config,
+ extra_info,
+ print_freq,
+ logger,
+):
+ loss, acc1, acc5 = procedure(
+ xloader,
+ teacher,
+ network,
+ criterion,
+ scheduler,
+ optimizer,
+ "train",
+ optim_config,
+ extra_info,
+ print_freq,
+ logger,
+ )
+ return loss, acc1, acc5
+
+
+def simple_KD_valid(
+ xloader, teacher, network, criterion, optim_config, extra_info, print_freq, logger
+):
+ with torch.no_grad():
+ loss, acc1, acc5 = procedure(
+ xloader,
+ teacher,
+ network,
+ criterion,
+ None,
+ None,
+ "valid",
+ optim_config,
+ extra_info,
+ print_freq,
+ logger,
+ )
+ return loss, acc1, acc5
+
+
+def loss_KD_fn(
+ criterion,
+ student_logits,
+ teacher_logits,
+ studentFeatures,
+ teacherFeatures,
+ targets,
+ alpha,
+ temperature,
+):
+ basic_loss = criterion(student_logits, targets) * (1.0 - alpha)
+ log_student = F.log_softmax(student_logits / temperature, dim=1)
+ sof_teacher = F.softmax(teacher_logits / temperature, dim=1)
+ KD_loss = F.kl_div(log_student, sof_teacher, reduction="batchmean") * (
+ alpha * temperature * temperature
+ )
+ return basic_loss + KD_loss
+
+
+def procedure(
+ xloader,
+ teacher,
+ network,
+ criterion,
+ scheduler,
+ optimizer,
+ mode,
+ config,
+ extra_info,
+ print_freq,
+ logger,
+):
+ data_time, batch_time, losses, top1, top5 = (
+ AverageMeter(),
+ AverageMeter(),
+ AverageMeter(),
+ AverageMeter(),
+ AverageMeter(),
+ )
+ Ttop1, Ttop5 = AverageMeter(), AverageMeter()
+ if mode == "train":
+ network.train()
+ elif mode == "valid":
+ network.eval()
+ else:
+ raise ValueError("The mode is not right : {:}".format(mode))
+ teacher.eval()
+
+ logger.log(
+ "[{:5s}] config :: auxiliary={:}, KD :: [alpha={:.2f}, temperature={:.2f}]".format(
+ mode,
+ config.auxiliary if hasattr(config, "auxiliary") else -1,
+ config.KD_alpha,
+ config.KD_temperature,
+ )
+ )
+ end = time.time()
+ for i, (inputs, targets) in enumerate(xloader):
+ if mode == "train":
+ scheduler.update(None, 1.0 * i / len(xloader))
+ # measure data loading time
+ data_time.update(time.time() - end)
+ # calculate prediction and loss
+ targets = targets.cuda(non_blocking=True)
+
+ if mode == "train":
+ optimizer.zero_grad()
+
+ student_f, logits = network(inputs)
+ if isinstance(logits, list):
+ assert len(logits) == 2, "logits must has {:} items instead of {:}".format(
+ 2, len(logits)
+ )
+ logits, logits_aux = logits
+ else:
+ logits, logits_aux = logits, None
+ with torch.no_grad():
+ teacher_f, teacher_logits = teacher(inputs)
+
+ loss = loss_KD_fn(
+ criterion,
+ logits,
+ teacher_logits,
+ student_f,
+ teacher_f,
+ targets,
+ config.KD_alpha,
+ config.KD_temperature,
+ )
+ if config is not None and hasattr(config, "auxiliary") and config.auxiliary > 0:
+ loss_aux = criterion(logits_aux, targets)
+ loss += config.auxiliary * loss_aux
+
+ if mode == "train":
+ loss.backward()
+ optimizer.step()
+
+ # record
+ sprec1, sprec5 = obtain_accuracy(logits.data, targets.data, topk=(1, 5))
+ losses.update(loss.item(), inputs.size(0))
+ top1.update(sprec1.item(), inputs.size(0))
+ top5.update(sprec5.item(), inputs.size(0))
+ # teacher
+ tprec1, tprec5 = obtain_accuracy(teacher_logits.data, targets.data, topk=(1, 5))
+ Ttop1.update(tprec1.item(), inputs.size(0))
+ Ttop5.update(tprec5.item(), inputs.size(0))
+
+ # measure elapsed time
+ batch_time.update(time.time() - end)
+ end = time.time()
+
+ if i % print_freq == 0 or (i + 1) == len(xloader):
+ Sstr = (
+ " {:5s} ".format(mode.upper())
+ + time_string()
+ + " [{:}][{:03d}/{:03d}]".format(extra_info, i, len(xloader))
+ )
+ if scheduler is not None:
+ Sstr += " {:}".format(scheduler.get_min_info())
+ Tstr = "Time {batch_time.val:.2f} ({batch_time.avg:.2f}) Data {data_time.val:.2f} ({data_time.avg:.2f})".format(
+ batch_time=batch_time, data_time=data_time
+ )
+ Lstr = "Loss {loss.val:.3f} ({loss.avg:.3f}) Prec@1 {top1.val:.2f} ({top1.avg:.2f}) Prec@5 {top5.val:.2f} ({top5.avg:.2f})".format(
+ loss=losses, top1=top1, top5=top5
+ )
+ Lstr += " Teacher : acc@1={:.2f}, acc@5={:.2f}".format(Ttop1.avg, Ttop5.avg)
+ Istr = "Size={:}".format(list(inputs.size()))
+ logger.log(Sstr + " " + Tstr + " " + Lstr + " " + Istr)
+
+ logger.log(
+ " **{:5s}** accuracy drop :: @1={:.2f}, @5={:.2f}".format(
+ mode.upper(), Ttop1.avg - top1.avg, Ttop5.avg - top5.avg
+ )
+ )
+ logger.log(
+ " **{mode:5s}** Prec@1 {top1.avg:.2f} Prec@5 {top5.avg:.2f} Error@1 {error1:.2f} Error@5 {error5:.2f} Loss:{loss:.3f}".format(
+ mode=mode.upper(),
+ top1=top1,
+ top5=top5,
+ error1=100 - top1.avg,
+ error5=100 - top5.avg,
+ loss=losses.avg,
+ )
+ )
+ return losses.avg, top1.avg, top5.avg
diff --git a/AutoDL-Projects/xautodl/procedures/starts.py b/AutoDL-Projects/xautodl/procedures/starts.py
new file mode 100644
index 0000000..b315521
--- /dev/null
+++ b/AutoDL-Projects/xautodl/procedures/starts.py
@@ -0,0 +1,79 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019 #
+##################################################
+import os, sys, torch, random, PIL, copy, numpy as np
+from os import path as osp
+from shutil import copyfile
+
+
+def prepare_seed(rand_seed):
+ random.seed(rand_seed)
+ np.random.seed(rand_seed)
+ torch.manual_seed(rand_seed)
+ torch.cuda.manual_seed(rand_seed)
+ torch.cuda.manual_seed_all(rand_seed)
+
+
+def prepare_logger(xargs):
+ args = copy.deepcopy(xargs)
+ from xautodl.log_utils import Logger
+
+ logger = Logger(args.save_dir, args.rand_seed)
+ logger.log("Main Function with logger : {:}".format(logger))
+ logger.log("Arguments : -------------------------------")
+ for name, value in args._get_kwargs():
+ logger.log("{:16} : {:}".format(name, value))
+ logger.log("Python Version : {:}".format(sys.version.replace("\n", " ")))
+ logger.log("Pillow Version : {:}".format(PIL.__version__))
+ logger.log("PyTorch Version : {:}".format(torch.__version__))
+ logger.log("cuDNN Version : {:}".format(torch.backends.cudnn.version()))
+ logger.log("CUDA available : {:}".format(torch.cuda.is_available()))
+ logger.log("CUDA GPU numbers : {:}".format(torch.cuda.device_count()))
+ logger.log(
+ "CUDA_VISIBLE_DEVICES : {:}".format(
+ os.environ["CUDA_VISIBLE_DEVICES"]
+ if "CUDA_VISIBLE_DEVICES" in os.environ
+ else "None"
+ )
+ )
+ return logger
+
+
+def get_machine_info():
+ info = "Python Version : {:}".format(sys.version.replace("\n", " "))
+ info += "\nPillow Version : {:}".format(PIL.__version__)
+ info += "\nPyTorch Version : {:}".format(torch.__version__)
+ info += "\ncuDNN Version : {:}".format(torch.backends.cudnn.version())
+ info += "\nCUDA available : {:}".format(torch.cuda.is_available())
+ info += "\nCUDA GPU numbers : {:}".format(torch.cuda.device_count())
+ if "CUDA_VISIBLE_DEVICES" in os.environ:
+ info += "\nCUDA_VISIBLE_DEVICES={:}".format(os.environ["CUDA_VISIBLE_DEVICES"])
+ else:
+ info += "\nDoes not set CUDA_VISIBLE_DEVICES"
+ return info
+
+
+def save_checkpoint(state, filename, logger):
+ if osp.isfile(filename):
+ if hasattr(logger, "log"):
+ logger.log(
+ "Find {:} exist, delete is at first before saving".format(filename)
+ )
+ os.remove(filename)
+ torch.save(state, filename)
+ assert osp.isfile(
+ filename
+ ), "save filename : {:} failed, which is not found.".format(filename)
+ if hasattr(logger, "log"):
+ logger.log("save checkpoint into {:}".format(filename))
+ return filename
+
+
+def copy_checkpoint(src, dst, logger):
+ if osp.isfile(dst):
+ if hasattr(logger, "log"):
+ logger.log("Find {:} exist, delete is at first before saving".format(dst))
+ os.remove(dst)
+ copyfile(src, dst)
+ if hasattr(logger, "log"):
+ logger.log("copy the file from {:} into {:}".format(src, dst))
diff --git a/AutoDL-Projects/xautodl/spaces/__init__.py b/AutoDL-Projects/xautodl/spaces/__init__.py
new file mode 100644
index 0000000..d777d0c
--- /dev/null
+++ b/AutoDL-Projects/xautodl/spaces/__init__.py
@@ -0,0 +1,17 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.01 #
+#####################################################
+# Define complex searc space for AutoDL #
+#####################################################
+
+from .basic_space import Categorical
+from .basic_space import Continuous
+from .basic_space import Integer
+from .basic_space import Space
+from .basic_space import VirtualNode
+from .basic_op import has_categorical
+from .basic_op import has_continuous
+from .basic_op import is_determined
+from .basic_op import get_determined_value
+from .basic_op import get_min
+from .basic_op import get_max
diff --git a/AutoDL-Projects/xautodl/spaces/basic_op.py b/AutoDL-Projects/xautodl/spaces/basic_op.py
new file mode 100644
index 0000000..a757b81
--- /dev/null
+++ b/AutoDL-Projects/xautodl/spaces/basic_op.py
@@ -0,0 +1,74 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.03 #
+#####################################################
+from .basic_space import Space
+from .basic_space import VirtualNode
+from .basic_space import Integer
+from .basic_space import Continuous
+from .basic_space import Categorical
+from .basic_space import _EPS
+
+
+def has_categorical(space_or_value, x):
+ if isinstance(space_or_value, Space):
+ return space_or_value.has(x)
+ else:
+ return space_or_value == x
+
+
+def has_continuous(space_or_value, x):
+ if isinstance(space_or_value, Space):
+ return space_or_value.has(x)
+ else:
+ return abs(space_or_value - x) <= _EPS
+
+
+def is_determined(space_or_value):
+ if isinstance(space_or_value, Space):
+ return space_or_value.determined
+ else:
+ return True
+
+
+def get_determined_value(space_or_value):
+ if not is_determined(space_or_value):
+ raise ValueError("This input is not determined: {:}".format(space_or_value))
+ if isinstance(space_or_value, Space):
+ if isinstance(space_or_value, Continuous):
+ return space_or_value.lower
+ elif isinstance(space_or_value, Categorical):
+ return get_determined_value(space_or_value[0])
+ else: # VirtualNode
+ return space_or_value.value
+ else:
+ return space_or_value
+
+
+def get_max(space_or_value):
+ if isinstance(space_or_value, Integer):
+ return max(space_or_value.candidates)
+ elif isinstance(space_or_value, Continuous):
+ return space_or_value.upper
+ elif isinstance(space_or_value, Categorical):
+ values = []
+ for index in range(len(space_or_value)):
+ max_value = get_max(space_or_value[index])
+ values.append(max_value)
+ return max(values)
+ else:
+ return space_or_value
+
+
+def get_min(space_or_value):
+ if isinstance(space_or_value, Integer):
+ return min(space_or_value.candidates)
+ elif isinstance(space_or_value, Continuous):
+ return space_or_value.lower
+ elif isinstance(space_or_value, Categorical):
+ values = []
+ for index in range(len(space_or_value)):
+ min_value = get_min(space_or_value[index])
+ values.append(min_value)
+ return min(values)
+ else:
+ return space_or_value
diff --git a/AutoDL-Projects/xautodl/spaces/basic_space.py b/AutoDL-Projects/xautodl/spaces/basic_space.py
new file mode 100644
index 0000000..6e79dc8
--- /dev/null
+++ b/AutoDL-Projects/xautodl/spaces/basic_space.py
@@ -0,0 +1,434 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.03 #
+#####################################################
+
+import abc
+import math
+import copy
+import random
+import numpy as np
+from collections import OrderedDict
+
+from typing import Optional, Text
+
+
+__all__ = ["_EPS", "Space", "Categorical", "Integer", "Continuous"]
+
+_EPS = 1e-9
+
+
+class Space(metaclass=abc.ABCMeta):
+ """Basic search space describing the set of possible candidate values for hyperparameter.
+ All search space must inherit from this basic class.
+ """
+
+ def __init__(self):
+ # used to avoid duplicate sample
+ self._last_sample = None
+ self._last_abstract = None
+
+ @abc.abstractproperty
+ def xrepr(self, depth=0) -> Text:
+ raise NotImplementedError
+
+ def __repr__(self) -> Text:
+ return self.xrepr()
+
+ @abc.abstractproperty
+ def abstract(self, reuse_last=False) -> "Space":
+ raise NotImplementedError
+
+ @abc.abstractmethod
+ def random(self, recursion=True, reuse_last=False):
+ raise NotImplementedError
+
+ @abc.abstractmethod
+ def clean_last_sample(self):
+ raise NotImplementedError
+
+ @abc.abstractmethod
+ def clean_last_abstract(self):
+ raise NotImplementedError
+
+ def clean_last(self):
+ self.clean_last_sample()
+ self.clean_last_abstract()
+
+ @abc.abstractproperty
+ def determined(self) -> bool:
+ raise NotImplementedError
+
+ @abc.abstractmethod
+ def has(self, x) -> bool:
+ """Check whether x is in this search space."""
+ assert not isinstance(
+ x, Space
+ ), "The input value itself can not be a search space."
+
+ @abc.abstractmethod
+ def __eq__(self, other):
+ raise NotImplementedError
+
+ def copy(self) -> "Space":
+ return copy.deepcopy(self)
+
+
+class VirtualNode(Space):
+ """For a nested search space, we represent it as a tree structure.
+
+ For example,
+ """
+
+ def __init__(self, id=None, value=None):
+ super(VirtualNode, self).__init__()
+ self._id = id
+ self._value = value
+ self._attributes = OrderedDict()
+
+ @property
+ def value(self):
+ return self._value
+
+ def append(self, key, value):
+ if not isinstance(key, str):
+ raise TypeError(
+ "Only accept string as a key instead of {:}".format(type(key))
+ )
+ if not isinstance(value, Space):
+ raise ValueError("Invalid type of value: {:}".format(type(value)))
+ # if value.determined:
+ # raise ValueError("Can not attach a determined value: {:}".format(value))
+ self._attributes[key] = value
+
+ def xrepr(self, depth=0) -> Text:
+ strs = [self.__class__.__name__ + "(value={:}".format(self._value)]
+ for key, value in self._attributes.items():
+ strs.append(key + " = " + value.xrepr(depth + 1))
+ strs.append(")")
+ if len(strs) == 2:
+ return "".join(strs)
+ else:
+ space = " "
+ xstrs = (
+ [strs[0]]
+ + [space * (depth + 1) + x for x in strs[1:-1]]
+ + [space * depth + strs[-1]]
+ )
+ return ",\n".join(xstrs)
+
+ def abstract(self, reuse_last=False) -> Space:
+ if reuse_last and self._last_abstract is not None:
+ return self._last_abstract
+ node = VirtualNode(id(self))
+ for key, value in self._attributes.items():
+ if not value.determined:
+ node.append(value.abstract(reuse_last))
+ self._last_abstract = node
+ return self._last_abstract
+
+ def random(self, recursion=True, reuse_last=False):
+ if reuse_last and self._last_sample is not None:
+ return self._last_sample
+ node = VirtualNode(None, self._value)
+ for key, value in self._attributes.items():
+ node.append(key, value.random(recursion, reuse_last))
+ self._last_sample = node # record the last sample
+ return node
+
+ def clean_last_sample(self):
+ self._last_sample = None
+ for key, value in self._attributes.items():
+ value.clean_last_sample()
+
+ def clean_last_abstract(self):
+ self._last_abstract = None
+ for key, value in self._attributes.items():
+ value.clean_last_abstract()
+
+ def has(self, x) -> bool:
+ for key, value in self._attributes.items():
+ if value.has(x):
+ return True
+ return False
+
+ def __contains__(self, key):
+ return key in self._attributes
+
+ def __getitem__(self, key):
+ return self._attributes[key]
+
+ @property
+ def determined(self) -> bool:
+ for key, value in self._attributes.items():
+ if not value.determined:
+ return False
+ return True
+
+ def __eq__(self, other):
+ if not isinstance(other, VirtualNode):
+ return False
+ for key, value in self._attributes.items():
+ if not key in other:
+ return False
+ if value != other[key]:
+ return False
+ return True
+
+
+class Categorical(Space):
+ """A space contains the categorical values.
+ It can be a nested space, which means that the candidate in this space can also be a search space.
+ """
+
+ def __init__(self, *data, default: Optional[int] = None):
+ super(Categorical, self).__init__()
+ self._candidates = [*data]
+ self._default = default
+ assert self._default is None or 0 <= self._default < len(
+ self._candidates
+ ), "default >= {:}".format(len(self._candidates))
+ assert len(self) > 0, "Please provide at least one candidate"
+
+ @property
+ def candidates(self):
+ return self._candidates
+
+ @property
+ def default(self):
+ return self._default
+
+ @property
+ def determined(self):
+ if len(self) == 1:
+ return (
+ not isinstance(self._candidates[0], Space)
+ or self._candidates[0].determined
+ )
+ else:
+ return False
+
+ def __getitem__(self, index):
+ return self._candidates[index]
+
+ def __len__(self):
+ return len(self._candidates)
+
+ def clean_last_sample(self):
+ self._last_sample = None
+ for candidate in self._candidates:
+ if isinstance(candidate, Space):
+ candidate.clean_last_sample()
+
+ def clean_last_abstract(self):
+ self._last_abstract = None
+ for candidate in self._candidates:
+ if isinstance(candidate, Space):
+ candidate.clean_last_abstract()
+
+ def abstract(self, reuse_last=False) -> Space:
+ if reuse_last and self._last_abstract is not None:
+ return self._last_abstract
+ if self.determined:
+ result = VirtualNode(id(self), self)
+ else:
+ # [TO-IMPROVE]
+ data = []
+ for candidate in self.candidates:
+ if isinstance(candidate, Space):
+ data.append(candidate.abstract())
+ else:
+ data.append(VirtualNode(id(candidate), candidate))
+ result = Categorical(*data, default=self._default)
+ self._last_abstract = result
+ return self._last_abstract
+
+ def random(self, recursion=True, reuse_last=False):
+ if reuse_last and self._last_sample is not None:
+ return self._last_sample
+ sample = random.choice(self._candidates)
+ if recursion and isinstance(sample, Space):
+ sample = sample.random(recursion, reuse_last)
+ if isinstance(sample, VirtualNode):
+ sample = sample.copy()
+ else:
+ sample = VirtualNode(None, sample)
+ self._last_sample = sample
+ return self._last_sample
+
+ def xrepr(self, depth=0):
+ del depth
+ xrepr = "{name:}(candidates={cs:}, default_index={default:})".format(
+ name=self.__class__.__name__, cs=self._candidates, default=self._default
+ )
+ return xrepr
+
+ def has(self, x):
+ super().has(x)
+ for candidate in self._candidates:
+ if isinstance(candidate, Space) and candidate.has(x):
+ return True
+ elif candidate == x:
+ return True
+ return False
+
+ def __eq__(self, other):
+ if not isinstance(other, Categorical):
+ return False
+ if len(self) != len(other):
+ return False
+ if self.default != other.default:
+ return False
+ for index in range(len(self)):
+ if self.__getitem__(index) != other[index]:
+ return False
+ return True
+
+
+class Integer(Categorical):
+ """A space contains the integer values."""
+
+ def __init__(self, lower: int, upper: int, default: Optional[int] = None):
+ if not isinstance(lower, int) or not isinstance(upper, int):
+ raise ValueError(
+ "The lower [{:}] and uppwer [{:}] must be int.".format(lower, upper)
+ )
+ data = list(range(lower, upper + 1))
+ self._raw_lower = lower
+ self._raw_upper = upper
+ self._raw_default = default
+ if default is not None and (default < lower or default > upper):
+ raise ValueError("The default value [{:}] is out of range.".format(default))
+ default = data.index(default)
+ super(Integer, self).__init__(*data, default=default)
+
+ def xrepr(self, depth=0):
+ del depth
+ xrepr = "{name:}(lower={lower:}, upper={upper:}, default={default:})".format(
+ name=self.__class__.__name__,
+ lower=self._raw_lower,
+ upper=self._raw_upper,
+ default=self._raw_default,
+ )
+ return xrepr
+
+
+np_float_types = (np.float16, np.float32, np.float64)
+np_int_types = (
+ np.uint8,
+ np.int8,
+ np.uint16,
+ np.int16,
+ np.uint32,
+ np.int32,
+ np.uint64,
+ np.int64,
+)
+
+
+class Continuous(Space):
+ """A space contains the continuous values."""
+
+ def __init__(
+ self,
+ lower: float,
+ upper: float,
+ default: Optional[float] = None,
+ log: bool = False,
+ eps: float = _EPS,
+ ):
+ super(Continuous, self).__init__()
+ self._lower = lower
+ self._upper = upper
+ self._default = default
+ self._log_scale = log
+ self._eps = eps
+
+ @property
+ def lower(self):
+ return self._lower
+
+ @property
+ def upper(self):
+ return self._upper
+
+ @property
+ def default(self):
+ return self._default
+
+ @property
+ def use_log(self):
+ return self._log_scale
+
+ @property
+ def eps(self):
+ return self._eps
+
+ def abstract(self, reuse_last=False) -> Space:
+ if reuse_last and self._last_abstract is not None:
+ return self._last_abstract
+ self._last_abstract = self.copy()
+ return self._last_abstract
+
+ def random(self, recursion=True, reuse_last=False):
+ del recursion
+ if reuse_last and self._last_sample is not None:
+ return self._last_sample
+ if self._log_scale:
+ sample = random.uniform(math.log(self._lower), math.log(self._upper))
+ sample = math.exp(sample)
+ else:
+ sample = random.uniform(self._lower, self._upper)
+ self._last_sample = VirtualNode(None, sample)
+ return self._last_sample
+
+ def xrepr(self, depth=0):
+ del depth
+ xrepr = "{name:}(lower={lower:}, upper={upper:}, default_value={default:}, log_scale={log:})".format(
+ name=self.__class__.__name__,
+ lower=self._lower,
+ upper=self._upper,
+ default=self._default,
+ log=self._log_scale,
+ )
+ return xrepr
+
+ def convert(self, x):
+ if isinstance(x, np_float_types) and x.size == 1:
+ return float(x), True
+ elif isinstance(x, np_int_types) and x.size == 1:
+ return float(x), True
+ elif isinstance(x, int):
+ return float(x), True
+ elif isinstance(x, float):
+ return float(x), True
+ else:
+ return None, False
+
+ def has(self, x):
+ super().has(x)
+ converted_x, success = self.convert(x)
+ return success and self.lower <= converted_x <= self.upper
+
+ @property
+ def determined(self):
+ return abs(self.lower - self.upper) <= self._eps
+
+ def clean_last_sample(self):
+ self._last_sample = None
+
+ def clean_last_abstract(self):
+ self._last_abstract = None
+
+ def __eq__(self, other):
+ if not isinstance(other, Continuous):
+ return False
+ if self is other:
+ return True
+ else:
+ return (
+ self.lower == other.lower
+ and self.upper == other.upper
+ and self.default == other.default
+ and self.use_log == other.use_log
+ and self.eps == other.eps
+ )
diff --git a/AutoDL-Projects/xautodl/trade_models/__init__.py b/AutoDL-Projects/xautodl/trade_models/__init__.py
new file mode 100644
index 0000000..0ee9460
--- /dev/null
+++ b/AutoDL-Projects/xautodl/trade_models/__init__.py
@@ -0,0 +1,4 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.03 #
+#####################################################
+from .transformers import get_transformer
diff --git a/AutoDL-Projects/xautodl/trade_models/naive_v1_model.py b/AutoDL-Projects/xautodl/trade_models/naive_v1_model.py
new file mode 100644
index 0000000..ca90c60
--- /dev/null
+++ b/AutoDL-Projects/xautodl/trade_models/naive_v1_model.py
@@ -0,0 +1,102 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021 #
+##################################################
+# Use noise as prediction #
+##################################################
+from __future__ import division
+from __future__ import print_function
+
+import random
+import numpy as np
+import pandas as pd
+
+from qlib.log import get_module_logger
+
+from qlib.model.base import Model
+from qlib.data.dataset import DatasetH
+from qlib.data.dataset.handler import DataHandlerLP
+
+
+class NAIVE_V1(Model):
+ """NAIVE Version 1 Quant Model"""
+
+ def __init__(self, d_feat=6, seed=None, **kwargs):
+ # Set logger.
+ self.logger = get_module_logger("NAIVE")
+ self.logger.info("NAIVE 1st version: random noise ...")
+
+ # set hyper-parameters.
+ self.d_feat = d_feat
+ self.seed = seed
+
+ self.logger.info(
+ "NAIVE-V1 parameters setting: d_feat={:}, seed={:}".format(
+ self.d_feat, self.seed
+ )
+ )
+
+ if self.seed is not None:
+ random.seed(self.seed)
+ np.random.seed(self.seed)
+ self._mean = None
+ self._std = None
+ self.fitted = False
+
+ def process_data(self, features):
+ features = features.reshape(len(features), self.d_feat, -1)
+ features = features.transpose((0, 2, 1))
+ return features[:, :59, 0]
+
+ def mse(self, preds, labels):
+ masks = ~np.isnan(labels)
+ masked_preds = preds[masks]
+ masked_labels = labels[masks]
+ return np.square(masked_preds - masked_labels).mean()
+
+ def model(self, x):
+ num = len(x)
+ return np.random.normal(loc=self._mean, scale=self._std, size=num).astype(
+ x.dtype
+ )
+
+ def fit(self, dataset: DatasetH):
+ def _prepare_dataset(df_data):
+ features = df_data["feature"].values
+ features = self.process_data(features)
+ labels = df_data["label"].values.squeeze()
+ return dict(features=features, labels=labels)
+
+ df_train, df_valid, df_test = dataset.prepare(
+ ["train", "valid", "test"],
+ col_set=["feature", "label"],
+ data_key=DataHandlerLP.DK_L,
+ )
+ train_dataset, valid_dataset, test_dataset = (
+ _prepare_dataset(df_train),
+ _prepare_dataset(df_valid),
+ _prepare_dataset(df_test),
+ )
+ # df_train['feature']['CLOSE1'].values
+ # train_dataset['features'][:, -1]
+ masks = ~np.isnan(train_dataset["labels"])
+ self._mean, self._std = np.mean(train_dataset["labels"][masks]), np.std(
+ train_dataset["labels"][masks]
+ )
+ train_mse_loss = self.mse(
+ self.model(train_dataset["features"]), train_dataset["labels"]
+ )
+ valid_mse_loss = self.mse(
+ self.model(valid_dataset["features"]), valid_dataset["labels"]
+ )
+ self.logger.info("Training MSE loss: {:}".format(train_mse_loss))
+ self.logger.info("Validation MSE loss: {:}".format(valid_mse_loss))
+ self.fitted = True
+
+ def predict(self, dataset):
+ if not self.fitted:
+ raise ValueError("The model is not fitted yet!")
+ x_test = dataset.prepare("test", col_set="feature")
+ index = x_test.index
+
+ preds = self.model(self.process_data(x_test.values))
+ return pd.Series(preds, index=index)
diff --git a/AutoDL-Projects/xautodl/trade_models/naive_v2_model.py b/AutoDL-Projects/xautodl/trade_models/naive_v2_model.py
new file mode 100644
index 0000000..79456c0
--- /dev/null
+++ b/AutoDL-Projects/xautodl/trade_models/naive_v2_model.py
@@ -0,0 +1,103 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021 #
+##################################################
+# A Simple Model that reused the prices of last day
+##################################################
+from __future__ import division
+from __future__ import print_function
+
+import random
+import numpy as np
+import pandas as pd
+
+from qlib.log import get_module_logger
+
+from qlib.model.base import Model
+from qlib.data.dataset import DatasetH
+from qlib.data.dataset.handler import DataHandlerLP
+
+
+class NAIVE_V2(Model):
+ """NAIVE Version 2 Quant Model"""
+
+ def __init__(self, d_feat=6, seed=None, **kwargs):
+ # Set logger.
+ self.logger = get_module_logger("NAIVE")
+ self.logger.info("NAIVE version...")
+
+ # set hyper-parameters.
+ self.d_feat = d_feat
+ self.seed = seed
+
+ self.logger.info(
+ "NAIVE parameters setting: d_feat={:}, seed={:}".format(
+ self.d_feat, self.seed
+ )
+ )
+
+ if self.seed is not None:
+ random.seed(self.seed)
+ np.random.seed(self.seed)
+
+ self.fitted = False
+
+ def process_data(self, features):
+ features = features.reshape(len(features), self.d_feat, -1)
+ features = features.transpose((0, 2, 1))
+ return features[:, :59, 0]
+
+ def mse(self, preds, labels):
+ masks = ~np.isnan(labels)
+ masked_preds = preds[masks]
+ masked_labels = labels[masks]
+ return np.square(masked_preds - masked_labels).mean()
+
+ def model(self, x):
+ x = 1 / x - 1
+ masks = ~np.isnan(x)
+ results = []
+ for rowd, rowm in zip(x, masks):
+ temp = rowd[rowm]
+ if rowm.any():
+ results.append(float(rowd[rowm][-1]))
+ else:
+ results.append(0)
+ return np.array(results, dtype=x.dtype)
+
+ def fit(self, dataset: DatasetH):
+ def _prepare_dataset(df_data):
+ features = df_data["feature"].values
+ features = self.process_data(features)
+ labels = df_data["label"].values.squeeze()
+ return dict(features=features, labels=labels)
+
+ df_train, df_valid, df_test = dataset.prepare(
+ ["train", "valid", "test"],
+ col_set=["feature", "label"],
+ data_key=DataHandlerLP.DK_L,
+ )
+ train_dataset, valid_dataset, test_dataset = (
+ _prepare_dataset(df_train),
+ _prepare_dataset(df_valid),
+ _prepare_dataset(df_test),
+ )
+ # df_train['feature']['CLOSE1'].values
+ # train_dataset['features'][:, -1]
+ train_mse_loss = self.mse(
+ self.model(train_dataset["features"]), train_dataset["labels"]
+ )
+ valid_mse_loss = self.mse(
+ self.model(valid_dataset["features"]), valid_dataset["labels"]
+ )
+ self.logger.info("Training MSE loss: {:}".format(train_mse_loss))
+ self.logger.info("Validation MSE loss: {:}".format(valid_mse_loss))
+ self.fitted = True
+
+ def predict(self, dataset):
+ if not self.fitted:
+ raise ValueError("The model is not fitted yet!")
+ x_test = dataset.prepare("test", col_set="feature")
+ index = x_test.index
+
+ preds = self.model(self.process_data(x_test.values))
+ return pd.Series(preds, index=index)
diff --git a/AutoDL-Projects/xautodl/trade_models/quant_transformer.py b/AutoDL-Projects/xautodl/trade_models/quant_transformer.py
new file mode 100644
index 0000000..d4e804a
--- /dev/null
+++ b/AutoDL-Projects/xautodl/trade_models/quant_transformer.py
@@ -0,0 +1,358 @@
+##################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021 #
+##################################################
+from __future__ import division
+from __future__ import print_function
+
+import os, math, random
+from collections import OrderedDict
+import numpy as np
+import pandas as pd
+from typing import Text, Union
+import copy
+from functools import partial
+from typing import Optional, Text
+
+from qlib.utils import get_or_create_path
+from qlib.log import get_module_logger
+
+import torch
+import torch.nn.functional as F
+import torch.optim as optim
+import torch.utils.data as th_data
+
+from xautodl.xmisc import AverageMeter
+from xautodl.xmisc import count_parameters
+
+from xautodl.xlayers import super_core
+from .transformers import DEFAULT_NET_CONFIG
+from .transformers import get_transformer
+
+
+from qlib.model.base import Model
+from qlib.data.dataset import DatasetH
+from qlib.data.dataset.handler import DataHandlerLP
+
+
+DEFAULT_OPT_CONFIG = dict(
+ epochs=200,
+ lr=0.001,
+ batch_size=2000,
+ early_stop=20,
+ loss="mse",
+ optimizer="adam",
+ num_workers=4,
+)
+
+
+def train_or_test_epoch(
+ xloader, model, loss_fn, metric_fn, is_train, optimizer, device
+):
+ if is_train:
+ model.train()
+ else:
+ model.eval()
+ score_meter, loss_meter = AverageMeter(), AverageMeter()
+ for ibatch, (feats, labels) in enumerate(xloader):
+ feats, labels = feats.to(device), labels.to(device)
+ # forward the network
+ preds = model(feats)
+ loss = loss_fn(preds, labels)
+ with torch.no_grad():
+ score = metric_fn(preds, labels)
+ loss_meter.update(loss.item(), feats.size(0))
+ score_meter.update(score.item(), feats.size(0))
+ # optimize the network
+ if is_train and optimizer is not None:
+ optimizer.zero_grad()
+ loss.backward()
+ torch.nn.utils.clip_grad_value_(model.parameters(), 3.0)
+ optimizer.step()
+ return loss_meter.avg, score_meter.avg
+
+
+class QuantTransformer(Model):
+ """Transformer-based Quant Model"""
+
+ def __init__(
+ self, net_config=None, opt_config=None, metric="", GPU=0, seed=None, **kwargs
+ ):
+ # Set logger.
+ self.logger = get_module_logger("QuantTransformer")
+ self.logger.info("QuantTransformer PyTorch version...")
+
+ # set hyper-parameters.
+ self.net_config = net_config or DEFAULT_NET_CONFIG
+ self.opt_config = opt_config or DEFAULT_OPT_CONFIG
+ self.metric = metric
+ self.device = torch.device(
+ "cuda:{:}".format(GPU) if torch.cuda.is_available() and GPU >= 0 else "cpu"
+ )
+ self.seed = seed
+
+ self.logger.info(
+ "Transformer parameters setting:"
+ "\nnet_config : {:}"
+ "\nopt_config : {:}"
+ "\nmetric : {:}"
+ "\ndevice : {:}"
+ "\nseed : {:}".format(
+ self.net_config,
+ self.opt_config,
+ self.metric,
+ self.device,
+ self.seed,
+ )
+ )
+
+ if self.seed is not None:
+ random.seed(self.seed)
+ np.random.seed(self.seed)
+ torch.manual_seed(self.seed)
+ if self.use_gpu:
+ torch.cuda.manual_seed(self.seed)
+ torch.cuda.manual_seed_all(self.seed)
+
+ self.model = get_transformer(self.net_config)
+ self.model.set_super_run_type(super_core.SuperRunMode.FullModel)
+ self.logger.info("model: {:}".format(self.model))
+ self.logger.info("model size: {:.3f} MB".format(count_parameters(self.model)))
+
+ if self.opt_config["optimizer"] == "adam":
+ self.train_optimizer = optim.Adam(
+ self.model.parameters(), lr=self.opt_config["lr"]
+ )
+ elif self.opt_config["optimizer"] == "adam":
+ self.train_optimizer = optim.SGD(
+ self.model.parameters(), lr=self.opt_config["lr"]
+ )
+ else:
+ raise NotImplementedError(
+ "optimizer {:} is not supported!".format(optimizer)
+ )
+
+ self.fitted = False
+ self.model.to(self.device)
+
+ @property
+ def use_gpu(self):
+ return self.device != torch.device("cpu")
+
+ def to(self, device):
+ if device is None:
+ device = "cpu"
+ self.device = device
+ self.model.to(self.device)
+ # move the optimizer
+ for param in self.train_optimizer.state.values():
+ # Not sure there are any global tensors in the state dict
+ if isinstance(param, torch.Tensor):
+ param.data = param.data.to(device)
+ if param._grad is not None:
+ param._grad.data = param._grad.data.to(device)
+ elif isinstance(param, dict):
+ for subparam in param.values():
+ if isinstance(subparam, torch.Tensor):
+ subparam.data = subparam.data.to(device)
+ if subparam._grad is not None:
+ subparam._grad.data = subparam._grad.data.to(device)
+
+ def loss_fn(self, pred, label):
+ mask = ~torch.isnan(label)
+ if self.opt_config["loss"] == "mse":
+ return F.mse_loss(pred[mask], label[mask])
+ else:
+ raise ValueError("unknown loss `{:}`".format(self.loss))
+
+ def metric_fn(self, pred, label):
+ # the metric score : higher is better
+ if self.metric == "" or self.metric == "loss":
+ return -self.loss_fn(pred, label)
+ else:
+ raise ValueError("unknown metric `{:}`".format(self.metric))
+
+ def fit(
+ self,
+ dataset: DatasetH,
+ save_dir: Optional[Text] = None,
+ ):
+ def _prepare_dataset(df_data):
+ return th_data.TensorDataset(
+ torch.from_numpy(df_data["feature"].values).float(),
+ torch.from_numpy(df_data["label"].values).squeeze().float(),
+ )
+
+ def _prepare_loader(dataset, shuffle):
+ return th_data.DataLoader(
+ dataset,
+ batch_size=self.opt_config["batch_size"],
+ drop_last=False,
+ pin_memory=True,
+ num_workers=self.opt_config["num_workers"],
+ shuffle=shuffle,
+ )
+
+ df_train, df_valid, df_test = dataset.prepare(
+ ["train", "valid", "test"],
+ col_set=["feature", "label"],
+ data_key=DataHandlerLP.DK_L,
+ )
+ train_dataset, valid_dataset, test_dataset = (
+ _prepare_dataset(df_train),
+ _prepare_dataset(df_valid),
+ _prepare_dataset(df_test),
+ )
+ train_loader, valid_loader, test_loader = (
+ _prepare_loader(train_dataset, True),
+ _prepare_loader(valid_dataset, False),
+ _prepare_loader(test_dataset, False),
+ )
+
+ save_dir = get_or_create_path(save_dir, return_dir=True)
+ self.logger.info(
+ "Fit procedure for [{:}] with save path={:}".format(
+ self.__class__.__name__, save_dir
+ )
+ )
+
+ def _internal_test(ckp_epoch=None, results_dict=None):
+ with torch.no_grad():
+ shared_kwards = {
+ "model": self.model,
+ "loss_fn": self.loss_fn,
+ "metric_fn": self.metric_fn,
+ "is_train": False,
+ "optimizer": None,
+ "device": self.device,
+ }
+ train_loss, train_score = train_or_test_epoch(
+ train_loader, **shared_kwards
+ )
+ valid_loss, valid_score = train_or_test_epoch(
+ valid_loader, **shared_kwards
+ )
+ test_loss, test_score = train_or_test_epoch(
+ test_loader, **shared_kwards
+ )
+ xstr = (
+ "train-score={:.6f}, valid-score={:.6f}, test-score={:.6f}".format(
+ train_score, valid_score, test_score
+ )
+ )
+ if ckp_epoch is not None and isinstance(results_dict, dict):
+ results_dict["train"][ckp_epoch] = train_score
+ results_dict["valid"][ckp_epoch] = valid_score
+ results_dict["test"][ckp_epoch] = test_score
+ return dict(train=train_score, valid=valid_score, test=test_score), xstr
+
+ # Pre-fetch the potential checkpoints
+ ckp_path = os.path.join(save_dir, "{:}.pth".format(self.__class__.__name__))
+ if os.path.exists(ckp_path):
+ ckp_data = torch.load(ckp_path, map_location=self.device)
+ stop_steps, best_score, best_epoch = (
+ ckp_data["stop_steps"],
+ ckp_data["best_score"],
+ ckp_data["best_epoch"],
+ )
+ start_epoch, best_param = ckp_data["start_epoch"], ckp_data["best_param"]
+ results_dict = ckp_data["results_dict"]
+ self.model.load_state_dict(ckp_data["net_state_dict"])
+ self.train_optimizer.load_state_dict(ckp_data["opt_state_dict"])
+ self.logger.info("Resume from existing checkpoint: {:}".format(ckp_path))
+ else:
+ stop_steps, best_score, best_epoch = 0, -np.inf, -1
+ start_epoch, best_param = 0, None
+ results_dict = dict(
+ train=OrderedDict(), valid=OrderedDict(), test=OrderedDict()
+ )
+ _, eval_str = _internal_test(-1, results_dict)
+ self.logger.info(
+ "Training from scratch, metrics@start: {:}".format(eval_str)
+ )
+
+ for iepoch in range(start_epoch, self.opt_config["epochs"]):
+ self.logger.info(
+ "Epoch={:03d}/{:03d} ::==>> Best valid @{:03d} ({:.6f})".format(
+ iepoch, self.opt_config["epochs"], best_epoch, best_score
+ )
+ )
+ train_loss, train_score = train_or_test_epoch(
+ train_loader,
+ self.model,
+ self.loss_fn,
+ self.metric_fn,
+ True,
+ self.train_optimizer,
+ self.device,
+ )
+ self.logger.info(
+ "Training :: loss={:.6f}, score={:.6f}".format(train_loss, train_score)
+ )
+
+ current_eval_scores, eval_str = _internal_test(iepoch, results_dict)
+ self.logger.info("Evaluating :: {:}".format(eval_str))
+
+ if current_eval_scores["valid"] > best_score:
+ stop_steps, best_epoch, best_score = (
+ 0,
+ iepoch,
+ current_eval_scores["valid"],
+ )
+ best_param = copy.deepcopy(self.model.state_dict())
+ else:
+ stop_steps += 1
+ if stop_steps >= self.opt_config["early_stop"]:
+ self.logger.info(
+ "early stop at {:}-th epoch, where the best is @{:}".format(
+ iepoch, best_epoch
+ )
+ )
+ break
+ save_info = dict(
+ net_config=self.net_config,
+ opt_config=self.opt_config,
+ net_state_dict=self.model.state_dict(),
+ opt_state_dict=self.train_optimizer.state_dict(),
+ best_param=best_param,
+ stop_steps=stop_steps,
+ best_score=best_score,
+ best_epoch=best_epoch,
+ results_dict=results_dict,
+ start_epoch=iepoch + 1,
+ )
+ torch.save(save_info, ckp_path)
+ self.logger.info(
+ "The best score: {:.6f} @ {:02d}-th epoch".format(best_score, best_epoch)
+ )
+ self.model.load_state_dict(best_param)
+ _, eval_str = _internal_test("final", results_dict)
+ self.logger.info("Reload the best parameter :: {:}".format(eval_str))
+
+ if self.use_gpu:
+ with torch.cuda.device(self.device):
+ torch.cuda.empty_cache()
+ self.fitted = True
+
+ def predict(self, dataset: DatasetH, segment: Union[Text, slice] = "test"):
+ if not self.fitted:
+ raise ValueError("The model is not fitted yet!")
+ x_test = dataset.prepare(
+ segment, col_set="feature", data_key=DataHandlerLP.DK_I
+ )
+ index = x_test.index
+
+ with torch.no_grad():
+ self.model.eval()
+ x_values = x_test.values
+ sample_num, batch_size = x_values.shape[0], self.opt_config["batch_size"]
+ preds = []
+ for begin in range(sample_num)[::batch_size]:
+ if sample_num - begin < batch_size:
+ end = sample_num
+ else:
+ end = begin + batch_size
+ x_batch = torch.from_numpy(x_values[begin:end]).float().to(self.device)
+ with torch.no_grad():
+ pred = self.model(x_batch).detach().cpu().numpy()
+ preds.append(pred)
+ return pd.Series(np.concatenate(preds), index=index)
diff --git a/AutoDL-Projects/xautodl/trade_models/transformers.py b/AutoDL-Projects/xautodl/trade_models/transformers.py
new file mode 100644
index 0000000..100cca4
--- /dev/null
+++ b/AutoDL-Projects/xautodl/trade_models/transformers.py
@@ -0,0 +1,199 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.03 #
+#####################################################
+from __future__ import division
+from __future__ import print_function
+
+import math
+from functools import partial
+from typing import Optional, Text, List
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+
+from xautodl import spaces
+from xautodl.xlayers import weight_init
+from xautodl.xlayers import super_core
+
+
+__all__ = ["DefaultSearchSpace", "DEFAULT_NET_CONFIG", "get_transformer"]
+
+
+def _get_mul_specs(candidates, num):
+ results = []
+ for i in range(num):
+ results.append(spaces.Categorical(*candidates))
+ return results
+
+
+def _get_list_mul(num, multipler):
+ results = []
+ for i in range(1, num + 1):
+ results.append(i * multipler)
+ return results
+
+
+def _assert_types(x, expected_types):
+ if not isinstance(x, expected_types):
+ raise TypeError(
+ "The type [{:}] is expected to be {:}.".format(type(x), expected_types)
+ )
+
+
+DEFAULT_NET_CONFIG = None
+_default_max_depth = 6
+DefaultSearchSpace = dict(
+ d_feat=6,
+ embed_dim=32,
+ # embed_dim=spaces.Categorical(*_get_list_mul(8, 16)),
+ num_heads=[4] * _default_max_depth,
+ mlp_hidden_multipliers=[4] * _default_max_depth,
+ qkv_bias=True,
+ pos_drop=0.0,
+ other_drop=0.0,
+)
+
+
+class SuperTransformer(super_core.SuperModule):
+ """The super model for transformer."""
+
+ def __init__(
+ self,
+ d_feat: int = 6,
+ embed_dim: List[super_core.IntSpaceType] = DefaultSearchSpace["embed_dim"],
+ num_heads: List[super_core.IntSpaceType] = DefaultSearchSpace["num_heads"],
+ mlp_hidden_multipliers: List[super_core.IntSpaceType] = DefaultSearchSpace[
+ "mlp_hidden_multipliers"
+ ],
+ qkv_bias: bool = DefaultSearchSpace["qkv_bias"],
+ pos_drop: float = DefaultSearchSpace["pos_drop"],
+ other_drop: float = DefaultSearchSpace["other_drop"],
+ max_seq_len: int = 65,
+ ):
+ super(SuperTransformer, self).__init__()
+ self._embed_dim = embed_dim
+ self._num_heads = num_heads
+ self._mlp_hidden_multipliers = mlp_hidden_multipliers
+
+ # the stem part
+ self.input_embed = super_core.SuperAlphaEBDv1(d_feat, embed_dim)
+ self.cls_token = nn.Parameter(torch.zeros(1, 1, self.embed_dim))
+ self.pos_embed = super_core.SuperPositionalEncoder(
+ d_model=embed_dim, max_seq_len=max_seq_len, dropout=pos_drop
+ )
+ # build the transformer encode layers -->> check params
+ _assert_types(num_heads, (tuple, list))
+ _assert_types(mlp_hidden_multipliers, (tuple, list))
+ assert len(num_heads) == len(mlp_hidden_multipliers), "{:} vs {:}".format(
+ len(num_heads), len(mlp_hidden_multipliers)
+ )
+ # build the transformer encode layers -->> backbone
+ layers = []
+ for num_head, mlp_hidden_multiplier in zip(num_heads, mlp_hidden_multipliers):
+ layer = super_core.SuperTransformerEncoderLayer(
+ embed_dim,
+ num_head,
+ qkv_bias,
+ mlp_hidden_multiplier,
+ other_drop,
+ )
+ layers.append(layer)
+ self.backbone = super_core.SuperSequential(*layers)
+
+ # the regression head
+ self.head = super_core.SuperSequential(
+ super_core.SuperLayerNorm1D(embed_dim), super_core.SuperLinear(embed_dim, 1)
+ )
+ weight_init.trunc_normal_(self.cls_token, std=0.02)
+ self.apply(self._init_weights)
+
+ @property
+ def embed_dim(self):
+ return spaces.get_max(self._embed_dim)
+
+ @property
+ def abstract_search_space(self):
+ root_node = spaces.VirtualNode(id(self))
+ if not spaces.is_determined(self._embed_dim):
+ root_node.append("_embed_dim", self._embed_dim.abstract(reuse_last=True))
+ xdict = dict(
+ input_embed=self.input_embed.abstract_search_space,
+ pos_embed=self.pos_embed.abstract_search_space,
+ backbone=self.backbone.abstract_search_space,
+ head=self.head.abstract_search_space,
+ )
+ for key, space in xdict.items():
+ if not spaces.is_determined(space):
+ root_node.append(key, space)
+ return root_node
+
+ def apply_candidate(self, abstract_child: spaces.VirtualNode):
+ super(SuperTransformer, self).apply_candidate(abstract_child)
+ xkeys = ("input_embed", "pos_embed", "backbone", "head")
+ for key in xkeys:
+ if key in abstract_child:
+ getattr(self, key).apply_candidate(abstract_child[key])
+
+ def _init_weights(self, m):
+ if isinstance(m, nn.Linear):
+ weight_init.trunc_normal_(m.weight, std=0.02)
+ if isinstance(m, nn.Linear) and m.bias is not None:
+ nn.init.constant_(m.bias, 0)
+ elif isinstance(m, super_core.SuperLinear):
+ weight_init.trunc_normal_(m._super_weight, std=0.02)
+ if m._super_bias is not None:
+ nn.init.constant_(m._super_bias, 0)
+ elif isinstance(m, super_core.SuperLayerNorm1D):
+ nn.init.constant_(m.weight, 1.0)
+ nn.init.constant_(m.bias, 0)
+
+ def forward_candidate(self, input: torch.Tensor) -> torch.Tensor:
+ batch, flatten_size = input.shape
+ feats = self.input_embed(input) # batch * 60 * 64
+ if not spaces.is_determined(self._embed_dim):
+ embed_dim = self.abstract_child["_embed_dim"].value
+ else:
+ embed_dim = spaces.get_determined_value(self._embed_dim)
+ cls_tokens = self.cls_token.expand(batch, -1, -1)
+ cls_tokens = F.interpolate(
+ cls_tokens, size=(embed_dim), mode="linear", align_corners=True
+ )
+ feats_w_ct = torch.cat((cls_tokens, feats), dim=1)
+ feats_w_tp = self.pos_embed(feats_w_ct)
+ xfeats = self.backbone(feats_w_tp)
+ xfeats = xfeats[:, 0, :] # use the feature for the first token
+ predicts = self.head(xfeats).squeeze(-1)
+ return predicts
+
+ def forward_raw(self, input: torch.Tensor) -> torch.Tensor:
+ batch, flatten_size = input.shape
+ feats = self.input_embed(input) # batch * 60 * 64
+ cls_tokens = self.cls_token.expand(batch, -1, -1)
+ feats_w_ct = torch.cat((cls_tokens, feats), dim=1)
+ feats_w_tp = self.pos_embed(feats_w_ct)
+ xfeats = self.backbone(feats_w_tp)
+ xfeats = xfeats[:, 0, :] # use the feature for the first token
+ predicts = self.head(xfeats).squeeze(-1)
+ return predicts
+
+
+def get_transformer(config):
+ if config is None:
+ return SuperTransformer(6)
+ if not isinstance(config, dict):
+ raise ValueError("Invalid Configuration: {:}".format(config))
+ name = config.get("name", "basic")
+ if name == "basic":
+ model = SuperTransformer(
+ d_feat=config.get("d_feat"),
+ embed_dim=config.get("embed_dim"),
+ num_heads=config.get("num_heads"),
+ mlp_hidden_multipliers=config.get("mlp_hidden_multipliers"),
+ qkv_bias=config.get("qkv_bias"),
+ pos_drop=config.get("pos_drop"),
+ other_drop=config.get("other_drop"),
+ )
+ else:
+ raise ValueError("Unknown model name: {:}".format(name))
+ return model
diff --git a/AutoDL-Projects/xautodl/utils/__init__.py b/AutoDL-Projects/xautodl/utils/__init__.py
new file mode 100644
index 0000000..4c39ad1
--- /dev/null
+++ b/AutoDL-Projects/xautodl/utils/__init__.py
@@ -0,0 +1,14 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.01 #
+#####################################################
+# This directory contains some ad-hoc functions, classes, etc.
+# It will be re-formulated in the future.
+#####################################################
+from .evaluation_utils import obtain_accuracy
+from .gpu_manager import GPUManager
+from .flop_benchmark import get_model_infos, count_parameters, count_parameters_in_MB
+from .affine_utils import normalize_points, denormalize_points
+from .affine_utils import identity2affine, solve2theta, affine2image
+from .hash_utils import get_md5_file
+from .str_utils import split_str2indexes
+from .str_utils import show_mean_var
diff --git a/AutoDL-Projects/xautodl/utils/affine_utils.py b/AutoDL-Projects/xautodl/utils/affine_utils.py
new file mode 100644
index 0000000..c1f7ad2
--- /dev/null
+++ b/AutoDL-Projects/xautodl/utils/affine_utils.py
@@ -0,0 +1,159 @@
+# functions for affine transformation
+import math
+import torch
+import numpy as np
+import torch.nn.functional as F
+
+
+def identity2affine(full=False):
+ if not full:
+ parameters = torch.zeros((2, 3))
+ parameters[0, 0] = parameters[1, 1] = 1
+ else:
+ parameters = torch.zeros((3, 3))
+ parameters[0, 0] = parameters[1, 1] = parameters[2, 2] = 1
+ return parameters
+
+
+def normalize_L(x, L):
+ return -1.0 + 2.0 * x / (L - 1)
+
+
+def denormalize_L(x, L):
+ return (x + 1.0) / 2.0 * (L - 1)
+
+
+def crop2affine(crop_box, W, H):
+ assert len(crop_box) == 4, "Invalid crop-box : {:}".format(crop_box)
+ parameters = torch.zeros(3, 3)
+ x1, y1 = normalize_L(crop_box[0], W), normalize_L(crop_box[1], H)
+ x2, y2 = normalize_L(crop_box[2], W), normalize_L(crop_box[3], H)
+ parameters[0, 0] = (x2 - x1) / 2
+ parameters[0, 2] = (x2 + x1) / 2
+
+ parameters[1, 1] = (y2 - y1) / 2
+ parameters[1, 2] = (y2 + y1) / 2
+ parameters[2, 2] = 1
+ return parameters
+
+
+def scale2affine(scalex, scaley):
+ parameters = torch.zeros(3, 3)
+ parameters[0, 0] = scalex
+ parameters[1, 1] = scaley
+ parameters[2, 2] = 1
+ return parameters
+
+
+def offset2affine(offx, offy):
+ parameters = torch.zeros(3, 3)
+ parameters[0, 0] = parameters[1, 1] = parameters[2, 2] = 1
+ parameters[0, 2] = offx
+ parameters[1, 2] = offy
+ return parameters
+
+
+def horizontalmirror2affine():
+ parameters = torch.zeros(3, 3)
+ parameters[0, 0] = -1
+ parameters[1, 1] = parameters[2, 2] = 1
+ return parameters
+
+
+# clockwise rotate image = counterclockwise rotate the rectangle
+# degree is between [0, 360]
+def rotate2affine(degree):
+ assert degree >= 0 and degree <= 360, "Invalid degree : {:}".format(degree)
+ degree = degree / 180 * math.pi
+ parameters = torch.zeros(3, 3)
+ parameters[0, 0] = math.cos(-degree)
+ parameters[0, 1] = -math.sin(-degree)
+ parameters[1, 0] = math.sin(-degree)
+ parameters[1, 1] = math.cos(-degree)
+ parameters[2, 2] = 1
+ return parameters
+
+
+# shape is a tuple [H, W]
+def normalize_points(shape, points):
+ assert (isinstance(shape, tuple) or isinstance(shape, list)) and len(
+ shape
+ ) == 2, "invalid shape : {:}".format(shape)
+ assert isinstance(points, torch.Tensor) and (
+ points.shape[0] == 2
+ ), "points are wrong : {:}".format(points.shape)
+ (H, W), points = shape, points.clone()
+ points[0, :] = normalize_L(points[0, :], W)
+ points[1, :] = normalize_L(points[1, :], H)
+ return points
+
+
+# shape is a tuple [H, W]
+def normalize_points_batch(shape, points):
+ assert (isinstance(shape, tuple) or isinstance(shape, list)) and len(
+ shape
+ ) == 2, "invalid shape : {:}".format(shape)
+ assert isinstance(points, torch.Tensor) and (
+ points.size(-1) == 2
+ ), "points are wrong : {:}".format(points.shape)
+ (H, W), points = shape, points.clone()
+ x = normalize_L(points[..., 0], W)
+ y = normalize_L(points[..., 1], H)
+ return torch.stack((x, y), dim=-1)
+
+
+# shape is a tuple [H, W]
+def denormalize_points(shape, points):
+ assert (isinstance(shape, tuple) or isinstance(shape, list)) and len(
+ shape
+ ) == 2, "invalid shape : {:}".format(shape)
+ assert isinstance(points, torch.Tensor) and (
+ points.shape[0] == 2
+ ), "points are wrong : {:}".format(points.shape)
+ (H, W), points = shape, points.clone()
+ points[0, :] = denormalize_L(points[0, :], W)
+ points[1, :] = denormalize_L(points[1, :], H)
+ return points
+
+
+# shape is a tuple [H, W]
+def denormalize_points_batch(shape, points):
+ assert (isinstance(shape, tuple) or isinstance(shape, list)) and len(
+ shape
+ ) == 2, "invalid shape : {:}".format(shape)
+ assert isinstance(points, torch.Tensor) and (
+ points.shape[-1] == 2
+ ), "points are wrong : {:}".format(points.shape)
+ (H, W), points = shape, points.clone()
+ x = denormalize_L(points[..., 0], W)
+ y = denormalize_L(points[..., 1], H)
+ return torch.stack((x, y), dim=-1)
+
+
+# make target * theta = source
+def solve2theta(source, target):
+ source, target = source.clone(), target.clone()
+ oks = source[2, :] == 1
+ assert torch.sum(oks).item() >= 3, "valid points : {:} is short".format(oks)
+ if target.size(0) == 2:
+ target = torch.cat((target, oks.unsqueeze(0).float()), dim=0)
+ source, target = source[:, oks], target[:, oks]
+ source, target = source.transpose(1, 0), target.transpose(1, 0)
+ assert source.size(1) == target.size(1) == 3
+ # X, residual, rank, s = np.linalg.lstsq(target.numpy(), source.numpy())
+ # theta = torch.Tensor(X.T[:2, :])
+ X_, qr = torch.gels(source, target)
+ theta = X_[:3, :2].transpose(1, 0)
+ return theta
+
+
+# shape = [H,W]
+def affine2image(image, theta, shape):
+ C, H, W = image.size()
+ theta = theta[:2, :].unsqueeze(0)
+ grid_size = torch.Size([1, C, shape[0], shape[1]])
+ grid = F.affine_grid(theta, grid_size)
+ affI = F.grid_sample(
+ image.unsqueeze(0), grid, mode="bilinear", padding_mode="border"
+ )
+ return affI.squeeze(0)
diff --git a/AutoDL-Projects/xautodl/utils/evaluation_utils.py b/AutoDL-Projects/xautodl/utils/evaluation_utils.py
new file mode 100644
index 0000000..088f318
--- /dev/null
+++ b/AutoDL-Projects/xautodl/utils/evaluation_utils.py
@@ -0,0 +1,17 @@
+import torch
+
+
+def obtain_accuracy(output, target, topk=(1,)):
+ """Computes the precision@k for the specified values of k"""
+ maxk = max(topk)
+ batch_size = target.size(0)
+
+ _, pred = output.topk(maxk, 1, True, True)
+ pred = pred.t()
+ correct = pred.eq(target.view(1, -1).expand_as(pred))
+
+ res = []
+ for k in topk:
+ correct_k = correct[:k].view(-1).float().sum(0, keepdim=True)
+ res.append(correct_k.mul_(100.0 / batch_size))
+ return res
diff --git a/AutoDL-Projects/xautodl/utils/flop_benchmark.py b/AutoDL-Projects/xautodl/utils/flop_benchmark.py
new file mode 100644
index 0000000..898c17e
--- /dev/null
+++ b/AutoDL-Projects/xautodl/utils/flop_benchmark.py
@@ -0,0 +1,227 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.01 #
+#####################################################
+import torch
+import torch.nn as nn
+import numpy as np
+
+
+def count_parameters_in_MB(model):
+ return count_parameters(model, "mb", deprecated=True)
+
+
+def count_parameters(model_or_parameters, unit="mb", deprecated=False):
+ if isinstance(model_or_parameters, nn.Module):
+ counts = sum(np.prod(v.size()) for v in model_or_parameters.parameters())
+ elif isinstance(model_or_parameters, nn.Parameter):
+ counts = model_or_parameters.numel()
+ elif isinstance(model_or_parameters, (list, tuple)):
+ counts = sum(
+ count_parameters(x, None, deprecated) for x in model_or_parameters
+ )
+ else:
+ counts = sum(np.prod(v.size()) for v in model_or_parameters)
+ if not isinstance(unit, str) and unit is not None:
+ raise ValueError("Unknow type of unit: {:}".format(unit))
+ elif unit is None:
+ counts = counts
+ elif unit.lower() == "kb" or unit.lower() == "k":
+ counts /= 1e3 if deprecated else 2 ** 10 # changed from 1e3 to 2^10
+ elif unit.lower() == "mb" or unit.lower() == "m":
+ counts /= 1e6 if deprecated else 2 ** 20 # changed from 1e6 to 2^20
+ elif unit.lower() == "gb" or unit.lower() == "g":
+ counts /= 1e9 if deprecated else 2 ** 30 # changed from 1e9 to 2^30
+ else:
+ raise ValueError("Unknow unit: {:}".format(unit))
+ return counts
+
+
+def get_model_infos(model, shape):
+ # model = copy.deepcopy( model )
+
+ model = add_flops_counting_methods(model)
+ # model = model.cuda()
+ model.eval()
+
+ # cache_inputs = torch.zeros(*shape).cuda()
+ # cache_inputs = torch.zeros(*shape)
+ cache_inputs = torch.rand(*shape)
+ if next(model.parameters()).is_cuda:
+ cache_inputs = cache_inputs.cuda()
+ # print_log('In the calculating function : cache input size : {:}'.format(cache_inputs.size()), log)
+ with torch.no_grad():
+ _____ = model(cache_inputs)
+ FLOPs = compute_average_flops_cost(model) / 1e6
+ Param = count_parameters_in_MB(model)
+
+ if hasattr(model, "auxiliary_param"):
+ aux_params = count_parameters_in_MB(model.auxiliary_param())
+ print("The auxiliary params of this model is : {:}".format(aux_params))
+ print(
+ "We remove the auxiliary params from the total params ({:}) when counting".format(
+ Param
+ )
+ )
+ Param = Param - aux_params
+
+ # print_log('FLOPs : {:} MB'.format(FLOPs), log)
+ torch.cuda.empty_cache()
+ model.apply(remove_hook_function)
+ return FLOPs, Param
+
+
+# ---- Public functions
+def add_flops_counting_methods(model):
+ model.__batch_counter__ = 0
+ add_batch_counter_hook_function(model)
+ model.apply(add_flops_counter_variable_or_reset)
+ model.apply(add_flops_counter_hook_function)
+ return model
+
+
+def compute_average_flops_cost(model):
+ """
+ A method that will be available after add_flops_counting_methods() is called on a desired net object.
+ Returns current mean flops consumption per image.
+ """
+ batches_count = model.__batch_counter__
+ flops_sum = 0
+ # or isinstance(module, torch.nn.AvgPool2d) or isinstance(module, torch.nn.MaxPool2d) \
+ for module in model.modules():
+ if (
+ isinstance(module, torch.nn.Conv2d)
+ or isinstance(module, torch.nn.Linear)
+ or isinstance(module, torch.nn.Conv1d)
+ or hasattr(module, "calculate_flop_self")
+ ):
+ flops_sum += module.__flops__
+ return flops_sum / batches_count
+
+
+# ---- Internal functions
+def pool_flops_counter_hook(pool_module, inputs, output):
+ batch_size = inputs[0].size(0)
+ kernel_size = pool_module.kernel_size
+ out_C, output_height, output_width = output.shape[1:]
+ assert out_C == inputs[0].size(1), "{:} vs. {:}".format(out_C, inputs[0].size())
+
+ overall_flops = (
+ batch_size * out_C * output_height * output_width * kernel_size * kernel_size
+ )
+ pool_module.__flops__ += overall_flops
+
+
+def self_calculate_flops_counter_hook(self_module, inputs, output):
+ overall_flops = self_module.calculate_flop_self(inputs[0].shape, output.shape)
+ self_module.__flops__ += overall_flops
+
+
+def fc_flops_counter_hook(fc_module, inputs, output):
+ batch_size = inputs[0].size(0)
+ xin, xout = fc_module.in_features, fc_module.out_features
+ assert xin == inputs[0].size(1) and xout == output.size(1), "IO=({:}, {:})".format(
+ xin, xout
+ )
+ overall_flops = batch_size * xin * xout
+ if fc_module.bias is not None:
+ overall_flops += batch_size * xout
+ fc_module.__flops__ += overall_flops
+
+
+def conv1d_flops_counter_hook(conv_module, inputs, outputs):
+ batch_size = inputs[0].size(0)
+ outL = outputs.shape[-1]
+ [kernel] = conv_module.kernel_size
+ in_channels = conv_module.in_channels
+ out_channels = conv_module.out_channels
+ groups = conv_module.groups
+ conv_per_position_flops = kernel * in_channels * out_channels / groups
+
+ active_elements_count = batch_size * outL
+ overall_flops = conv_per_position_flops * active_elements_count
+
+ if conv_module.bias is not None:
+ overall_flops += out_channels * active_elements_count
+ conv_module.__flops__ += overall_flops
+
+
+def conv2d_flops_counter_hook(conv_module, inputs, output):
+ batch_size = inputs[0].size(0)
+ output_height, output_width = output.shape[2:]
+
+ kernel_height, kernel_width = conv_module.kernel_size
+ in_channels = conv_module.in_channels
+ out_channels = conv_module.out_channels
+ groups = conv_module.groups
+ conv_per_position_flops = (
+ kernel_height * kernel_width * in_channels * out_channels / groups
+ )
+
+ active_elements_count = batch_size * output_height * output_width
+ overall_flops = conv_per_position_flops * active_elements_count
+
+ if conv_module.bias is not None:
+ overall_flops += out_channels * active_elements_count
+ conv_module.__flops__ += overall_flops
+
+
+def batch_counter_hook(module, inputs, output):
+ # Can have multiple inputs, getting the first one
+ inputs = inputs[0]
+ batch_size = inputs.shape[0]
+ module.__batch_counter__ += batch_size
+
+
+def add_batch_counter_hook_function(module):
+ if not hasattr(module, "__batch_counter_handle__"):
+ handle = module.register_forward_hook(batch_counter_hook)
+ module.__batch_counter_handle__ = handle
+
+
+def add_flops_counter_variable_or_reset(module):
+ if (
+ isinstance(module, torch.nn.Conv2d)
+ or isinstance(module, torch.nn.Linear)
+ or isinstance(module, torch.nn.Conv1d)
+ or isinstance(module, torch.nn.AvgPool2d)
+ or isinstance(module, torch.nn.MaxPool2d)
+ or hasattr(module, "calculate_flop_self")
+ ):
+ module.__flops__ = 0
+
+
+def add_flops_counter_hook_function(module):
+ if isinstance(module, torch.nn.Conv2d):
+ if not hasattr(module, "__flops_handle__"):
+ handle = module.register_forward_hook(conv2d_flops_counter_hook)
+ module.__flops_handle__ = handle
+ elif isinstance(module, torch.nn.Conv1d):
+ if not hasattr(module, "__flops_handle__"):
+ handle = module.register_forward_hook(conv1d_flops_counter_hook)
+ module.__flops_handle__ = handle
+ elif isinstance(module, torch.nn.Linear):
+ if not hasattr(module, "__flops_handle__"):
+ handle = module.register_forward_hook(fc_flops_counter_hook)
+ module.__flops_handle__ = handle
+ elif isinstance(module, torch.nn.AvgPool2d) or isinstance(
+ module, torch.nn.MaxPool2d
+ ):
+ if not hasattr(module, "__flops_handle__"):
+ handle = module.register_forward_hook(pool_flops_counter_hook)
+ module.__flops_handle__ = handle
+ elif hasattr(module, "calculate_flop_self"): # self-defined module
+ if not hasattr(module, "__flops_handle__"):
+ handle = module.register_forward_hook(self_calculate_flops_counter_hook)
+ module.__flops_handle__ = handle
+
+
+def remove_hook_function(module):
+ hookers = ["__batch_counter_handle__", "__flops_handle__"]
+ for hooker in hookers:
+ if hasattr(module, hooker):
+ handle = getattr(module, hooker)
+ handle.remove()
+ keys = ["__flops__", "__batch_counter__", "__flops__"] + hookers
+ for ckey in keys:
+ if hasattr(module, ckey):
+ delattr(module, ckey)
diff --git a/AutoDL-Projects/xautodl/utils/gpu_manager.py b/AutoDL-Projects/xautodl/utils/gpu_manager.py
new file mode 100644
index 0000000..700b856
--- /dev/null
+++ b/AutoDL-Projects/xautodl/utils/gpu_manager.py
@@ -0,0 +1,86 @@
+import os
+
+
+class GPUManager:
+ queries = (
+ "index",
+ "gpu_name",
+ "memory.free",
+ "memory.used",
+ "memory.total",
+ "power.draw",
+ "power.limit",
+ )
+
+ def __init__(self):
+ all_gpus = self.query_gpu(False)
+
+ def get_info(self, ctype):
+ cmd = "nvidia-smi --query-gpu={} --format=csv,noheader".format(ctype)
+ lines = os.popen(cmd).readlines()
+ lines = [line.strip("\n") for line in lines]
+ return lines
+
+ def query_gpu(self, show=True):
+ num_gpus = len(self.get_info("index"))
+ all_gpus = [{} for i in range(num_gpus)]
+ for query in self.queries:
+ infos = self.get_info(query)
+ for idx, info in enumerate(infos):
+ all_gpus[idx][query] = info
+
+ if "CUDA_VISIBLE_DEVICES" in os.environ:
+ CUDA_VISIBLE_DEVICES = os.environ["CUDA_VISIBLE_DEVICES"].split(",")
+ selected_gpus = []
+ for idx, CUDA_VISIBLE_DEVICE in enumerate(CUDA_VISIBLE_DEVICES):
+ find = False
+ for gpu in all_gpus:
+ if gpu["index"] == CUDA_VISIBLE_DEVICE:
+ assert not find, "Duplicate cuda device index : {}".format(
+ CUDA_VISIBLE_DEVICE
+ )
+ find = True
+ selected_gpus.append(gpu.copy())
+ selected_gpus[-1]["index"] = "{}".format(idx)
+ assert find, "Does not find the device : {}".format(CUDA_VISIBLE_DEVICE)
+ all_gpus = selected_gpus
+
+ if show:
+ allstrings = ""
+ for gpu in all_gpus:
+ string = "| "
+ for query in self.queries:
+ if query.find("memory") == 0:
+ xinfo = "{:>9}".format(gpu[query])
+ else:
+ xinfo = gpu[query]
+ string = string + query + " : " + xinfo + " | "
+ allstrings = allstrings + string + "\n"
+ return allstrings
+ else:
+ return all_gpus
+
+ def select_by_memory(self, numbers=1):
+ all_gpus = self.query_gpu(False)
+ assert numbers <= len(all_gpus), "Require {} gpus more than you have".format(
+ numbers
+ )
+ alls = []
+ for idx, gpu in enumerate(all_gpus):
+ free_memory = gpu["memory.free"]
+ free_memory = free_memory.split(" ")[0]
+ free_memory = int(free_memory)
+ index = gpu["index"]
+ alls.append((free_memory, index))
+ alls.sort(reverse=True)
+ alls = [int(alls[i][1]) for i in range(numbers)]
+ return sorted(alls)
+
+
+"""
+if __name__ == '__main__':
+ manager = GPUManager()
+ manager.query_gpu(True)
+ indexes = manager.select_by_memory(3)
+ print (indexes)
+"""
diff --git a/AutoDL-Projects/xautodl/utils/hash_utils.py b/AutoDL-Projects/xautodl/utils/hash_utils.py
new file mode 100644
index 0000000..53696ae
--- /dev/null
+++ b/AutoDL-Projects/xautodl/utils/hash_utils.py
@@ -0,0 +1,17 @@
+import os
+import hashlib
+
+
+def get_md5_file(file_path, post_truncated=5):
+ md5_hash = hashlib.md5()
+ if os.path.exists(file_path):
+ xfile = open(file_path, "rb")
+ content = xfile.read()
+ md5_hash.update(content)
+ digest = md5_hash.hexdigest()
+ else:
+ raise ValueError("[get_md5_file] {:} does not exist".format(file_path))
+ if post_truncated is None:
+ return digest
+ else:
+ return digest[-post_truncated:]
diff --git a/AutoDL-Projects/xautodl/utils/nas_utils.py b/AutoDL-Projects/xautodl/utils/nas_utils.py
new file mode 100644
index 0000000..48e81f5
--- /dev/null
+++ b/AutoDL-Projects/xautodl/utils/nas_utils.py
@@ -0,0 +1,76 @@
+# This file is for experimental usage
+import torch, random
+import numpy as np
+from copy import deepcopy
+import torch.nn as nn
+
+# modules in AutoDL
+from models import CellStructure
+from log_utils import time_string
+
+
+def evaluate_one_shot(model, xloader, api, cal_mode, seed=111):
+ print(
+ "This is an old version of codes to use NAS-Bench-API, and should be modified to align with the new version. Please contact me for more details if you use this function."
+ )
+ weights = deepcopy(model.state_dict())
+ model.train(cal_mode)
+ with torch.no_grad():
+ logits = nn.functional.log_softmax(model.arch_parameters, dim=-1)
+ archs = CellStructure.gen_all(model.op_names, model.max_nodes, False)
+ probs, accuracies, gt_accs_10_valid, gt_accs_10_test = [], [], [], []
+ loader_iter = iter(xloader)
+ random.seed(seed)
+ random.shuffle(archs)
+ for idx, arch in enumerate(archs):
+ arch_index = api.query_index_by_arch(arch)
+ metrics = api.get_more_info(arch_index, "cifar10-valid", None, False, False)
+ gt_accs_10_valid.append(metrics["valid-accuracy"])
+ metrics = api.get_more_info(arch_index, "cifar10", None, False, False)
+ gt_accs_10_test.append(metrics["test-accuracy"])
+ select_logits = []
+ for i, node_info in enumerate(arch.nodes):
+ for op, xin in node_info:
+ node_str = "{:}<-{:}".format(i + 1, xin)
+ op_index = model.op_names.index(op)
+ select_logits.append(logits[model.edge2index[node_str], op_index])
+ cur_prob = sum(select_logits).item()
+ probs.append(cur_prob)
+ cor_prob_valid = np.corrcoef(probs, gt_accs_10_valid)[0, 1]
+ cor_prob_test = np.corrcoef(probs, gt_accs_10_test)[0, 1]
+ print(
+ "{:} correlation for probabilities : {:.6f} on CIFAR-10 validation and {:.6f} on CIFAR-10 test".format(
+ time_string(), cor_prob_valid, cor_prob_test
+ )
+ )
+
+ for idx, arch in enumerate(archs):
+ model.set_cal_mode("dynamic", arch)
+ try:
+ inputs, targets = next(loader_iter)
+ except:
+ loader_iter = iter(xloader)
+ inputs, targets = next(loader_iter)
+ _, logits = model(inputs.cuda())
+ _, preds = torch.max(logits, dim=-1)
+ correct = (preds == targets.cuda()).float()
+ accuracies.append(correct.mean().item())
+ if idx != 0 and (idx % 500 == 0 or idx + 1 == len(archs)):
+ cor_accs_valid = np.corrcoef(accuracies, gt_accs_10_valid[: idx + 1])[
+ 0, 1
+ ]
+ cor_accs_test = np.corrcoef(accuracies, gt_accs_10_test[: idx + 1])[
+ 0, 1
+ ]
+ print(
+ "{:} {:05d}/{:05d} mode={:5s}, correlation : accs={:.5f} for CIFAR-10 valid, {:.5f} for CIFAR-10 test.".format(
+ time_string(),
+ idx,
+ len(archs),
+ "Train" if cal_mode else "Eval",
+ cor_accs_valid,
+ cor_accs_test,
+ )
+ )
+ model.load_state_dict(weights)
+ return archs, probs, accuracies
diff --git a/AutoDL-Projects/xautodl/utils/qlib_utils.py b/AutoDL-Projects/xautodl/utils/qlib_utils.py
new file mode 100644
index 0000000..1e1eec5
--- /dev/null
+++ b/AutoDL-Projects/xautodl/utils/qlib_utils.py
@@ -0,0 +1,129 @@
+import os
+import numpy as np
+from typing import List, Text
+from collections import defaultdict, OrderedDict
+
+
+class QResult:
+ """A class to maintain the results of a qlib experiment."""
+
+ def __init__(self, name):
+ self._result = defaultdict(list)
+ self._name = name
+ self._recorder_paths = []
+ self._date2ICs = []
+
+ def append(self, key, value):
+ self._result[key].append(value)
+
+ def append_path(self, xpath):
+ self._recorder_paths.append(xpath)
+
+ def append_date2ICs(self, date2IC):
+ if self._date2ICs: # not empty
+ keys = sorted(list(date2IC.keys()))
+ pre_keys = sorted(list(self._date2ICs[0].keys()))
+ assert len(keys) == len(pre_keys)
+ for i, (x, y) in enumerate(zip(keys, pre_keys)):
+ assert x == y, "[{:}] {:} vs {:}".format(i, x, y)
+ self._date2ICs.append(date2IC)
+
+ def find_all_dates(self):
+ dates = self._date2ICs[-1].keys()
+ return sorted(list(dates))
+
+ def get_IC_by_date(self, date, scale=1.0):
+ values = []
+ for date2IC in self._date2ICs:
+ values.append(date2IC[date] * scale)
+ return float(np.mean(values)), float(np.std(values))
+
+ @property
+ def name(self):
+ return self._name
+
+ @property
+ def paths(self):
+ return self._recorder_paths
+
+ @property
+ def result(self):
+ return self._result
+
+ @property
+ def keys(self):
+ return list(self._result.keys())
+
+ def __len__(self):
+ return len(self._result)
+
+ def __repr__(self):
+ return "{name}({xname}, {num} metrics)".format(
+ name=self.__class__.__name__, xname=self.name, num=len(self.result)
+ )
+
+ def __getitem__(self, key):
+ if key not in self._result:
+ raise ValueError(
+ "Invalid key {:}, please use one of {:}".format(key, self.keys)
+ )
+ values = self._result[key]
+ return float(np.mean(values))
+
+ def update(self, metrics, filter_keys=None):
+ for key, value in metrics.items():
+ if filter_keys is not None and key in filter_keys:
+ key = filter_keys[key]
+ elif filter_keys is not None:
+ continue
+ self.append(key, value)
+
+ @staticmethod
+ def full_str(xstr, space):
+ xformat = "{:" + str(space) + "s}"
+ return xformat.format(str(xstr))
+
+ @staticmethod
+ def merge_dict(dict_list):
+ new_dict = dict()
+ for xkey in dict_list[0].keys():
+ values = [x for xdict in dict_list for x in xdict[xkey]]
+ new_dict[xkey] = values
+ return new_dict
+
+ def info(
+ self,
+ keys: List[Text],
+ separate: Text = "& ",
+ space: int = 20,
+ verbose: bool = True,
+ version: str = "v1",
+ ):
+ avaliable_keys = []
+ for key in keys:
+ if key not in self.result:
+ print("There are invalid key [{:}].".format(key))
+ else:
+ avaliable_keys.append(key)
+ head_str = separate.join([self.full_str(x, space) for x in avaliable_keys])
+ values = []
+ for key in avaliable_keys:
+ if "IR" in key:
+ current_values = [x * 100 for x in self._result[key]]
+ else:
+ current_values = self._result[key]
+ mean = np.mean(current_values)
+ std = np.std(current_values)
+ if version == "v0":
+ values.append("{:.2f} $\pm$ {:.2f}".format(mean, std))
+ elif version == "v1":
+ values.append(
+ "{:.2f}".format(mean) + " \\subs{" + "{:.2f}".format(std) + "}"
+ )
+ else:
+ raise ValueError("Unknown version")
+ value_str = separate.join([self.full_str(x, space) for x in values])
+ if verbose:
+ print(head_str)
+ print(value_str)
+ return head_str, value_str
diff --git a/AutoDL-Projects/xautodl/utils/str_utils.py b/AutoDL-Projects/xautodl/utils/str_utils.py
new file mode 100644
index 0000000..5cd78fc
--- /dev/null
+++ b/AutoDL-Projects/xautodl/utils/str_utils.py
@@ -0,0 +1,34 @@
+import numpy as np
+
+
+def split_str2indexes(string: str, max_check: int, length_limit=5):
+ if not isinstance(string, str):
+ raise ValueError("Invalid scheme for {:}".format(string))
+ srangestr = "".join(string.split())
+ indexes = set()
+ for srange in srangestr.split(","):
+ srange = srange.split("-")
+ if len(srange) != 2:
+ raise ValueError("invalid srange : {:}".format(srange))
+ if length_limit is not None:
+ assert (
+ len(srange[0]) == len(srange[1]) == length_limit
+ ), "invalid srange : {:}".format(srange)
+ srange = (int(srange[0]), int(srange[1]))
+ if not (0 <= srange[0] <= srange[1] < max_check):
+ raise ValueError(
+ "{:} vs {:} vs {:}".format(srange[0], srange[1], max_check)
+ )
+ for i in range(srange[0], srange[1] + 1):
+ indexes.add(i)
+ return indexes
+
+
+def show_mean_var(xlist):
+ values = np.array(xlist)
+ print(
+ "{:.2f}".format(values.mean())
+ + "$_{{\pm}{"
+ + "{:.2f}".format(values.std())
+ + "}}$"
+ )
diff --git a/AutoDL-Projects/xautodl/utils/temp_sync.py b/AutoDL-Projects/xautodl/utils/temp_sync.py
new file mode 100644
index 0000000..fe8526d
--- /dev/null
+++ b/AutoDL-Projects/xautodl/utils/temp_sync.py
@@ -0,0 +1,61 @@
+# To be deleted.
+import copy
+import torch
+
+from xlayers.super_core import SuperSequential, SuperMLPv1
+from xlayers.super_core import SuperSimpleNorm
+from xlayers.super_core import SuperLinear
+
+
+def optimize_fn(xs, ys, device="cpu", max_iter=2000, max_lr=0.1):
+ xs = torch.FloatTensor(xs).view(-1, 1).to(device)
+ ys = torch.FloatTensor(ys).view(-1, 1).to(device)
+
+ model = SuperSequential(
+ SuperSimpleNorm(xs.mean().item(), xs.std().item()),
+ SuperLinear(1, 200),
+ torch.nn.LeakyReLU(),
+ SuperLinear(200, 100),
+ torch.nn.LeakyReLU(),
+ SuperLinear(100, 1),
+ ).to(device)
+ model.train()
+ optimizer = torch.optim.Adam(model.parameters(), lr=max_lr, amsgrad=True)
+ loss_func = torch.nn.MSELoss()
+ lr_scheduler = torch.optim.lr_scheduler.MultiStepLR(
+ optimizer,
+ milestones=[
+ int(max_iter * 0.25),
+ int(max_iter * 0.5),
+ int(max_iter * 0.75),
+ ],
+ gamma=0.3,
+ )
+
+ best_loss, best_param = None, None
+ for _iter in range(max_iter):
+ preds = model(xs)
+
+ optimizer.zero_grad()
+ loss = loss_func(preds, ys)
+ loss.backward()
+ optimizer.step()
+ lr_scheduler.step()
+
+ if best_loss is None or best_loss > loss.item():
+ best_loss = loss.item()
+ best_param = copy.deepcopy(model.state_dict())
+
+ # print('loss={:}, best-loss={:}'.format(loss.item(), best_loss))
+ model.load_state_dict(best_param)
+ return model, loss_func, best_loss
+
+
+def evaluate_fn(model, xs, ys, loss_fn, device="cpu"):
+ with torch.no_grad():
+ inputs = torch.FloatTensor(xs).view(-1, 1).to(device)
+ ys = torch.FloatTensor(ys).view(-1, 1).to(device)
+ preds = model(inputs)
+ loss = loss_fn(preds, ys)
+ preds = preds.view(-1).cpu().numpy()
+ return preds, loss.item()
diff --git a/AutoDL-Projects/xautodl/utils/weight_watcher.py b/AutoDL-Projects/xautodl/utils/weight_watcher.py
new file mode 100644
index 0000000..7a766d4
--- /dev/null
+++ b/AutoDL-Projects/xautodl/utils/weight_watcher.py
@@ -0,0 +1,400 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020.03 #
+#####################################################
+# Reformulate the codes in https://github.com/CalculatedContent/WeightWatcher
+#####################################################
+import numpy as np
+from typing import List
+import torch.nn as nn
+from collections import OrderedDict
+from sklearn.decomposition import TruncatedSVD
+
+
+def available_module_types():
+ return (nn.Conv2d, nn.Linear)
+
+
+def get_conv2D_Wmats(tensor: np.ndarray) -> List[np.ndarray]:
+ """
+ Extract W slices from a 4 index conv2D tensor of shape: (N,M,i,j) or (M,N,i,j).
+ Return ij (N x M) matrices
+ """
+ mats = []
+ N, M, imax, jmax = tensor.shape
+ assert (
+ N + M >= imax + jmax
+ ), "invalid tensor shape detected: {}x{} (NxM), {}x{} (i,j)".format(
+ N, M, imax, jmax
+ )
+ for i in range(imax):
+ for j in range(jmax):
+ w = tensor[:, :, i, j]
+ if N < M:
+ w = w.T
+ mats.append(w)
+ return mats
+
+
+def glorot_norm_check(W, N, M, rf_size, lower=0.5, upper=1.5):
+ """Check if this layer needs Glorot Normalization Fix"""
+
+ kappa = np.sqrt(2 / ((N + M) * rf_size))
+ norm = np.linalg.norm(W)
+
+ check1 = norm / np.sqrt(N * M)
+ check2 = norm / (kappa * np.sqrt(N * M))
+
+ if (rf_size > 1) and (check2 > lower) and (check2 < upper):
+ return check2, True
+ elif (check1 > lower) & (check1 < upper):
+ return check1, True
+ else:
+ if rf_size > 1:
+ return check2, False
+ else:
+ return check1, False
+
+
+def glorot_norm_fix(w, n, m, rf_size):
+ """Apply Glorot Normalization Fix."""
+ kappa = np.sqrt(2 / ((n + m) * rf_size))
+ w = w / kappa
+ return w
+
+
+def analyze_weights(
+ weights,
+ min_size,
+ max_size,
+ alphas,
+ lognorms,
+ spectralnorms,
+ softranks,
+ normalize,
+ glorot_fix,
+):
+ results = OrderedDict()
+ count = len(weights)
+ if count == 0:
+ return results
+
+ for i, weight in enumerate(weights):
+ M, N = np.min(weight.shape), np.max(weight.shape)
+ Q = N / M
+ results[i] = cur_res = OrderedDict(N=N, M=M, Q=Q)
+ check, checkTF = glorot_norm_check(weight, N, M, count)
+ cur_res["check"] = check
+ cur_res["checkTF"] = checkTF
+ # assume receptive field size is count
+ if glorot_fix:
+ weight = glorot_norm_fix(weight, N, M, count)
+ else:
+ # probably never needed since we always fix for glorot
+ weight = weight * np.sqrt(count / 2.0)
+
+ if spectralnorms: # spectralnorm is the max eigenvalues
+ svd = TruncatedSVD(n_components=1, n_iter=7, random_state=10)
+ svd.fit(weight)
+ sv = svd.singular_values_
+ sv_max = np.max(sv)
+ if normalize:
+ evals = sv * sv / N
+ else:
+ evals = sv * sv
+ lambda0 = evals[0]
+ cur_res["spectralnorm"] = lambda0
+ cur_res["logspectralnorm"] = np.log10(lambda0)
+ else:
+ lambda0 = None
+
+ if M < min_size:
+ summary = "Weight matrix {}/{} ({},{}): Skipping: too small (<{})".format(
+ i + 1, count, M, N, min_size
+ )
+ cur_res["summary"] = summary
+ continue
+ elif max_size > 0 and M > max_size:
+ summary = (
+ "Weight matrix {}/{} ({},{}): Skipping: too big (testing) (>{})".format(
+ i + 1, count, M, N, max_size
+ )
+ )
+ cur_res["summary"] = summary
+ continue
+ else:
+ summary = []
+ if alphas:
+ import powerlaw
+
+ svd = TruncatedSVD(n_components=M - 1, n_iter=7, random_state=10)
+ svd.fit(weight.astype(float))
+ sv = svd.singular_values_
+ if normalize:
+ evals = sv * sv / N
+ else:
+ evals = sv * sv
+
+ lambda_max = np.max(evals)
+ fit = powerlaw.Fit(evals, xmax=lambda_max, verbose=False)
+ alpha = fit.alpha
+ cur_res["alpha"] = alpha
+ D = fit.D
+ cur_res["D"] = D
+ cur_res["lambda_min"] = np.min(evals)
+ cur_res["lambda_max"] = lambda_max
+ alpha_weighted = alpha * np.log10(lambda_max)
+ cur_res["alpha_weighted"] = alpha_weighted
+ tolerance = lambda_max * M * np.finfo(np.max(sv)).eps
+ cur_res["rank_loss"] = np.count_nonzero(sv > tolerance, axis=-1)
+
+ logpnorm = np.log10(np.sum([ev ** alpha for ev in evals]))
+ cur_res["logpnorm"] = logpnorm
+
+ summary.append(
+ "Weight matrix {}/{} ({},{}): Alpha: {}, Alpha Weighted: {}, D: {}, pNorm {}".format(
+ i + 1, count, M, N, alpha, alpha_weighted, D, logpnorm
+ )
+ )
+
+ if lognorms:
+ norm = np.linalg.norm(weight) # Frobenius Norm
+ cur_res["norm"] = norm
+ lognorm = np.log10(norm)
+ cur_res["lognorm"] = lognorm
+
+ X = np.dot(weight.T, weight)
+ if normalize:
+ X = X / N
+ normX = np.linalg.norm(X) # Frobenius Norm
+ cur_res["normX"] = normX
+ lognormX = np.log10(normX)
+ cur_res["lognormX"] = lognormX
+
+ summary.append(
+ "Weight matrix {}/{} ({},{}): LogNorm: {} ; LogNormX: {}".format(
+ i + 1, count, M, N, lognorm, lognormX
+ )
+ )
+
+ if softranks:
+ softrank = norm ** 2 / sv_max ** 2
+ softranklog = np.log10(softrank)
+ softranklogratio = lognorm / np.log10(sv_max)
+ cur_res["softrank"] = softrank
+ cur_res["softranklog"] = softranklog
+ cur_res["softranklogratio"] = softranklogratio
+ summary += (
+ "{}. Softrank: {}. Softrank log: {}. Softrank log ratio: {}".format(
+ summary, softrank, softranklog, softranklogratio
+ )
+ )
+ cur_res["summary"] = "\n".join(summary)
+ return results
+
+
+def compute_details(results):
+ """
+ Return a pandas data frame.
+ """
+ final_summary = OrderedDict()
+
+ metrics = {
+ # key in "results" : pretty print name
+ "check": "Check",
+ "checkTF": "CheckTF",
+ "norm": "Norm",
+ "lognorm": "LogNorm",
+ "normX": "Norm X",
+ "lognormX": "LogNorm X",
+ "alpha": "Alpha",
+ "alpha_weighted": "Alpha Weighted",
+ "spectralnorm": "Spectral Norm",
+ "logspectralnorm": "Log Spectral Norm",
+ "softrank": "Softrank",
+ "softranklog": "Softrank Log",
+ "softranklogratio": "Softrank Log Ratio",
+ "sigma_mp": "Marchenko-Pastur (MP) fit sigma",
+ "numofSpikes": "Number of spikes per MP fit",
+ "ratio_numofSpikes": "aka, percent_mass, Number of spikes / total number of evals",
+ "softrank_mp": "Softrank for MP fit",
+ "logpnorm": "alpha pNorm",
+ }
+
+ metrics_stats = []
+ for metric in metrics:
+ metrics_stats.append("{}_min".format(metric))
+ metrics_stats.append("{}_max".format(metric))
+ metrics_stats.append("{}_avg".format(metric))
+
+ metrics_stats.append("{}_compound_min".format(metric))
+ metrics_stats.append("{}_compound_max".format(metric))
+ metrics_stats.append("{}_compound_avg".format(metric))
+
+ columns = (
+ [
+ "layer_id",
+ "layer_type",
+ "N",
+ "M",
+ "layer_count",
+ "slice",
+ "slice_count",
+ "level",
+ "comment",
+ ]
+ + [*metrics]
+ + metrics_stats
+ )
+
+ metrics_values = {}
+ metrics_values_compound = {}
+
+ for metric in metrics:
+ metrics_values[metric] = []
+ metrics_values_compound[metric] = []
+
+ layer_count = 0
+ for layer_id, result in results.items():
+ layer_count += 1
+
+ layer_type = np.NAN
+ if "layer_type" in result:
+ layer_type = str(result["layer_type"]).replace("LAYER_TYPE.", "")
+
+ compounds = {} # temp var
+ for metric in metrics:
+ compounds[metric] = []
+
+ slice_count, Ntotal, Mtotal = 0, 0, 0
+ for slice_id, summary in result.items():
+ if not str(slice_id).isdigit():
+ continue
+ slice_count += 1
+
+ N = np.NAN
+ if "N" in summary:
+ N = summary["N"]
+ Ntotal += N
+
+ M = np.NAN
+ if "M" in summary:
+ M = summary["M"]
+ Mtotal += M
+
+ data = {
+ "layer_id": layer_id,
+ "layer_type": layer_type,
+ "N": N,
+ "M": M,
+ "slice": slice_id,
+ "level": "SLICE",
+ "comment": "Slice level",
+ }
+ for metric in metrics:
+ if metric in summary:
+ value = summary[metric]
+ if value is not None:
+ metrics_values[metric].append(value)
+ compounds[metric].append(value)
+ data[metric] = value
+
+ data = {
+ "layer_id": layer_id,
+ "layer_type": layer_type,
+ "N": Ntotal,
+ "M": Mtotal,
+ "slice_count": slice_count,
+ "level": "LAYER",
+ "comment": "Layer level",
+ }
+ # Compute the compound value over the slices
+ for metric, value in compounds.items():
+ count = len(value)
+ if count == 0:
+ continue
+
+ compound = np.mean(value)
+ metrics_values_compound[metric].append(compound)
+ data[metric] = compound
+
+ data = {"layer_count": layer_count, "level": "NETWORK", "comment": "Network Level"}
+ for metric, metric_name in metrics.items():
+ if metric not in metrics_values or len(metrics_values[metric]) == 0:
+ continue
+
+ values = metrics_values[metric]
+ minimum = min(values)
+ maximum = max(values)
+ avg = np.mean(values)
+ final_summary[metric] = avg
+ # print("{}: min: {}, max: {}, avg: {}".format(metric_name, minimum, maximum, avg))
+ data["{}_min".format(metric)] = minimum
+ data["{}_max".format(metric)] = maximum
+ data["{}_avg".format(metric)] = avg
+
+ values = metrics_values_compound[metric]
+ minimum = min(values)
+ maximum = max(values)
+ avg = np.mean(values)
+ final_summary["{}_compound".format(metric)] = avg
+ # print("{} compound: min: {}, max: {}, avg: {}".format(metric_name, minimum, maximum, avg))
+ data["{}_compound_min".format(metric)] = minimum
+ data["{}_compound_max".format(metric)] = maximum
+ data["{}_compound_avg".format(metric)] = avg
+
+ return final_summary
+
+
+def analyze(
+ model: nn.Module,
+ min_size=50,
+ max_size=0,
+ alphas: bool = False,
+ lognorms: bool = True,
+ spectralnorms: bool = False,
+ softranks: bool = False,
+ normalize: bool = False,
+ glorot_fix: bool = False,
+):
+ """
+ Analyze the weight matrices of a model.
+ :param model: A PyTorch model
+ :param min_size: The minimum weight matrix size to analyze.
+ :param max_size: The maximum weight matrix size to analyze (0 = no limit).
+ :param alphas: Compute the power laws (alpha) of the weight matrices.
+ Time consuming so disabled by default (use lognorm if you want speed)
+ :param lognorms: Compute the log norms of the weight matrices.
+ :param spectralnorms: Compute the spectral norm (max eigenvalue) of the weight matrices.
+ :param softranks: Compute the soft norm (i.e. StableRank) of the weight matrices.
+ :param normalize: Normalize or not.
+ :param glorot_fix:
+ :return: (a dict of all layers' results, a dict of the summarized info)
+ """
+ names, modules = [], []
+ for name, module in model.named_modules():
+ if isinstance(module, available_module_types()):
+ names.append(name)
+ modules.append(module)
+ # print('There are {:} layers to be analyzed in this model.'.format(len(modules)))
+ all_results = OrderedDict()
+ for index, module in enumerate(modules):
+ if isinstance(module, nn.Linear):
+ weights = [module.weight.cpu().detach().numpy()]
+ else:
+ weights = get_conv2D_Wmats(module.weight.cpu().detach().numpy())
+ results = analyze_weights(
+ weights,
+ min_size,
+ max_size,
+ alphas,
+ lognorms,
+ spectralnorms,
+ softranks,
+ normalize,
+ glorot_fix,
+ )
+ results["id"] = index
+ results["type"] = type(module)
+ all_results[index] = results
+ summary = compute_details(all_results)
+ return all_results, summary
diff --git a/AutoDL-Projects/xautodl/xlayers/__init__.py b/AutoDL-Projects/xautodl/xlayers/__init__.py
new file mode 100644
index 0000000..41d4b61
--- /dev/null
+++ b/AutoDL-Projects/xautodl/xlayers/__init__.py
@@ -0,0 +1,7 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2019.01 #
+#####################################################
+# This file is expected to be self-contained, expect
+# for importing from spaces to include search space.
+#####################################################
+from .super_core import *
diff --git a/AutoDL-Projects/xautodl/xlayers/misc_utils.py b/AutoDL-Projects/xautodl/xlayers/misc_utils.py
new file mode 100644
index 0000000..086f3d7
--- /dev/null
+++ b/AutoDL-Projects/xautodl/xlayers/misc_utils.py
@@ -0,0 +1,154 @@
+# borrowed from https://github.com/arogozhnikov/einops/blob/master/einops/parsing.py
+import warnings
+import keyword
+from typing import List
+
+
+class AnonymousAxis:
+ """Important thing: all instances of this class are not equal to each other"""
+
+ def __init__(self, value: str):
+ self.value = int(value)
+ if self.value <= 1:
+ if self.value == 1:
+ raise EinopsError(
+ "No need to create anonymous axis of length 1. Report this as an issue"
+ )
+ else:
+ raise EinopsError(
+ "Anonymous axis should have positive length, not {}".format(
+ self.value
+ )
+ )
+
+ def __repr__(self):
+ return "{}-axis".format(str(self.value))
+
+
+class ParsedExpression:
+ """
+ non-mutable structure that contains information about one side of expression (e.g. 'b c (h w)')
+ and keeps some information important for downstream
+ """
+
+ def __init__(self, expression):
+ self.identifiers = set()
+ # that's axes like 2, 3 or 5. Axes with size 1 are exceptional and replaced with empty composition
+ self.has_non_unitary_anonymous_axes = False
+ # composition keeps structure of composite axes, see how different corner cases are handled in tests
+ self.composition = []
+ if "." in expression:
+ raise ValueError("Does not support . in the expression.")
+
+ bracket_group = None
+
+ def add_axis_name(x):
+ if x is not None:
+ if x in self.identifiers:
+ raise ValueError(
+ 'Indexing expression contains duplicate dimension "{}"'.format(
+ x
+ )
+ )
+ is_number = str.isdecimal(x)
+ if is_number and int(x) == 1:
+ # handling the case of anonymous axis of length 1
+ if bracket_group is None:
+ self.composition.append([])
+ else:
+ pass # no need to think about 1s inside parenthesis
+ return
+ is_axis_name, reason = self.check_axis_name(x, return_reason=True)
+ if not (is_number or is_axis_name):
+ raise ValueError(
+ "Invalid axis identifier: {}\n{}".format(x, reason)
+ )
+ if is_number:
+ x = AnonymousAxis(x)
+ self.identifiers.add(x)
+ if is_number:
+ self.has_non_unitary_anonymous_axes = True
+ if bracket_group is None:
+ self.composition.append([x])
+ else:
+ bracket_group.append(x)
+
+ current_identifier = None
+ for char in expression:
+ if char in "() ":
+ add_axis_name(current_identifier)
+ current_identifier = None
+ if char == "(":
+ if bracket_group is not None:
+ raise ValueError(
+ "Axis composition is one-level (brackets inside brackets not allowed)"
+ )
+ bracket_group = []
+ elif char == ")":
+ if bracket_group is None:
+ raise ValueError("Brackets are not balanced")
+ self.composition.append(bracket_group)
+ bracket_group = None
+ elif str.isalnum(char) or char == "_":
+ if current_identifier is None:
+ current_identifier = char
+ else:
+ current_identifier += char
+ else:
+ raise ValueError("Unknown character '{}'".format(char))
+
+ if bracket_group is not None:
+ raise ValueError(
+ 'Imbalanced parentheses in expression: "{}"'.format(expression)
+ )
+ add_axis_name(current_identifier)
+
+ def flat_axes_order(self) -> List:
+ result = []
+ for composed_axis in self.composition:
+ assert isinstance(composed_axis, list), "does not work with ellipsis"
+ for axis in composed_axis:
+ result.append(axis)
+ return result
+
+ def has_composed_axes(self) -> bool:
+ # this will ignore 1 inside brackets
+ for axes in self.composition:
+ if isinstance(axes, list) and len(axes) > 1:
+ return True
+ return False
+
+ @staticmethod
+ def check_axis_name(name: str, return_reason=False):
+ """
+ Valid axes names are python identifiers except keywords,
+ and additionally should not start or end with underscore
+ """
+ if not str.isidentifier(name):
+ result = False, "not a valid python identifier"
+ elif name[0] == "_" or name[-1] == "_":
+ result = False, "axis name should should not start or end with underscore"
+ else:
+ if keyword.iskeyword(name):
+ warnings.warn(
+ "It is discouraged to use axes names that are keywords: {}".format(
+ name
+ ),
+ RuntimeWarning,
+ )
+ if name in ["axis"]:
+ warnings.warn(
+ "It is discouraged to use 'axis' as an axis name "
+ "and will raise an error in future",
+ FutureWarning,
+ )
+ result = True, None
+ if return_reason:
+ return result
+ else:
+ return result[0]
+
+ def __repr__(self) -> str:
+ return "{name}({composition})".format(
+ name=self.__class__.__name__, composition=self.composition
+ )
diff --git a/AutoDL-Projects/xautodl/xlayers/super_activations.py b/AutoDL-Projects/xautodl/xlayers/super_activations.py
new file mode 100644
index 0000000..312917f
--- /dev/null
+++ b/AutoDL-Projects/xautodl/xlayers/super_activations.py
@@ -0,0 +1,124 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.03 #
+#####################################################
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+
+import math
+from typing import Optional, Callable
+
+from xautodl import spaces
+from .super_module import SuperModule
+from .super_module import IntSpaceType
+from .super_module import BoolSpaceType
+
+
+class SuperReLU(SuperModule):
+ """Applies a the rectified linear unit function element-wise."""
+
+ def __init__(self, inplace: bool = False) -> None:
+ super(SuperReLU, self).__init__()
+ self._inplace = inplace
+
+ @property
+ def abstract_search_space(self):
+ return spaces.VirtualNode(id(self))
+
+ def forward_candidate(self, input: torch.Tensor) -> torch.Tensor:
+ return self.forward_raw(input)
+
+ def forward_raw(self, input: torch.Tensor) -> torch.Tensor:
+ return F.relu(input, inplace=self._inplace)
+
+ def forward_with_container(self, input, container, prefix=[]):
+ return self.forward_raw(input)
+
+ def extra_repr(self) -> str:
+ return "inplace=True" if self._inplace else ""
+
+
+class SuperGELU(SuperModule):
+ """Applies a the Gaussian Error Linear Units function element-wise."""
+
+ def __init__(self) -> None:
+ super(SuperGELU, self).__init__()
+
+ @property
+ def abstract_search_space(self):
+ return spaces.VirtualNode(id(self))
+
+ def forward_candidate(self, input: torch.Tensor) -> torch.Tensor:
+ return self.forward_raw(input)
+
+ def forward_raw(self, input: torch.Tensor) -> torch.Tensor:
+ return F.gelu(input)
+
+ def forward_with_container(self, input, container, prefix=[]):
+ return self.forward_raw(input)
+
+
+class SuperSigmoid(SuperModule):
+ """Applies a the Sigmoid function element-wise."""
+
+ def __init__(self) -> None:
+ super(SuperSigmoid, self).__init__()
+
+ @property
+ def abstract_search_space(self):
+ return spaces.VirtualNode(id(self))
+
+ def forward_candidate(self, input: torch.Tensor) -> torch.Tensor:
+ return self.forward_raw(input)
+
+ def forward_raw(self, input: torch.Tensor) -> torch.Tensor:
+ return torch.sigmoid(input)
+
+ def forward_with_container(self, input, container, prefix=[]):
+ return self.forward_raw(input)
+
+
+class SuperLeakyReLU(SuperModule):
+ """https://pytorch.org/docs/stable/_modules/torch/nn/modules/activation.html#LeakyReLU"""
+
+ def __init__(self, negative_slope: float = 1e-2, inplace: bool = False) -> None:
+ super(SuperLeakyReLU, self).__init__()
+ self._negative_slope = negative_slope
+ self._inplace = inplace
+
+ @property
+ def abstract_search_space(self):
+ return spaces.VirtualNode(id(self))
+
+ def forward_candidate(self, input: torch.Tensor) -> torch.Tensor:
+ return self.forward_raw(input)
+
+ def forward_raw(self, input: torch.Tensor) -> torch.Tensor:
+ return F.leaky_relu(input, self._negative_slope, self._inplace)
+
+ def forward_with_container(self, input, container, prefix=[]):
+ return self.forward_raw(input)
+
+ def extra_repr(self) -> str:
+ inplace_str = "inplace=True" if self._inplace else ""
+ return "negative_slope={}{}".format(self._negative_slope, inplace_str)
+
+
+class SuperTanh(SuperModule):
+ """Applies a the Tanh function element-wise."""
+
+ def __init__(self) -> None:
+ super(SuperTanh, self).__init__()
+
+ @property
+ def abstract_search_space(self):
+ return spaces.VirtualNode(id(self))
+
+ def forward_candidate(self, input: torch.Tensor) -> torch.Tensor:
+ return self.forward_raw(input)
+
+ def forward_raw(self, input: torch.Tensor) -> torch.Tensor:
+ return torch.tanh(input)
+
+ def forward_with_container(self, input, container, prefix=[]):
+ return self.forward_raw(input)
diff --git a/AutoDL-Projects/xautodl/xlayers/super_attention.py b/AutoDL-Projects/xautodl/xlayers/super_attention.py
new file mode 100644
index 0000000..a032a14
--- /dev/null
+++ b/AutoDL-Projects/xautodl/xlayers/super_attention.py
@@ -0,0 +1,341 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.03 #
+#####################################################
+import math
+from typing import Optional, Text
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+
+
+from xautodl import spaces
+from .super_module import SuperModule
+from .super_module import IntSpaceType
+from .super_module import BoolSpaceType
+from .super_dropout import SuperDropout, SuperDrop
+from .super_linear import SuperLinear
+
+
+class SuperSelfAttention(SuperModule):
+ """The super model for attention layer."""
+
+ def __init__(
+ self,
+ input_dim: IntSpaceType,
+ proj_dim: Optional[IntSpaceType],
+ num_heads: IntSpaceType,
+ qkv_bias: BoolSpaceType = False,
+ attn_drop: Optional[float] = None,
+ proj_drop: Optional[float] = None,
+ use_mask=False,
+ ):
+ super(SuperSelfAttention, self).__init__()
+ self._input_dim = input_dim
+ self._proj_dim = proj_dim
+ self._num_heads = num_heads
+ self._qkv_bias = qkv_bias
+ self._use_mask = use_mask
+ self._infinity = 1e9
+
+ mul_head_dim = (
+ spaces.get_max(input_dim) // spaces.get_min(num_heads)
+ ) * spaces.get_min(num_heads)
+ assert mul_head_dim == spaces.get_max(input_dim)
+ self.q_fc = SuperLinear(input_dim, input_dim, bias=qkv_bias)
+ self.k_fc = SuperLinear(input_dim, input_dim, bias=qkv_bias)
+ self.v_fc = SuperLinear(input_dim, input_dim, bias=qkv_bias)
+
+ self.attn_drop = SuperDrop(attn_drop or 0.0, [-1, -1, -1, -1], recover=True)
+ if proj_dim is not None:
+ self.proj = SuperLinear(input_dim, proj_dim)
+ self.proj_drop = SuperDropout(proj_drop or 0.0)
+ else:
+ self.proj = None
+
+ @property
+ def num_heads(self):
+ return spaces.get_max(self._num_heads)
+
+ @property
+ def input_dim(self):
+ return spaces.get_max(self._input_dim)
+
+ @property
+ def proj_dim(self):
+ return spaces.get_max(self._proj_dim)
+
+ @property
+ def abstract_search_space(self):
+ root_node = spaces.VirtualNode(id(self))
+ space_q = self.q_fc.abstract_search_space
+ space_k = self.k_fc.abstract_search_space
+ space_v = self.v_fc.abstract_search_space
+ if not spaces.is_determined(self._num_heads):
+ root_node.append("_num_heads", self._num_heads.abstract(reuse_last=True))
+ if not spaces.is_determined(space_q):
+ root_node.append("q_fc", space_q)
+ if not spaces.is_determined(space_k):
+ root_node.append("k_fc", space_k)
+ if not spaces.is_determined(space_v):
+ root_node.append("v_fc", space_v)
+ if self.proj is not None:
+ space_proj = self.proj.abstract_search_space
+ if not spaces.is_determined(space_proj):
+ root_node.append("proj", space_proj)
+ return root_node
+
+ def apply_candidate(self, abstract_child: spaces.VirtualNode):
+ super(SuperSelfAttention, self).apply_candidate(abstract_child)
+ if "q_fc" in abstract_child:
+ self.q_fc.apply_candidate(abstract_child["q_fc"])
+ if "k_fc" in abstract_child:
+ self.k_fc.apply_candidate(abstract_child["k_fc"])
+ if "v_fc" in abstract_child:
+ self.v_fc.apply_candidate(abstract_child["v_fc"])
+ if "proj" in abstract_child:
+ self.proj.apply_candidate(abstract_child["proj"])
+
+ def forward_qkv(self, input: torch.Tensor, num_head: int) -> torch.Tensor:
+ B, N, C = input.shape
+ q = self.q_fc(input)
+ k = self.k_fc(input)
+ v = self.v_fc(input)
+ if num_head > C:
+ raise ValueError("Invalid num_head [{:}] vs C [{:}]".format(num_head, C))
+ head_dim = C // num_head
+ # process the first [num_head * head_dim] part
+ q_v1 = (
+ q[:, :, : num_head * head_dim]
+ .reshape(B, N, num_head, head_dim)
+ .permute(0, 2, 1, 3)
+ )
+ k_v1 = (
+ k[:, :, : num_head * head_dim]
+ .reshape(B, N, num_head, head_dim)
+ .permute(0, 2, 1, 3)
+ )
+ v_v1 = (
+ v[:, :, : num_head * head_dim]
+ .reshape(B, N, num_head, head_dim)
+ .permute(0, 2, 1, 3)
+ )
+ attn_v1 = (q_v1 @ k_v1.transpose(-2, -1)) * math.sqrt(head_dim)
+ if self._use_mask:
+ mask = torch.triu(
+ torch.ones((N, N), dtype=torch.bool, device=input.device), 1
+ )
+ mask = torch.unsqueeze(torch.unsqueeze(mask, dim=0), dim=0)
+ attn_v1 = attn_v1.masked_fill(mask, -self._infinity)
+ attn_v1 = attn_v1.softmax(dim=-1) # B * #head * N * N
+ attn_v1 = self.attn_drop(attn_v1)
+ feats_v1 = (attn_v1 @ v_v1).permute(0, 2, 1, 3).reshape(B, N, -1)
+ if C == head_dim * num_head:
+ feats = feats_v1
+ else: # The channels can not be divided by num_head, the remainder forms an additional head
+ q_v2 = q[:, :, num_head * head_dim :]
+ k_v2 = k[:, :, num_head * head_dim :]
+ v_v2 = v[:, :, num_head * head_dim :]
+ attn_v2 = (q_v2 @ k_v2.transpose(-2, -1)) * math.sqrt(q_v2.shape[-1])
+ attn_v2 = attn_v2.softmax(dim=-1)
+ attn_v2 = self.attn_drop(attn_v2)
+ feats_v2 = attn_v2 @ v_v2
+ feats = torch.cat([feats_v1, feats_v2], dim=-1)
+ return feats
+
+ def forward_candidate(self, input: torch.Tensor) -> torch.Tensor:
+ # check the num_heads:
+ if not spaces.is_determined(self._num_heads):
+ num_heads = self.abstract_child["_num_heads"].value
+ else:
+ num_heads = spaces.get_determined_value(self._num_heads)
+ feats = self.forward_qkv(input, num_heads)
+ if self.proj is None:
+ return feats
+ else:
+ outs = self.proj(feats)
+ outs = self.proj_drop(outs)
+ return outs
+
+ def forward_raw(self, input: torch.Tensor) -> torch.Tensor:
+ feats = self.forward_qkv(input, self.num_heads)
+ if self.proj is None:
+ return feats
+ else:
+ outs = self.proj(feats)
+ outs = self.proj_drop(outs)
+ return outs
+
+ def extra_repr(self) -> str:
+ return (
+ "input_dim={:}, proj_dim={:}, num_heads={:}, mask={:}, infinity={:}".format(
+ self._input_dim,
+ self._proj_dim,
+ self._num_heads,
+ self._use_mask,
+ self._infinity,
+ )
+ )
+
+
+class SuperQKVAttention(SuperModule):
+ """The super model for attention layer."""
+
+ def __init__(
+ self,
+ in_q_dim: IntSpaceType,
+ in_k_dim: IntSpaceType,
+ in_v_dim: IntSpaceType,
+ proj_dim: IntSpaceType,
+ num_heads: IntSpaceType,
+ qkv_bias: BoolSpaceType = False,
+ attn_drop: Optional[float] = None,
+ proj_drop: Optional[float] = None,
+ ):
+ super(SuperQKVAttention, self).__init__()
+ self._in_v_dim = in_v_dim
+ self._in_q_dim = in_q_dim
+ self._in_k_dim = in_k_dim
+ self._proj_dim = proj_dim
+ self._num_heads = num_heads
+ self._qkv_bias = qkv_bias
+
+ self.q_fc = SuperLinear(in_q_dim, proj_dim, bias=qkv_bias)
+ self.k_fc = SuperLinear(in_k_dim, proj_dim, bias=qkv_bias)
+ self.v_fc = SuperLinear(in_v_dim, proj_dim, bias=qkv_bias)
+
+ self.attn_drop = nn.Dropout(attn_drop or 0.0)
+ self.proj = SuperLinear(proj_dim, proj_dim)
+ self.proj_drop = nn.Dropout(proj_drop or 0.0)
+ self._infinity = 1e9
+
+ @property
+ def num_heads(self):
+ return spaces.get_max(self._num_heads)
+
+ @property
+ def in_v_dim(self):
+ return spaces.get_max(self._in_v_dim)
+
+ @property
+ def in_q_dim(self):
+ return spaces.get_max(self._in_q_dim)
+
+ @property
+ def in_k_dim(self):
+ return spaces.get_max(self._in_k_dim)
+
+ @property
+ def proj_dim(self):
+ return spaces.get_max(self._proj_dim)
+
+ @property
+ def abstract_search_space(self):
+ root_node = spaces.VirtualNode(id(self))
+ space_q = self.q_fc.abstract_search_space
+ space_k = self.k_fc.abstract_search_space
+ space_v = self.v_fc.abstract_search_space
+ space_proj = self.proj.abstract_search_space
+ if not spaces.is_determined(self._num_heads):
+ root_node.append("_num_heads", self._num_heads.abstract(reuse_last=True))
+ if not spaces.is_determined(space_q):
+ root_node.append("q_fc", space_q)
+ if not spaces.is_determined(space_k):
+ root_node.append("k_fc", space_k)
+ if not spaces.is_determined(space_v):
+ root_node.append("v_fc", space_v)
+ if not spaces.is_determined(space_proj):
+ root_node.append("proj", space_proj)
+ return root_node
+
+ def apply_candidate(self, abstract_child: spaces.VirtualNode):
+ super(SuperQKVAttention, self).apply_candidate(abstract_child)
+ if "q_fc" in abstract_child:
+ self.q_fc.apply_candidate(abstract_child["q_fc"])
+ if "k_fc" in abstract_child:
+ self.k_fc.apply_candidate(abstract_child["k_fc"])
+ if "v_fc" in abstract_child:
+ self.v_fc.apply_candidate(abstract_child["v_fc"])
+ if "proj" in abstract_child:
+ self.proj.apply_candidate(abstract_child["proj"])
+
+ def forward_qkv(
+ self, q_tensor, k_tensor, v_tensor, num_head: int, mask=None
+ ) -> torch.Tensor:
+ q = self.q_fc(q_tensor)
+ B, N, C = q.shape
+
+ k = self.k_fc(k_tensor)
+ B0, S, _ = k.shape
+
+ v = self.v_fc(v_tensor)
+ assert B0 == v.shape[0] and S == v.shape[1]
+
+ head_dim = C // num_head
+ if num_head > C:
+ raise ValueError("Invalid num_head [{:}] vs C [{:}]".format(num_head, C))
+ q_v1 = (
+ q[:, :, : num_head * head_dim]
+ .reshape(B, N, num_head, head_dim)
+ .permute(0, 2, 1, 3)
+ )
+ k_v1 = (
+ k[:, :, : num_head * head_dim]
+ .reshape(B0, S, num_head, head_dim)
+ .permute(0, 2, 1, 3)
+ )
+ # compute the attention map
+ attn_v1 = (q_v1 @ k_v1.transpose(-2, -1)) * math.sqrt(head_dim)
+ if mask is not None:
+ mask = torch.unsqueeze(mask, dim=1)
+ attn_v1 = attn_v1.masked_fill(mask, -self._infinity)
+ attn_v1 = attn_v1.softmax(dim=-1) # B * #head * N * S
+ attn_v1 = self.attn_drop(attn_v1)
+
+ v_v1 = (
+ v[:, :, : num_head * head_dim]
+ .reshape(B0, S, num_head, head_dim)
+ .permute(0, 2, 1, 3)
+ )
+ feats_v1 = (attn_v1 @ v_v1).permute(0, 2, 1, 3).reshape(B, N, -1)
+ # process the first [num_head * head_dim] part
+ if C == head_dim * num_head:
+ feats = feats_v1
+ else: # The channels can not be divided by num_head, the remainder forms an additional head
+ # [might have bugs, did not check yet]
+ q_v2 = q[:, :, num_head * head_dim :]
+ k_v2 = k[:, :, num_head * head_dim :]
+ v_v2 = v[:, :, num_head * head_dim :]
+ attn_v2 = (q_v2 @ k_v2.transpose(-2, -1)) * math.sqrt(q_v2.shape[-1])
+ attn_v2 = attn_v2.softmax(dim=-1)
+ attn_v2 = self.attn_drop(attn_v2)
+ feats_v2 = attn_v2 @ v_v2
+ feats = torch.cat([feats_v1, feats_v2], dim=-1)
+ return feats
+
+ def forward_candidate(
+ self, q_tensor, k_tensor, v_tensor, mask=None
+ ) -> torch.Tensor:
+ # check the num_heads:
+ if not spaces.is_determined(self._num_heads):
+ num_heads = self.abstract_child["_num_heads"].value
+ else:
+ num_heads = spaces.get_determined_value(self._num_heads)
+ feats = self.forward_qkv(q_tensor, k_tensor, v_tensor, num_heads, mask)
+ outs = self.proj(feats)
+ outs = self.proj_drop(outs)
+ return outs
+
+ def forward_raw(self, q_tensor, k_tensor, v_tensor, mask=None) -> torch.Tensor:
+ feats = self.forward_qkv(q_tensor, k_tensor, v_tensor, self.num_heads, mask)
+ outs = self.proj(feats)
+ outs = self.proj_drop(outs)
+ return outs
+
+ def extra_repr(self) -> str:
+ return "input_dim={:}, proj_dim={:}, num_heads={:}, infinity={:}".format(
+ (self.in_q_dim, self.in_k_dim, self.in_v_dim),
+ self._proj_dim,
+ self._num_heads,
+ self._infinity,
+ )
diff --git a/AutoDL-Projects/xautodl/xlayers/super_attention_v2.py b/AutoDL-Projects/xautodl/xlayers/super_attention_v2.py
new file mode 100644
index 0000000..4b4437a
--- /dev/null
+++ b/AutoDL-Projects/xautodl/xlayers/super_attention_v2.py
@@ -0,0 +1,113 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.03 #
+#####################################################
+import math
+from typing import Optional, Text
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+
+
+from xautodl import spaces
+from .super_module import SuperModule
+from .super_module import IntSpaceType
+from .super_module import BoolSpaceType
+from .super_linear import SuperLinear
+
+
+class SuperQKVAttentionV2(SuperModule):
+ """The super model for attention layer."""
+
+ def __init__(
+ self,
+ qk_att_dim: int,
+ in_v_dim: int,
+ hidden_dim: int,
+ num_heads: int,
+ proj_dim: int,
+ qkv_bias: bool = False,
+ attn_drop: Optional[float] = None,
+ proj_drop: Optional[float] = None,
+ ):
+ super(SuperQKVAttentionV2, self).__init__()
+ self._in_v_dim = in_v_dim
+ self._qk_att_dim = qk_att_dim
+ self._proj_dim = proj_dim
+ self._hidden_dim = hidden_dim
+ self._num_heads = num_heads
+ self._qkv_bias = qkv_bias
+
+ self.qk_fc = SuperLinear(qk_att_dim, num_heads, bias=qkv_bias)
+ self.v_fc = SuperLinear(in_v_dim, hidden_dim * num_heads, bias=qkv_bias)
+
+ self.attn_drop = nn.Dropout(attn_drop or 0.0)
+ self.proj = SuperLinear(hidden_dim * num_heads, proj_dim)
+ self.proj_drop = nn.Dropout(proj_drop or 0.0)
+ self._infinity = 1e9
+
+ @property
+ def num_heads(self):
+ return spaces.get_max(self._num_heads)
+
+ @property
+ def in_v_dim(self):
+ return spaces.get_max(self._in_v_dim)
+
+ @property
+ def qk_att_dim(self):
+ return spaces.get_max(self._qk_att_dim)
+
+ @property
+ def hidden_dim(self):
+ return spaces.get_max(self._hidden_dim)
+
+ @property
+ def proj_dim(self):
+ return spaces.get_max(self._proj_dim)
+
+ @property
+ def abstract_search_space(self):
+ root_node = spaces.VirtualNode(id(self))
+ raise NotImplementedError
+
+ def apply_candidate(self, abstract_child: spaces.VirtualNode):
+ super(SuperQKVAttentionV2, self).apply_candidate(abstract_child)
+ raise NotImplementedError
+
+ def forward_qkv(
+ self, qk_att_tensor, v_tensor, num_head: int, mask=None
+ ) -> torch.Tensor:
+ qk_att = self.qk_fc(qk_att_tensor)
+ B, N, S, _ = qk_att.shape
+ assert _ == num_head
+ attn_v1 = qk_att.permute(0, 3, 1, 2)
+ if mask is not None:
+ mask = torch.unsqueeze(mask, dim=1)
+ attn_v1 = attn_v1.masked_fill(mask, -self._infinity)
+ attn_v1 = attn_v1.softmax(dim=-1) # B * #head * N * S
+ attn_v1 = self.attn_drop(attn_v1)
+
+ v = self.v_fc(v_tensor)
+ B0, _, _ = v.shape
+ v_v1 = v.reshape(B0, S, num_head, -1).permute(0, 2, 1, 3)
+ feats_v1 = (attn_v1 @ v_v1).permute(0, 2, 1, 3).reshape(B, N, -1)
+ return feats_v1
+
+ def forward_candidate(self, qk_att_tensor, v_tensor, mask=None) -> torch.Tensor:
+ return self.forward_raw(qk_att_tensor, v_tensor, mask)
+
+ def forward_raw(self, qk_att_tensor, v_tensor, mask=None) -> torch.Tensor:
+ feats = self.forward_qkv(qk_att_tensor, v_tensor, self.num_heads, mask)
+ outs = self.proj(feats)
+ outs = self.proj_drop(outs)
+ return outs
+
+ def extra_repr(self) -> str:
+ return "input_dim={:}, hidden_dim={:}, proj_dim={:}, num_heads={:}, infinity={:}".format(
+ (self.qk_att_dim, self.in_v_dim),
+ self._hidden_dim,
+ self._proj_dim,
+ self._num_heads,
+ self._infinity,
+ )
diff --git a/AutoDL-Projects/xautodl/xlayers/super_container.py b/AutoDL-Projects/xautodl/xlayers/super_container.py
new file mode 100644
index 0000000..56b9c91
--- /dev/null
+++ b/AutoDL-Projects/xautodl/xlayers/super_container.py
@@ -0,0 +1,120 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.03 #
+#####################################################
+import torch
+
+from itertools import islice
+import operator
+
+from collections import OrderedDict
+from typing import Optional, Union, Callable, TypeVar, Iterator
+
+from xautodl import spaces
+from .super_module import SuperModule
+
+
+T = TypeVar("T", bound=SuperModule)
+
+
+class SuperSequential(SuperModule):
+ """A sequential container wrapped with 'Super' ability.
+
+ Modules will be added to it in the order they are passed in the constructor.
+ Alternatively, an ordered dict of modules can also be passed in.
+ To make it easier to understand, here is a small example::
+ # Example of using Sequential
+ model = SuperSequential(
+ nn.Conv2d(1,20,5),
+ nn.ReLU(),
+ nn.Conv2d(20,64,5),
+ nn.ReLU()
+ )
+ # Example of using Sequential with OrderedDict
+ model = nn.Sequential(OrderedDict([
+ ('conv1', nn.Conv2d(1,20,5)),
+ ('relu1', nn.ReLU()),
+ ('conv2', nn.Conv2d(20,64,5)),
+ ('relu2', nn.ReLU())
+ ]))
+ """
+
+ def __init__(self, *args):
+ super(SuperSequential, self).__init__()
+ if len(args) == 1 and isinstance(args[0], OrderedDict):
+ for key, module in args[0].items():
+ self.add_module(key, module)
+ else:
+ if not isinstance(args, (list, tuple)):
+ raise ValueError("Invalid input type: {:}".format(type(args)))
+ for idx, module in enumerate(args):
+ self.add_module(str(idx), module)
+
+ def _get_item_by_idx(self, iterator, idx) -> T:
+ """Get the idx-th item of the iterator"""
+ size = len(self)
+ idx = operator.index(idx)
+ if not -size <= idx < size:
+ raise IndexError("index {} is out of range".format(idx))
+ idx %= size
+ return next(islice(iterator, idx, None))
+
+ def __getitem__(self, idx) -> Union["SuperSequential", T]:
+ if isinstance(idx, slice):
+ return self.__class__(OrderedDict(list(self._modules.items())[idx]))
+ else:
+ return self._get_item_by_idx(self._modules.values(), idx)
+
+ def __setitem__(self, idx: int, module: SuperModule) -> None:
+ key: str = self._get_item_by_idx(self._modules.keys(), idx)
+ return setattr(self, key, module)
+
+ def __delitem__(self, idx: Union[slice, int]) -> None:
+ if isinstance(idx, slice):
+ for key in list(self._modules.keys())[idx]:
+ delattr(self, key)
+ else:
+ key = self._get_item_by_idx(self._modules.keys(), idx)
+ delattr(self, key)
+
+ def __len__(self) -> int:
+ return len(self._modules)
+
+ def __dir__(self):
+ keys = super(SuperSequential, self).__dir__()
+ keys = [key for key in keys if not key.isdigit()]
+ return keys
+
+ def __iter__(self) -> Iterator[SuperModule]:
+ return iter(self._modules.values())
+
+ @property
+ def abstract_search_space(self):
+ root_node = spaces.VirtualNode(id(self))
+ for index, module in enumerate(self):
+ if not isinstance(module, SuperModule):
+ continue
+ space = module.abstract_search_space
+ if not spaces.is_determined(space):
+ root_node.append(str(index), space)
+ return root_node
+
+ def apply_candidate(self, abstract_child: spaces.VirtualNode):
+ super(SuperSequential, self).apply_candidate(abstract_child)
+ for index, module in enumerate(self):
+ if str(index) in abstract_child:
+ module.apply_candidate(abstract_child[str(index)])
+
+ def forward_candidate(self, input):
+ return self.forward_raw(input)
+
+ def forward_raw(self, input):
+ for module in self:
+ input = module(input)
+ return input
+
+ def forward_with_container(self, input, container, prefix=[]):
+ for index, module in enumerate(self):
+ input = module.forward_with_container(
+ input, container, prefix + [str(index)]
+ )
+ return input
diff --git a/AutoDL-Projects/xautodl/xlayers/super_core.py b/AutoDL-Projects/xautodl/xlayers/super_core.py
new file mode 100644
index 0000000..6dacc48
--- /dev/null
+++ b/AutoDL-Projects/xautodl/xlayers/super_core.py
@@ -0,0 +1,51 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.03 #
+#####################################################
+from .super_module import SuperRunMode
+from .super_module import IntSpaceType
+from .super_module import LayerOrder
+
+from .super_module import SuperModule
+from .super_container import SuperSequential
+from .super_linear import SuperLinear
+from .super_linear import SuperMLPv1, SuperMLPv2
+
+from .super_norm import SuperSimpleNorm
+from .super_norm import SuperLayerNorm1D
+from .super_norm import SuperSimpleLearnableNorm
+from .super_norm import SuperIdentity
+from .super_dropout import SuperDropout
+from .super_dropout import SuperDrop
+
+super_name2norm = {
+ "simple_norm": SuperSimpleNorm,
+ "simple_learn_norm": SuperSimpleLearnableNorm,
+ "layer_norm_1d": SuperLayerNorm1D,
+ "identity": SuperIdentity,
+}
+
+from .super_attention import SuperSelfAttention
+from .super_attention import SuperQKVAttention
+from .super_attention_v2 import SuperQKVAttentionV2
+from .super_transformer import SuperTransformerEncoderLayer
+
+from .super_activations import SuperReLU
+from .super_activations import SuperLeakyReLU
+from .super_activations import SuperTanh
+from .super_activations import SuperGELU
+from .super_activations import SuperSigmoid
+
+super_name2activation = {
+ "relu": SuperReLU,
+ "sigmoid": SuperSigmoid,
+ "gelu": SuperGELU,
+ "leaky_relu": SuperLeakyReLU,
+ "tanh": SuperTanh,
+}
+
+
+from .super_trade_stem import SuperAlphaEBDv1
+from .super_positional_embedding import SuperDynamicPositionE
+from .super_positional_embedding import SuperPositionalEncoder
+
+from .super_rearrange import SuperReArrange
diff --git a/AutoDL-Projects/xautodl/xlayers/super_dropout.py b/AutoDL-Projects/xautodl/xlayers/super_dropout.py
new file mode 100644
index 0000000..9d14e6d
--- /dev/null
+++ b/AutoDL-Projects/xautodl/xlayers/super_dropout.py
@@ -0,0 +1,83 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.03 #
+#####################################################
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+
+import math
+from typing import Optional, Callable, Tuple
+
+from xautodl import spaces
+from .super_module import SuperModule
+from .super_module import IntSpaceType
+from .super_module import BoolSpaceType
+
+
+class SuperDropout(SuperModule):
+ """Applies a the dropout function element-wise."""
+
+ def __init__(self, p: float = 0.5, inplace: bool = False) -> None:
+ super(SuperDropout, self).__init__()
+ self._p = p
+ self._inplace = inplace
+
+ @property
+ def abstract_search_space(self):
+ return spaces.VirtualNode(id(self))
+
+ def forward_candidate(self, input: torch.Tensor) -> torch.Tensor:
+ return self.forward_raw(input)
+
+ def forward_raw(self, input: torch.Tensor) -> torch.Tensor:
+ return F.dropout(input, self._p, self.training, self._inplace)
+
+ def forward_with_container(self, input, container, prefix=[]):
+ return self.forward_raw(input)
+
+ def extra_repr(self) -> str:
+ xstr = "inplace=True" if self._inplace else ""
+ return "p={:}".format(self._p) + ", " + xstr
+
+
+class SuperDrop(SuperModule):
+ """Applies a the drop-path function element-wise."""
+
+ def __init__(self, p: float, dims: Tuple[int], recover: bool = True) -> None:
+ super(SuperDrop, self).__init__()
+ self._p = p
+ self._dims = dims
+ self._recover = recover
+
+ @property
+ def abstract_search_space(self):
+ return spaces.VirtualNode(id(self))
+
+ def forward_candidate(self, input: torch.Tensor) -> torch.Tensor:
+ return self.forward_raw(input)
+
+ def forward_raw(self, input: torch.Tensor) -> torch.Tensor:
+ if not self.training or self._p <= 0:
+ return input
+ keep_prob = 1 - self._p
+ shape = [input.shape[0]] + [
+ x if y == -1 else y for x, y in zip(input.shape[1:], self._dims)
+ ]
+ random_tensor = keep_prob + torch.rand(
+ shape, dtype=input.dtype, device=input.device
+ )
+ random_tensor.floor_() # binarize
+ if self._recover:
+ return input.div(keep_prob) * random_tensor
+ else:
+ return input * random_tensor # as masks
+
+ def forward_with_container(self, input, container, prefix=[]):
+ return self.forward_raw(input)
+
+ def extra_repr(self) -> str:
+ return (
+ "p={:}".format(self._p)
+ + ", dims={:}".format(self._dims)
+ + ", recover={:}".format(self._recover)
+ )
diff --git a/AutoDL-Projects/xautodl/xlayers/super_linear.py b/AutoDL-Projects/xautodl/xlayers/super_linear.py
new file mode 100644
index 0000000..f5e04bf
--- /dev/null
+++ b/AutoDL-Projects/xautodl/xlayers/super_linear.py
@@ -0,0 +1,310 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.03 #
+#####################################################
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+
+import math
+from typing import Optional, Callable
+
+from xautodl import spaces
+from .super_module import SuperModule
+from .super_module import IntSpaceType
+from .super_module import BoolSpaceType
+
+
+class SuperLinear(SuperModule):
+ """Applies a linear transformation to the incoming data: :math:`y = xA^T + b`"""
+
+ def __init__(
+ self,
+ in_features: IntSpaceType,
+ out_features: IntSpaceType,
+ bias: BoolSpaceType = True,
+ ) -> None:
+ super(SuperLinear, self).__init__()
+
+ # the raw input args
+ self._in_features = in_features
+ self._out_features = out_features
+ self._bias = bias
+ # weights to be optimized
+ self.register_parameter(
+ "_super_weight",
+ torch.nn.Parameter(torch.Tensor(self.out_features, self.in_features)),
+ )
+ if self.bias:
+ self.register_parameter(
+ "_super_bias", torch.nn.Parameter(torch.Tensor(self.out_features))
+ )
+ else:
+ self.register_parameter("_super_bias", None)
+ self.reset_parameters()
+
+ @property
+ def in_features(self):
+ return spaces.get_max(self._in_features)
+
+ @property
+ def out_features(self):
+ return spaces.get_max(self._out_features)
+
+ @property
+ def bias(self):
+ return spaces.has_categorical(self._bias, True)
+
+ @property
+ def abstract_search_space(self):
+ root_node = spaces.VirtualNode(id(self))
+ if not spaces.is_determined(self._in_features):
+ root_node.append(
+ "_in_features", self._in_features.abstract(reuse_last=True)
+ )
+ if not spaces.is_determined(self._out_features):
+ root_node.append(
+ "_out_features", self._out_features.abstract(reuse_last=True)
+ )
+ if not spaces.is_determined(self._bias):
+ root_node.append("_bias", self._bias.abstract(reuse_last=True))
+ return root_node
+
+ def reset_parameters(self) -> None:
+ nn.init.kaiming_uniform_(self._super_weight, a=math.sqrt(5))
+ if self.bias:
+ fan_in, _ = nn.init._calculate_fan_in_and_fan_out(self._super_weight)
+ bound = 1 / math.sqrt(fan_in)
+ nn.init.uniform_(self._super_bias, -bound, bound)
+
+ def forward_candidate(self, input: torch.Tensor) -> torch.Tensor:
+ # check inputs ->
+ if not spaces.is_determined(self._in_features):
+ expected_input_dim = self.abstract_child["_in_features"].value
+ else:
+ expected_input_dim = spaces.get_determined_value(self._in_features)
+ if input.size(-1) != expected_input_dim:
+ raise ValueError(
+ "Expect the input dim of {:} instead of {:}".format(
+ expected_input_dim, input.size(-1)
+ )
+ )
+ # create the weight matrix
+ if not spaces.is_determined(self._out_features):
+ out_dim = self.abstract_child["_out_features"].value
+ else:
+ out_dim = spaces.get_determined_value(self._out_features)
+ candidate_weight = self._super_weight[:out_dim, :expected_input_dim]
+ # create the bias matrix
+ if not spaces.is_determined(self._bias):
+ if self.abstract_child["_bias"].value:
+ candidate_bias = self._super_bias[:out_dim]
+ else:
+ candidate_bias = None
+ else:
+ if spaces.get_determined_value(self._bias):
+ candidate_bias = self._super_bias[:out_dim]
+ else:
+ candidate_bias = None
+ return F.linear(input, candidate_weight, candidate_bias)
+
+ def forward_raw(self, input: torch.Tensor) -> torch.Tensor:
+ return F.linear(input, self._super_weight, self._super_bias)
+
+ def extra_repr(self) -> str:
+ return "in_features={:}, out_features={:}, bias={:}".format(
+ self._in_features, self._out_features, self._bias
+ )
+
+ def forward_with_container(self, input, container, prefix=[]):
+ super_weight_name = ".".join(prefix + ["_super_weight"])
+ super_weight = container.query(super_weight_name)
+ super_bias_name = ".".join(prefix + ["_super_bias"])
+ if container.has(super_bias_name):
+ super_bias = container.query(super_bias_name)
+ else:
+ super_bias = None
+ return F.linear(input, super_weight, super_bias)
+
+
+class SuperMLPv1(SuperModule):
+ """An MLP layer: FC -> Activation -> Drop -> FC -> Drop."""
+
+ def __init__(
+ self,
+ in_features: IntSpaceType,
+ hidden_features: IntSpaceType,
+ out_features: IntSpaceType,
+ act_layer: Callable[[], nn.Module] = nn.GELU,
+ drop: Optional[float] = None,
+ ):
+ super(SuperMLPv1, self).__init__()
+ self._in_features = in_features
+ self._hidden_features = hidden_features
+ self._out_features = out_features
+ self._drop_rate = drop
+ self.fc1 = SuperLinear(in_features, hidden_features)
+ self.act = act_layer()
+ self.fc2 = SuperLinear(hidden_features, out_features)
+ self.drop = nn.Dropout(drop or 0.0)
+
+ @property
+ def abstract_search_space(self):
+ root_node = spaces.VirtualNode(id(self))
+ space_fc1 = self.fc1.abstract_search_space
+ space_fc2 = self.fc2.abstract_search_space
+ if not spaces.is_determined(space_fc1):
+ root_node.append("fc1", space_fc1)
+ if not spaces.is_determined(space_fc2):
+ root_node.append("fc2", space_fc2)
+ return root_node
+
+ def apply_candidate(self, abstract_child: spaces.VirtualNode):
+ super(SuperMLPv1, self).apply_candidate(abstract_child)
+ if "fc1" in abstract_child:
+ self.fc1.apply_candidate(abstract_child["fc1"])
+ if "fc2" in abstract_child:
+ self.fc2.apply_candidate(abstract_child["fc2"])
+
+ def forward_candidate(self, input: torch.Tensor) -> torch.Tensor:
+ return self.forward_raw(input)
+
+ def forward_raw(self, input: torch.Tensor) -> torch.Tensor:
+ x = self.fc1(input)
+ x = self.act(x)
+ x = self.drop(x)
+ x = self.fc2(x)
+ x = self.drop(x)
+ return x
+
+ def extra_repr(self) -> str:
+ return "in_features={:}, hidden_features={:}, out_features={:}, drop={:}, fc1 -> act -> drop -> fc2 -> drop,".format(
+ self._in_features,
+ self._hidden_features,
+ self._out_features,
+ self._drop_rate,
+ )
+
+
+class SuperMLPv2(SuperModule):
+ """An MLP layer: FC -> Activation -> Drop -> FC -> Drop."""
+
+ def __init__(
+ self,
+ in_features: IntSpaceType,
+ hidden_multiplier: IntSpaceType,
+ out_features: IntSpaceType,
+ act_layer: Callable[[], nn.Module] = nn.GELU,
+ drop: Optional[float] = None,
+ ):
+ super(SuperMLPv2, self).__init__()
+ self._in_features = in_features
+ self._hidden_multiplier = hidden_multiplier
+ self._out_features = out_features
+ self._drop_rate = drop
+
+ self._create_linear(
+ "fc1", self.in_features, int(self.in_features * self.hidden_multiplier)
+ )
+ self._create_linear(
+ "fc2", int(self.in_features * self.hidden_multiplier), self.out_features
+ )
+ self.act = act_layer()
+ self.drop = nn.Dropout(drop or 0.0)
+ self.reset_parameters()
+
+ @property
+ def in_features(self):
+ return spaces.get_max(self._in_features)
+
+ @property
+ def hidden_multiplier(self):
+ return spaces.get_max(self._hidden_multiplier)
+
+ @property
+ def out_features(self):
+ return spaces.get_max(self._out_features)
+
+ def _create_linear(self, name, inC, outC):
+ self.register_parameter(
+ "{:}_super_weight".format(name), torch.nn.Parameter(torch.Tensor(outC, inC))
+ )
+ self.register_parameter(
+ "{:}_super_bias".format(name), torch.nn.Parameter(torch.Tensor(outC))
+ )
+
+ def reset_parameters(self) -> None:
+ nn.init.kaiming_uniform_(self.fc1_super_weight, a=math.sqrt(5))
+ nn.init.kaiming_uniform_(self.fc2_super_weight, a=math.sqrt(5))
+ fan_in, _ = nn.init._calculate_fan_in_and_fan_out(self.fc1_super_weight)
+ bound = 1 / math.sqrt(fan_in)
+ nn.init.uniform_(self.fc1_super_bias, -bound, bound)
+ fan_in, _ = nn.init._calculate_fan_in_and_fan_out(self.fc2_super_weight)
+ bound = 1 / math.sqrt(fan_in)
+ nn.init.uniform_(self.fc2_super_bias, -bound, bound)
+
+ @property
+ def abstract_search_space(self):
+ root_node = spaces.VirtualNode(id(self))
+ if not spaces.is_determined(self._in_features):
+ root_node.append(
+ "_in_features", self._in_features.abstract(reuse_last=True)
+ )
+ if not spaces.is_determined(self._hidden_multiplier):
+ root_node.append(
+ "_hidden_multiplier", self._hidden_multiplier.abstract(reuse_last=True)
+ )
+ if not spaces.is_determined(self._out_features):
+ root_node.append(
+ "_out_features", self._out_features.abstract(reuse_last=True)
+ )
+ return root_node
+
+ def forward_candidate(self, input: torch.Tensor) -> torch.Tensor:
+ # check inputs ->
+ if not spaces.is_determined(self._in_features):
+ expected_input_dim = self.abstract_child["_in_features"].value
+ else:
+ expected_input_dim = spaces.get_determined_value(self._in_features)
+ if input.size(-1) != expected_input_dim:
+ raise ValueError(
+ "Expect the input dim of {:} instead of {:}".format(
+ expected_input_dim, input.size(-1)
+ )
+ )
+ # create the weight and bias matrix for fc1
+ if not spaces.is_determined(self._hidden_multiplier):
+ hmul = self.abstract_child["_hidden_multiplier"].value * expected_input_dim
+ else:
+ hmul = spaces.get_determined_value(self._hidden_multiplier)
+ hidden_dim = int(expected_input_dim * hmul)
+ _fc1_weight = self.fc1_super_weight[:hidden_dim, :expected_input_dim]
+ _fc1_bias = self.fc1_super_bias[:hidden_dim]
+ x = F.linear(input, _fc1_weight, _fc1_bias)
+ x = self.act(x)
+ x = self.drop(x)
+ # create the weight and bias matrix for fc2
+ if not spaces.is_determined(self._out_features):
+ out_dim = self.abstract_child["_out_features"].value
+ else:
+ out_dim = spaces.get_determined_value(self._out_features)
+ _fc2_weight = self.fc2_super_weight[:out_dim, :hidden_dim]
+ _fc2_bias = self.fc2_super_bias[:out_dim]
+ x = F.linear(x, _fc2_weight, _fc2_bias)
+ x = self.drop(x)
+ return x
+
+ def forward_raw(self, input: torch.Tensor) -> torch.Tensor:
+ x = F.linear(input, self.fc1_super_weight, self.fc1_super_bias)
+ x = self.act(x)
+ x = self.drop(x)
+ x = F.linear(x, self.fc2_super_weight, self.fc2_super_bias)
+ x = self.drop(x)
+ return x
+
+ def extra_repr(self) -> str:
+ return "in_features={:}, hidden_multiplier={:}, out_features={:}, drop={:}, fc1 -> act -> drop -> fc2 -> drop,".format(
+ self._in_features,
+ self._hidden_multiplier,
+ self._out_features,
+ self._drop_rate,
+ )
diff --git a/AutoDL-Projects/xautodl/xlayers/super_module.py b/AutoDL-Projects/xautodl/xlayers/super_module.py
new file mode 100644
index 0000000..0ba4b75
--- /dev/null
+++ b/AutoDL-Projects/xautodl/xlayers/super_module.py
@@ -0,0 +1,227 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.03 #
+#####################################################
+
+import os
+from pathlib import Path
+import abc
+import tempfile
+import warnings
+from typing import Optional, Union, Callable
+import torch
+import torch.nn as nn
+from enum import Enum
+
+from xautodl import spaces
+from .super_utils import IntSpaceType, BoolSpaceType
+from .super_utils import LayerOrder, SuperRunMode
+from .super_utils import TensorContainer
+from .super_utils import ShapeContainer
+
+BEST_DIR_KEY = "best_model_dir"
+BEST_NAME_KEY = "best_model_name"
+BEST_SCORE_KEY = "best_model_score"
+ENABLE_CANDIDATE = 0
+DISABLE_CANDIDATE = 1
+
+
+class SuperModule(abc.ABC, nn.Module):
+ """This class equips the nn.Module class with the ability to apply AutoDL."""
+
+ def __init__(self):
+ super(SuperModule, self).__init__()
+ self._super_run_type = SuperRunMode.Default
+ self._abstract_child = None
+ self._verbose = False
+ self._meta_info = {}
+ self._candidate_mode = DISABLE_CANDIDATE
+
+ def set_super_run_type(self, super_run_type):
+ def _reset_super_run(m):
+ if isinstance(m, SuperModule):
+ m._super_run_type = super_run_type
+
+ self.apply(_reset_super_run)
+
+ def add_module(self, name: str, module: Optional[torch.nn.Module]) -> None:
+ if not isinstance(module, SuperModule):
+ warnings.warn(
+ "Add {:}:{:} module, which is not SuperModule, into {:}".format(
+ name, module.__class__.__name__, self.__class__.__name__
+ )
+ + "\n"
+ + "It may cause some functions invalid."
+ )
+ super(SuperModule, self).add_module(name, module)
+
+ def apply_verbose(self, verbose):
+ def _reset_verbose(m):
+ if isinstance(m, SuperModule):
+ m._verbose = verbose
+
+ self.apply(_reset_verbose)
+
+ def apply_candidate(self, abstract_child):
+ if not isinstance(abstract_child, spaces.VirtualNode):
+ raise ValueError(
+ "Invalid abstract child program: {:}".format(abstract_child)
+ )
+ self._abstract_child = abstract_child
+
+ def enable_candidate(self):
+ def _enable_candidate(m):
+ if isinstance(m, SuperModule):
+ m._candidate_mode = ENABLE_CANDIDATE
+
+ self.apply(_enable_candidate)
+
+ def disable_candidate(self):
+ def _disable_candidate(m):
+ if isinstance(m, SuperModule):
+ m._candidate_mode = DISABLE_CANDIDATE
+
+ self.apply(_disable_candidate)
+
+ def get_w_container(self):
+ container = TensorContainer()
+ for name, param in self.named_parameters():
+ container.append(name, param, True)
+ for name, buf in self.named_buffers():
+ container.append(name, buf, False)
+ return container
+
+ def analyze_weights(self):
+ with torch.no_grad():
+ for name, param in self.named_parameters():
+ shapestr = "[{:10s}] shape={:}".format(name, list(param.shape))
+ finalstr = shapestr + "{:.2f} +- {:.2f}".format(
+ param.mean(), param.std()
+ )
+ print(finalstr)
+
+ def numel(self, buffer=True):
+ total = 0
+ for name, param in self.named_parameters():
+ total += param.numel()
+ if buffer:
+ for name, buf in self.named_buffers():
+ total += buf.numel()
+ return total
+
+ def set_best_dir(self, xdir):
+ self._meta_info[BEST_DIR_KEY] = str(xdir)
+ Path(xdir).mkdir(parents=True, exist_ok=True)
+
+ def set_best_name(self, xname):
+ self._meta_info[BEST_NAME_KEY] = str(xname)
+
+ def save_best(self, score):
+ if BEST_DIR_KEY not in self._meta_info:
+ tempdir = tempfile.mkdtemp("-xlayers")
+ self._meta_info[BEST_DIR_KEY] = tempdir
+ if BEST_SCORE_KEY not in self._meta_info:
+ self._meta_info[BEST_SCORE_KEY] = None
+ best_score = self._meta_info[BEST_SCORE_KEY]
+ if best_score is None or best_score <= score:
+ best_save_name = self._meta_info.get(
+ BEST_NAME_KEY, "best-{:}.pth".format(self.__class__.__name__)
+ )
+
+ best_save_path = os.path.join(self._meta_info[BEST_DIR_KEY], best_save_name)
+ self._meta_info[BEST_SCORE_KEY] = score
+ torch.save(self.state_dict(), best_save_path)
+ return True, self._meta_info[BEST_SCORE_KEY]
+ else:
+ return False, self._meta_info[BEST_SCORE_KEY]
+
+ def load_best(self, best_save_name=None):
+ if BEST_DIR_KEY not in self._meta_info:
+ raise ValueError("Please set BEST_DIR_KEY at first")
+ if best_save_name is None:
+ best_save_name = self._meta_info.get(
+ BEST_NAME_KEY, "best-{:}.pth".format(self.__class__.__name__)
+ )
+ best_save_path = os.path.join(self._meta_info[BEST_DIR_KEY], best_save_name)
+ state_dict = torch.load(best_save_path)
+ self.load_state_dict(state_dict)
+
+ def has_best(self, best_name=None):
+ if BEST_DIR_KEY not in self._meta_info:
+ raise ValueError("Please set BEST_DIR_KEY at first")
+ if best_name is None:
+ best_save_name = self._meta_info.get(
+ BEST_NAME_KEY, "best-{:}.pth".format(self.__class__.__name__)
+ )
+ else:
+ best_save_name = best_name
+ best_save_path = os.path.join(self._meta_info[BEST_DIR_KEY], best_save_name)
+ return os.path.exists(best_save_path)
+
+ @property
+ def abstract_search_space(self):
+ raise NotImplementedError
+
+ @property
+ def super_run_type(self):
+ return self._super_run_type
+
+ @property
+ def abstract_child(self):
+ return self._abstract_child
+
+ @property
+ def verbose(self):
+ return self._verbose
+
+ @abc.abstractmethod
+ def forward_raw(self, *inputs):
+ """Use the largest candidate for forward. Similar to the original PyTorch model."""
+ raise NotImplementedError
+
+ @abc.abstractmethod
+ def forward_candidate(self, *inputs):
+ raise NotImplementedError
+
+ @property
+ def name_with_id(self):
+ return "name={:}, id={:}".format(self.__class__.__name__, id(self))
+
+ def get_shape_str(self, tensors):
+ if isinstance(tensors, (list, tuple)):
+ shapes = [self.get_shape_str(tensor) for tensor in tensors]
+ if len(shapes) == 1:
+ return shapes[0]
+ else:
+ return ", ".join(shapes)
+ elif isinstance(tensors, (torch.Tensor, nn.Parameter)):
+ return str(tuple(tensors.shape))
+ else:
+ raise TypeError("Invalid input type: {:}.".format(type(tensors)))
+
+ def forward(self, *inputs):
+ if self.verbose:
+ print(
+ "[{:}] inputs shape: {:}".format(
+ self.name_with_id, self.get_shape_str(inputs)
+ )
+ )
+ if self.super_run_type == SuperRunMode.FullModel:
+ outputs = self.forward_raw(*inputs)
+ elif self.super_run_type == SuperRunMode.Candidate:
+ if self._candidate_mode == DISABLE_CANDIDATE:
+ raise ValueError("candidate mode is disabled")
+ outputs = self.forward_candidate(*inputs)
+ else:
+ raise ValueError(
+ "Unknown Super Model Run Mode: {:}".format(self.super_run_type)
+ )
+ if self.verbose:
+ print(
+ "[{:}] outputs shape: {:}".format(
+ self.name_with_id, self.get_shape_str(outputs)
+ )
+ )
+ return outputs
+
+ def forward_with_container(self, inputs, container, prefix=[]):
+ raise NotImplementedError
diff --git a/AutoDL-Projects/xautodl/xlayers/super_norm.py b/AutoDL-Projects/xautodl/xlayers/super_norm.py
new file mode 100644
index 0000000..1cd3b8f
--- /dev/null
+++ b/AutoDL-Projects/xautodl/xlayers/super_norm.py
@@ -0,0 +1,224 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.03 #
+#####################################################
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+
+import math
+from typing import Optional, Callable
+
+from xautodl import spaces
+from .super_module import SuperModule
+from .super_module import IntSpaceType
+from .super_module import BoolSpaceType
+
+
+class SuperLayerNorm1D(SuperModule):
+ """Super Layer Norm."""
+
+ def __init__(
+ self, dim: IntSpaceType, eps: float = 1e-6, elementwise_affine: bool = True
+ ) -> None:
+ super(SuperLayerNorm1D, self).__init__()
+ self._in_dim = dim
+ self._eps = eps
+ self._elementwise_affine = elementwise_affine
+ if self._elementwise_affine:
+ self.register_parameter("weight", nn.Parameter(torch.Tensor(self.in_dim)))
+ self.register_parameter("bias", nn.Parameter(torch.Tensor(self.in_dim)))
+ else:
+ self.register_parameter("weight", None)
+ self.register_parameter("bias", None)
+ self.reset_parameters()
+
+ @property
+ def in_dim(self):
+ return spaces.get_max(self._in_dim)
+
+ @property
+ def eps(self):
+ return self._eps
+
+ def reset_parameters(self) -> None:
+ if self._elementwise_affine:
+ nn.init.ones_(self.weight)
+ nn.init.zeros_(self.bias)
+
+ @property
+ def abstract_search_space(self):
+ root_node = spaces.VirtualNode(id(self))
+ if not spaces.is_determined(self._in_dim):
+ root_node.append("_in_dim", self._in_dim.abstract(reuse_last=True))
+ return root_node
+
+ def forward_candidate(self, input: torch.Tensor) -> torch.Tensor:
+ # check inputs ->
+ if not spaces.is_determined(self._in_dim):
+ expected_input_dim = self.abstract_child["_in_dim"].value
+ else:
+ expected_input_dim = spaces.get_determined_value(self._in_dim)
+ if input.size(-1) != expected_input_dim:
+ raise ValueError(
+ "Expect the input dim of {:} instead of {:}".format(
+ expected_input_dim, input.size(-1)
+ )
+ )
+ if self._elementwise_affine:
+ weight = self.weight[:expected_input_dim]
+ bias = self.bias[:expected_input_dim]
+ else:
+ weight, bias = None, None
+ return F.layer_norm(input, (expected_input_dim,), weight, bias, self.eps)
+
+ def forward_raw(self, input: torch.Tensor) -> torch.Tensor:
+ return F.layer_norm(input, (self.in_dim,), self.weight, self.bias, self.eps)
+
+ def forward_with_container(self, input, container, prefix=[]):
+ super_weight_name = ".".join(prefix + ["weight"])
+ if container.has(super_weight_name):
+ weight = container.query(super_weight_name)
+ else:
+ weight = None
+ super_bias_name = ".".join(prefix + ["bias"])
+ if container.has(super_bias_name):
+ bias = container.query(super_bias_name)
+ else:
+ bias = None
+ return F.layer_norm(input, (self.in_dim,), weight, bias, self.eps)
+
+ def extra_repr(self) -> str:
+ return (
+ "shape={in_dim}, eps={eps}, elementwise_affine={elementwise_affine}".format(
+ in_dim=self._in_dim,
+ eps=self._eps,
+ elementwise_affine=self._elementwise_affine,
+ )
+ )
+
+
+class SuperSimpleNorm(SuperModule):
+ """Super simple normalization."""
+
+ def __init__(self, mean, std, inplace=False) -> None:
+ super(SuperSimpleNorm, self).__init__()
+ self.register_buffer("_mean", torch.tensor(mean, dtype=torch.float))
+ self.register_buffer("_std", torch.tensor(std, dtype=torch.float))
+ self._inplace = inplace
+
+ @property
+ def abstract_search_space(self):
+ return spaces.VirtualNode(id(self))
+
+ def forward_candidate(self, input: torch.Tensor) -> torch.Tensor:
+ # check inputs ->
+ return self.forward_raw(input)
+
+ def forward_raw(self, input: torch.Tensor) -> torch.Tensor:
+ if not self._inplace:
+ tensor = input.clone()
+ else:
+ tensor = input
+ mean = torch.as_tensor(self._mean, dtype=tensor.dtype, device=tensor.device)
+ std = torch.as_tensor(self._std, dtype=tensor.dtype, device=tensor.device)
+ if (std == 0).any():
+ raise ValueError(
+ "std evaluated to zero after conversion to {}, leading to division by zero.".format(
+ tensor.dtype
+ )
+ )
+ while mean.ndim < tensor.ndim:
+ mean, std = torch.unsqueeze(mean, dim=0), torch.unsqueeze(std, dim=0)
+ return tensor.sub_(mean).div_(std)
+
+ def extra_repr(self) -> str:
+ return "mean={mean}, std={std}, inplace={inplace}".format(
+ mean=self._mean.item(), std=self._std.item(), inplace=self._inplace
+ )
+
+
+class SuperSimpleLearnableNorm(SuperModule):
+ """Super simple normalization."""
+
+ def __init__(self, mean=0, std=1, eps=1e-6, inplace=False) -> None:
+ super(SuperSimpleLearnableNorm, self).__init__()
+ self.register_parameter(
+ "_mean", nn.Parameter(torch.tensor(mean, dtype=torch.float))
+ )
+ self.register_parameter(
+ "_std", nn.Parameter(torch.tensor(std, dtype=torch.float))
+ )
+ self._eps = eps
+ self._inplace = inplace
+
+ @property
+ def abstract_search_space(self):
+ return spaces.VirtualNode(id(self))
+
+ def forward_candidate(self, input: torch.Tensor) -> torch.Tensor:
+ # check inputs ->
+ return self.forward_raw(input)
+
+ def forward_raw(self, input: torch.Tensor) -> torch.Tensor:
+ if not self._inplace:
+ tensor = input.clone()
+ else:
+ tensor = input
+ mean, std = (
+ self._mean.to(tensor.device),
+ torch.abs(self._std.to(tensor.device)) + self._eps,
+ )
+ if (std == 0).any():
+ raise ValueError("std leads to division by zero.")
+ while mean.ndim < tensor.ndim:
+ mean, std = torch.unsqueeze(mean, dim=0), torch.unsqueeze(std, dim=0)
+ return tensor.sub_(mean).div_(std)
+
+ def forward_with_container(self, input, container, prefix=[]):
+ if not self._inplace:
+ tensor = input.clone()
+ else:
+ tensor = input
+ mean_name = ".".join(prefix + ["_mean"])
+ std_name = ".".join(prefix + ["_std"])
+ mean, std = (
+ container.query(mean_name).to(tensor.device),
+ torch.abs(container.query(std_name).to(tensor.device)) + self._eps,
+ )
+ while mean.ndim < tensor.ndim:
+ mean, std = torch.unsqueeze(mean, dim=0), torch.unsqueeze(std, dim=0)
+ return tensor.sub_(mean).div_(std)
+
+ def extra_repr(self) -> str:
+ return "mean={mean}, std={std}, inplace={inplace}".format(
+ mean=self._mean.item(), std=self._std.item(), inplace=self._inplace
+ )
+
+
+class SuperIdentity(SuperModule):
+ """Super identity mapping layer."""
+
+ def __init__(self, inplace=False, **kwargs) -> None:
+ super(SuperIdentity, self).__init__()
+ self._inplace = inplace
+
+ @property
+ def abstract_search_space(self):
+ return spaces.VirtualNode(id(self))
+
+ def forward_candidate(self, input: torch.Tensor) -> torch.Tensor:
+ # check inputs ->
+ return self.forward_raw(input)
+
+ def forward_raw(self, input: torch.Tensor) -> torch.Tensor:
+ if not self._inplace:
+ tensor = input.clone()
+ else:
+ tensor = input
+ return tensor
+
+ def extra_repr(self) -> str:
+ return "inplace={inplace}".format(inplace=self._inplace)
+
+ def forward_with_container(self, input, container, prefix=[]):
+ return self.forward_raw(input)
diff --git a/AutoDL-Projects/xautodl/xlayers/super_positional_embedding.py b/AutoDL-Projects/xautodl/xlayers/super_positional_embedding.py
new file mode 100644
index 0000000..4ee7f28
--- /dev/null
+++ b/AutoDL-Projects/xautodl/xlayers/super_positional_embedding.py
@@ -0,0 +1,105 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.02 #
+#####################################################
+import torch
+import torch.nn as nn
+import math
+
+from xautodl import spaces
+from .super_module import SuperModule
+from .super_module import IntSpaceType
+
+
+class SuperDynamicPositionE(SuperModule):
+ """Applies a positional encoding to the input positions."""
+
+ def __init__(self, dimension: int, scale: float = 1.0) -> None:
+ super(SuperDynamicPositionE, self).__init__()
+
+ self._scale = scale
+ self._dimension = dimension
+ # weights to be optimized
+ self.register_buffer(
+ "_div_term",
+ torch.exp(
+ torch.arange(0, dimension, 2).float() * (-math.log(10000.0) / dimension)
+ ),
+ )
+
+ @property
+ def abstract_search_space(self):
+ root_node = spaces.VirtualNode(id(self))
+ return root_node
+
+ def forward_candidate(self, input: torch.Tensor) -> torch.Tensor:
+ return self.forward_raw(input)
+
+ def forward_raw(self, input: torch.Tensor) -> torch.Tensor:
+ positions = torch.unsqueeze(input * self._scale, dim=-1)
+ divisions = torch.reshape(
+ self._div_term, [1] * input.ndim + [self._div_term.numel()]
+ )
+ values = positions / divisions
+ embeds = torch.cat((torch.sin(values), torch.cos(values)), dim=-1)
+ return embeds
+
+ def extra_repr(self) -> str:
+ return "scale={:}, dim={:}".format(self._scale, self._dimension)
+
+
+class SuperPositionalEncoder(SuperModule):
+ """Attention Is All You Need: https://arxiv.org/pdf/1706.03762.pdf
+ https://github.com/pytorch/examples/blob/master/word_language_model/model.py#L65
+ """
+
+ def __init__(self, d_model: IntSpaceType, max_seq_len: int, dropout: float = 0.1):
+ super(SuperPositionalEncoder, self).__init__()
+ self._d_model = d_model
+ # create constant 'pe' matrix with values dependant on
+ # pos and i
+ self.dropout = nn.Dropout(p=dropout)
+ self.register_buffer("pe", self.create_pos_embed(max_seq_len, self.d_model))
+
+ @property
+ def d_model(self):
+ return spaces.get_max(self._d_model)
+
+ @property
+ def abstract_search_space(self):
+ root_node = spaces.VirtualNode(id(self))
+ if not spaces.is_determined(self._d_model):
+ root_node.append("_d_model", self._d_model.abstract(reuse_last=True))
+ return root_node
+
+ def create_pos_embed(self, max_seq_len, d_model):
+ pe = torch.zeros(max_seq_len, d_model)
+ for pos in range(max_seq_len):
+ for i in range(0, d_model):
+ div = 10000 ** ((i // 2) * 2 / d_model)
+ value = pos / div
+ if i % 2 == 0:
+ pe[pos, i] = math.sin(value)
+ else:
+ pe[pos, i] = math.cos(value)
+ return pe.unsqueeze(0)
+
+ def forward_candidate(self, input: torch.Tensor) -> torch.Tensor:
+ batch, seq, fdim = input.shape[:3]
+ embeddings = self.pe[:, :seq]
+ if not spaces.is_determined(self._d_model):
+ expected_d_model = self.abstract_child["_d_model"].value
+ else:
+ expected_d_model = spaces.get_determined_value(self._d_model)
+ assert fdim == expected_d_model, "{:} vs {:}".format(fdim, expected_d_model)
+
+ embeddings = torch.nn.functional.interpolate(
+ embeddings, size=(expected_d_model), mode="linear", align_corners=True
+ )
+ outs = self.dropout(input + embeddings)
+ return outs
+
+ def forward_raw(self, input: torch.Tensor) -> torch.Tensor:
+ batch, seq, fdim = input.shape[:3]
+ embeddings = self.pe[:, :seq]
+ outs = self.dropout(input + embeddings)
+ return outs
diff --git a/AutoDL-Projects/xautodl/xlayers/super_rearrange.py b/AutoDL-Projects/xautodl/xlayers/super_rearrange.py
new file mode 100644
index 0000000..ff9ff35
--- /dev/null
+++ b/AutoDL-Projects/xautodl/xlayers/super_rearrange.py
@@ -0,0 +1,187 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.03 #
+#############################################################
+# Borrow the idea of https://github.com/arogozhnikov/einops #
+#############################################################
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+
+import math
+import numpy as np
+import itertools
+import functools
+from collections import OrderedDict
+from typing import Optional, Callable
+
+from xautodl import spaces
+from .misc_utils import ParsedExpression, AnonymousAxis
+from .super_module import SuperModule
+from .super_module import IntSpaceType
+from .super_module import BoolSpaceType
+
+
+class SuperReArrange(SuperModule):
+ """Applies the rearrange operation."""
+
+ def __init__(self, pattern, **axes_lengths):
+ super(SuperReArrange, self).__init__()
+
+ self._pattern = pattern
+ self._axes_lengths = axes_lengths
+ axes_lengths = tuple(sorted(self._axes_lengths.items()))
+ # Perform initial parsing of pattern and provided supplementary info
+ # axes_lengths is a tuple of tuples (axis_name, axis_length)
+ left, right = pattern.split("->")
+ left = ParsedExpression(left)
+ right = ParsedExpression(right)
+ difference = set.symmetric_difference(left.identifiers, right.identifiers)
+ if difference:
+ raise ValueError(
+ "Identifiers only on one side of expression (should be on both): {}".format(
+ difference
+ )
+ )
+
+ # parsing all dimensions to find out lengths
+ axis_name2known_length = OrderedDict()
+ for composite_axis in left.composition:
+ for axis_name in composite_axis:
+ if isinstance(axis_name, AnonymousAxis):
+ axis_name2known_length[axis_name] = axis_name.value
+ else:
+ axis_name2known_length[axis_name] = None
+ for axis_name in right.identifiers:
+ if axis_name not in axis_name2known_length:
+ if isinstance(axis_name, AnonymousAxis):
+ axis_name2known_length[axis_name] = axis_name.value
+ else:
+ axis_name2known_length[axis_name] = None
+
+ axis_name2position = {
+ name: position for position, name in enumerate(axis_name2known_length)
+ }
+ for elementary_axis, axis_length in axes_lengths:
+ if not ParsedExpression.check_axis_name(elementary_axis):
+ raise ValueError("Invalid name for an axis", elementary_axis)
+ if elementary_axis not in axis_name2known_length:
+ raise ValueError(
+ "Axis {} is not used in transform".format(elementary_axis)
+ )
+ axis_name2known_length[elementary_axis] = axis_length
+
+ input_composite_axes = []
+ # some of shapes will be inferred later - all information is prepared for faster inference
+ for composite_axis in left.composition:
+ known = {
+ axis
+ for axis in composite_axis
+ if axis_name2known_length[axis] is not None
+ }
+ unknown = {
+ axis for axis in composite_axis if axis_name2known_length[axis] is None
+ }
+ if len(unknown) > 1:
+ raise ValueError("Could not infer sizes for {}".format(unknown))
+ assert len(unknown) + len(known) == len(composite_axis)
+ input_composite_axes.append(
+ (
+ [axis_name2position[axis] for axis in known],
+ [axis_name2position[axis] for axis in unknown],
+ )
+ )
+
+ axis_position_after_reduction = {}
+ for axis_name in itertools.chain(*left.composition):
+ if axis_name in right.identifiers:
+ axis_position_after_reduction[axis_name] = len(
+ axis_position_after_reduction
+ )
+
+ result_axes_grouping = []
+ for composite_axis in right.composition:
+ result_axes_grouping.append(
+ [axis_name2position[axis] for axis in composite_axis]
+ )
+
+ ordered_axis_right = list(itertools.chain(*right.composition))
+ axes_permutation = tuple(
+ axis_position_after_reduction[axis]
+ for axis in ordered_axis_right
+ if axis in left.identifiers
+ )
+ #
+ self.input_composite_axes = input_composite_axes
+ self.output_composite_axes = result_axes_grouping
+ self.elementary_axes_lengths = list(axis_name2known_length.values())
+ self.axes_permutation = axes_permutation
+
+ @functools.lru_cache(maxsize=1024)
+ def reconstruct_from_shape(self, shape):
+ if len(shape) != len(self.input_composite_axes):
+ raise ValueError(
+ "Expected {} dimensions, got {}".format(
+ len(self.input_composite_axes), len(shape)
+ )
+ )
+ axes_lengths = list(self.elementary_axes_lengths)
+ for input_axis, (known_axes, unknown_axes) in enumerate(
+ self.input_composite_axes
+ ):
+ length = shape[input_axis]
+ known_product = 1
+ for axis in known_axes:
+ known_product *= axes_lengths[axis]
+ if len(unknown_axes) == 0:
+ if (
+ isinstance(length, int)
+ and isinstance(known_product, int)
+ and length != known_product
+ ):
+ raise ValueError(
+ "Shape mismatch, {} != {}".format(length, known_product)
+ )
+ else:
+ if (
+ isinstance(length, int)
+ and isinstance(known_product, int)
+ and length % known_product != 0
+ ):
+ raise ValueError(
+ "Shape mismatch, can't divide axis of length {} in chunks of {}".format(
+ length, known_product
+ )
+ )
+
+ (unknown_axis,) = unknown_axes
+ axes_lengths[unknown_axis] = length // known_product
+ # at this point all axes_lengths are computed (either have values or variables, but not Nones)
+ final_shape = []
+ for output_axis, grouping in enumerate(self.output_composite_axes):
+ lengths = [axes_lengths[elementary_axis] for elementary_axis in grouping]
+ final_shape.append(int(np.prod(lengths)))
+ axes_reordering = self.axes_permutation
+ return axes_lengths, axes_reordering, final_shape
+
+ @property
+ def abstract_search_space(self):
+ root_node = spaces.VirtualNode(id(self))
+ return root_node
+
+ def forward_candidate(self, input: torch.Tensor) -> torch.Tensor:
+ self.forward_raw(input)
+
+ def forward_raw(self, input: torch.Tensor) -> torch.Tensor:
+ init_shape, axes_reordering, final_shape = self.reconstruct_from_shape(
+ tuple(input.shape)
+ )
+ tensor = torch.reshape(input, init_shape)
+ tensor = tensor.permute(axes_reordering)
+ tensor = torch.reshape(tensor, final_shape)
+ return tensor
+
+ def extra_repr(self) -> str:
+ params = repr(self._pattern)
+ for axis, length in self._axes_lengths.items():
+ params += ", {}={}".format(axis, length)
+ return "{:}".format(params)
diff --git a/AutoDL-Projects/xautodl/xlayers/super_trade_stem.py b/AutoDL-Projects/xautodl/xlayers/super_trade_stem.py
new file mode 100644
index 0000000..d3c64e9
--- /dev/null
+++ b/AutoDL-Projects/xautodl/xlayers/super_trade_stem.py
@@ -0,0 +1,58 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.03 #
+#####################################################
+import math
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+
+from xautodl import spaces
+from .super_linear import SuperLinear
+from .super_module import SuperModule
+from .super_module import IntSpaceType
+
+
+class SuperAlphaEBDv1(SuperModule):
+ """A simple layer to convert the raw trading data from 1-D to 2-D data and apply an FC layer."""
+
+ def __init__(self, d_feat: int, embed_dim: IntSpaceType):
+ super(SuperAlphaEBDv1, self).__init__()
+ self._d_feat = d_feat
+ self._embed_dim = embed_dim
+ self.proj = SuperLinear(d_feat, embed_dim)
+
+ @property
+ def embed_dim(self):
+ return spaces.get_max(self._embed_dim)
+
+ @property
+ def abstract_search_space(self):
+ root_node = spaces.VirtualNode(id(self))
+ space = self.proj.abstract_search_space
+ if not spaces.is_determined(space):
+ root_node.append("proj", space)
+ if not spaces.is_determined(self._embed_dim):
+ root_node.append("_embed_dim", self._embed_dim.abstract(reuse_last=True))
+ return root_node
+
+ def apply_candidate(self, abstract_child: spaces.VirtualNode):
+ super(SuperAlphaEBDv1, self).apply_candidate(abstract_child)
+ if "proj" in abstract_child:
+ self.proj.apply_candidate(abstract_child["proj"])
+
+ def forward_candidate(self, input: torch.Tensor) -> torch.Tensor:
+ x = input.reshape(len(input), self._d_feat, -1) # [N, F*T] -> [N, F, T]
+ x = x.permute(0, 2, 1) # [N, F, T] -> [N, T, F]
+ if not spaces.is_determined(self._embed_dim):
+ embed_dim = self.abstract_child["_embed_dim"].value
+ else:
+ embed_dim = spaces.get_determined_value(self._embed_dim)
+ out = self.proj(x) * math.sqrt(embed_dim)
+ return out
+
+ def forward_raw(self, input: torch.Tensor) -> torch.Tensor:
+ x = input.reshape(len(input), self._d_feat, -1) # [N, F*T] -> [N, F, T]
+ x = x.permute(0, 2, 1) # [N, F, T] -> [N, T, F]
+ out = self.proj(x) * math.sqrt(self.embed_dim)
+ return out
diff --git a/AutoDL-Projects/xautodl/xlayers/super_transformer.py b/AutoDL-Projects/xautodl/xlayers/super_transformer.py
new file mode 100644
index 0000000..b45ca51
--- /dev/null
+++ b/AutoDL-Projects/xautodl/xlayers/super_transformer.py
@@ -0,0 +1,127 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.03 #
+#####################################################
+import math
+from typing import Optional, Callable
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+
+from xautodl import spaces
+from .super_module import IntSpaceType
+from .super_module import BoolSpaceType
+from .super_module import LayerOrder
+from .super_module import SuperModule
+from .super_linear import SuperMLPv2
+from .super_norm import SuperLayerNorm1D
+from .super_attention import SuperSelfAttention
+
+
+class SuperTransformerEncoderLayer(SuperModule):
+ """TransformerEncoderLayer is made up of self-attn and feedforward network.
+ This is a super model for TransformerEncoderLayer that can support search for the transformer encoder layer.
+
+ Reference:
+ - Paper: Attention Is All You Need, NeurIPS 2017
+ - PyTorch Implementation: https://pytorch.org/docs/stable/_modules/torch/nn/modules/transformer.html#TransformerEncoderLayer
+
+ Details:
+ the original post-norm version: MHA -> residual -> norm -> MLP -> residual -> norm
+ the pre-norm version: norm -> MHA -> residual -> norm -> MLP -> residual
+ """
+
+ def __init__(
+ self,
+ d_model: IntSpaceType,
+ num_heads: IntSpaceType,
+ qkv_bias: BoolSpaceType = False,
+ mlp_hidden_multiplier: IntSpaceType = 4,
+ dropout: Optional[float] = None,
+ att_dropout: Optional[float] = None,
+ norm_affine: bool = True,
+ act_layer: Callable[[], nn.Module] = nn.GELU,
+ order: LayerOrder = LayerOrder.PreNorm,
+ use_mask: bool = False,
+ ):
+ super(SuperTransformerEncoderLayer, self).__init__()
+ mha = SuperSelfAttention(
+ d_model,
+ d_model,
+ num_heads=num_heads,
+ qkv_bias=qkv_bias,
+ attn_drop=att_dropout,
+ proj_drop=None,
+ use_mask=use_mask,
+ )
+ mlp = SuperMLPv2(
+ d_model,
+ hidden_multiplier=mlp_hidden_multiplier,
+ out_features=d_model,
+ act_layer=act_layer,
+ drop=dropout,
+ )
+ if order is LayerOrder.PreNorm:
+ self.norm1 = SuperLayerNorm1D(d_model, elementwise_affine=norm_affine)
+ self.mha = mha
+ self.drop = nn.Dropout(dropout or 0.0)
+ self.norm2 = SuperLayerNorm1D(d_model, elementwise_affine=norm_affine)
+ self.mlp = mlp
+ elif order is LayerOrder.PostNorm:
+ self.mha = mha
+ self.drop1 = nn.Dropout(dropout or 0.0)
+ self.norm1 = SuperLayerNorm1D(d_model, elementwise_affine=norm_affine)
+ self.mlp = mlp
+ self.drop2 = nn.Dropout(dropout or 0.0)
+ self.norm2 = SuperLayerNorm1D(d_model, elementwise_affine=norm_affine)
+ else:
+ raise ValueError("Unknown order: {:}".format(order))
+ self._order = order
+
+ @property
+ def abstract_search_space(self):
+ root_node = spaces.VirtualNode(id(self))
+ xdict = dict(
+ mha=self.mha.abstract_search_space,
+ norm1=self.norm1.abstract_search_space,
+ mlp=self.mlp.abstract_search_space,
+ norm2=self.norm2.abstract_search_space,
+ )
+ for key, space in xdict.items():
+ if not spaces.is_determined(space):
+ root_node.append(key, space)
+ return root_node
+
+ def apply_candidate(self, abstract_child: spaces.VirtualNode):
+ super(SuperTransformerEncoderLayer, self).apply_candidate(abstract_child)
+ valid_keys = ["mha", "norm1", "mlp", "norm2"]
+ for key in valid_keys:
+ if key in abstract_child:
+ getattr(self, key).apply_candidate(abstract_child[key])
+
+ def forward_candidate(self, inputs: torch.Tensor) -> torch.Tensor:
+ return self.forward_raw(inputs)
+
+ def forward_raw(self, inputs: torch.Tensor) -> torch.Tensor:
+ if self._order is LayerOrder.PreNorm:
+ # https://github.com/google-research/vision_transformer/blob/master/vit_jax/models.py#L135
+ x = self.norm1(inputs)
+ x = self.mha(x)
+ x = self.drop(x)
+ x = x + inputs
+ # feed-forward layer -- MLP
+ y = self.norm2(x)
+ outs = x + self.mlp(y)
+ elif self._order is LayerOrder.PostNorm:
+ # https://pytorch.org/docs/stable/_modules/torch/nn/modules/transformer.html#TransformerEncoder
+ # multi-head attention
+ x = self.mha(inputs)
+ x = inputs + self.drop1(x)
+ x = self.norm1(x)
+ # feed-forward layer -- MLP
+ y = self.mlp(x)
+ y = x + self.drop2(y)
+ outs = self.norm2(y)
+ else:
+ raise ValueError("Unknown order: {:}".format(self._order))
+ return outs
diff --git a/AutoDL-Projects/xautodl/xlayers/super_utils.py b/AutoDL-Projects/xautodl/xlayers/super_utils.py
new file mode 100644
index 0000000..6a5cb12
--- /dev/null
+++ b/AutoDL-Projects/xautodl/xlayers/super_utils.py
@@ -0,0 +1,222 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.03 #
+#####################################################
+
+import abc
+import warnings
+from typing import Optional, Union, Callable
+import torch
+import torch.nn as nn
+from enum import Enum
+
+from xautodl import spaces
+
+IntSpaceType = Union[int, spaces.Integer, spaces.Categorical]
+BoolSpaceType = Union[bool, spaces.Categorical]
+
+
+class LayerOrder(Enum):
+ """This class defines the enumerations for order of operation in a residual or normalization-based layer."""
+
+ PreNorm = "pre-norm"
+ PostNorm = "post-norm"
+
+
+class SuperRunMode(Enum):
+ """This class defines the enumerations for Super Model Running Mode."""
+
+ FullModel = "fullmodel"
+ Candidate = "candidate"
+ Default = "fullmodel"
+
+
+class ShapeContainer:
+ """A class to maintain the shape of each weight tensor for a model."""
+
+ def __init__(self):
+ self._names = []
+ self._shapes = []
+ self._name2index = dict()
+ self._param_or_buffers = []
+
+ @property
+ def shapes(self):
+ return self._shapes
+
+ def __getitem__(self, index):
+ return self._shapes[index]
+
+ def translate(self, tensors, all_none_match=True):
+ result = TensorContainer()
+ for index, name in enumerate(self._names):
+ cur_num = tensors[index].numel()
+ expected_num = self._shapes[index].numel()
+ if cur_num < expected_num or (
+ cur_num > expected_num and not all_none_match
+ ):
+ raise ValueError("Invalid {:} vs {:}".format(cur_num, expected_num))
+ cur_tensor = tensors[index].view(-1)[:expected_num]
+ new_tensor = torch.reshape(cur_tensor, self._shapes[index])
+ result.append(name, new_tensor, self._param_or_buffers[index])
+ return result
+
+ def append(self, name, shape, param_or_buffer):
+ if not isinstance(shape, torch.Size):
+ raise TypeError(
+ "The input tensor must be torch.Size instead of {:}".format(type(shape))
+ )
+ self._names.append(name)
+ self._shapes.append(shape)
+ self._param_or_buffers.append(param_or_buffer)
+ assert name not in self._name2index, "The [{:}] has already been added.".format(
+ name
+ )
+ self._name2index[name] = len(self._names) - 1
+
+ def query(self, name):
+ if not self.has(name):
+ raise ValueError(
+ "The {:} is not in {:}".format(name, list(self._name2index.keys()))
+ )
+ index = self._name2index[name]
+ return self._shapes[index]
+
+ def has(self, name):
+ return name in self._name2index
+
+ def has_prefix(self, prefix):
+ for name, idx in self._name2index.items():
+ if name.startswith(prefix):
+ return name
+ return False
+
+ def numel(self, index=None):
+ if index is None:
+ shapes = self._shapes
+ else:
+ shapes = [self._shapes[index]]
+ total = 0
+ for shape in shapes:
+ total += shape.numel()
+ return total
+
+ def __len__(self):
+ return len(self._names)
+
+ def __repr__(self):
+ return "{name}({num} tensors)".format(
+ name=self.__class__.__name__, num=len(self)
+ )
+
+
+class TensorContainer:
+ """A class to maintain both parameters and buffers for a model."""
+
+ def __init__(self):
+ self._names = []
+ self._tensors = []
+ self._param_or_buffers = []
+ self._name2index = dict()
+
+ def additive(self, tensors):
+ result = TensorContainer()
+ for index, name in enumerate(self._names):
+ new_tensor = self._tensors[index] + tensors[index]
+ result.append(name, new_tensor, self._param_or_buffers[index])
+ return result
+
+ def create_container(self, tensors):
+ result = TensorContainer()
+ for index, name in enumerate(self._names):
+ new_tensor = tensors[index]
+ result.append(name, new_tensor, self._param_or_buffers[index])
+ return result
+
+ def no_grad_clone(self):
+ result = TensorContainer()
+ with torch.no_grad():
+ for index, name in enumerate(self._names):
+ result.append(
+ name, self._tensors[index].clone(), self._param_or_buffers[index]
+ )
+ return result
+
+ def to_shape_container(self):
+ result = ShapeContainer()
+ for index, name in enumerate(self._names):
+ result.append(
+ name, self._tensors[index].shape, self._param_or_buffers[index]
+ )
+ return result
+
+ def requires_grad_(self, requires_grad=True):
+ for tensor in self._tensors:
+ tensor.requires_grad_(requires_grad)
+
+ def parameters(self):
+ return self._tensors
+
+ @property
+ def tensors(self):
+ return self._tensors
+
+ def flatten(self, tensors=None):
+ if tensors is None:
+ tensors = self._tensors
+ tensors = [tensor.view(-1) for tensor in tensors]
+ return torch.cat(tensors)
+
+ def unflatten(self, tensor):
+ tensors, s = [], 0
+ for raw_tensor in self._tensors:
+ length = raw_tensor.numel()
+ x = torch.reshape(tensor[s : s + length], shape=raw_tensor.shape)
+ tensors.append(x)
+ s += length
+ return tensors
+
+ def append(self, name, tensor, param_or_buffer):
+ if not isinstance(tensor, torch.Tensor):
+ raise TypeError(
+ "The input tensor must be torch.Tensor instead of {:}".format(
+ type(tensor)
+ )
+ )
+ self._names.append(name)
+ self._tensors.append(tensor)
+ self._param_or_buffers.append(param_or_buffer)
+ assert name not in self._name2index, "The [{:}] has already been added.".format(
+ name
+ )
+ self._name2index[name] = len(self._names) - 1
+
+ def query(self, name):
+ if not self.has(name):
+ raise ValueError(
+ "The {:} is not in {:}".format(name, list(self._name2index.keys()))
+ )
+ index = self._name2index[name]
+ return self._tensors[index]
+
+ def has(self, name):
+ return name in self._name2index
+
+ def has_prefix(self, prefix):
+ for name, idx in self._name2index.items():
+ if name.startswith(prefix):
+ return name
+ return False
+
+ def numel(self):
+ total = 0
+ for tensor in self._tensors:
+ total += tensor.numel()
+ return total
+
+ def __len__(self):
+ return len(self._names)
+
+ def __repr__(self):
+ return "{name}({num} tensors)".format(
+ name=self.__class__.__name__, num=len(self)
+ )
diff --git a/AutoDL-Projects/xautodl/xlayers/weight_init.py b/AutoDL-Projects/xautodl/xlayers/weight_init.py
new file mode 100644
index 0000000..c0583b2
--- /dev/null
+++ b/AutoDL-Projects/xautodl/xlayers/weight_init.py
@@ -0,0 +1,84 @@
+# Borrowed from https://github.com/rwightman/pytorch-image-models
+import torch
+import torch.nn as nn
+import math
+import warnings
+
+# setup for xlayers
+from . import super_core
+
+
+def _no_grad_trunc_normal_(tensor, mean, std, a, b):
+ # Cut & paste from PyTorch official master until it's in a few official releases - RW
+ # Method based on https://people.sc.fsu.edu/~jburkardt/presentations/truncated_normal.pdf
+ def norm_cdf(x):
+ # Computes standard normal cumulative distribution function
+ return (1.0 + math.erf(x / math.sqrt(2.0))) / 2.0
+
+ if (mean < a - 2 * std) or (mean > b + 2 * std):
+ warnings.warn(
+ "mean is more than 2 std from [a, b] in nn.init.trunc_normal_. "
+ "The distribution of values may be incorrect.",
+ stacklevel=2,
+ )
+
+ with torch.no_grad():
+ # Values are generated by using a truncated uniform distribution and
+ # then using the inverse CDF for the normal distribution.
+ # Get upper and lower cdf values
+ l = norm_cdf((a - mean) / std)
+ u = norm_cdf((b - mean) / std)
+
+ # Uniformly fill tensor with values from [l, u], then translate to
+ # [2l-1, 2u-1].
+ tensor.uniform_(2 * l - 1, 2 * u - 1)
+
+ # Use inverse cdf transform for normal distribution to get truncated
+ # standard normal
+ tensor.erfinv_()
+
+ # Transform to proper mean, std
+ tensor.mul_(std * math.sqrt(2.0))
+ tensor.add_(mean)
+
+ # Clamp to ensure it's in the proper range
+ tensor.clamp_(min=a, max=b)
+ return tensor
+
+
+def trunc_normal_(tensor, mean=0.0, std=1.0, a=-2.0, b=2.0):
+ # type: (Tensor, float, float, float, float) -> Tensor
+ r"""Fills the input Tensor with values drawn from a truncated
+ normal distribution. The values are effectively drawn from the
+ normal distribution :math:`\mathcal{N}(\text{mean}, \text{std}^2)`
+ with values outside :math:`[a, b]` redrawn until they are within
+ the bounds. The method used for generating the random values works
+ best when :math:`a \leq \text{mean} \leq b`.
+ Args:
+ tensor: an n-dimensional `torch.Tensor`
+ mean: the mean of the normal distribution
+ std: the standard deviation of the normal distribution
+ a: the minimum cutoff value
+ b: the maximum cutoff value
+ Examples:
+ >>> w = torch.empty(3, 5)
+ >>> nn.init.trunc_normal_(w)
+ """
+ if isinstance(tensor, list):
+ return [_no_grad_trunc_normal_(x, mean, std, a, b) for x in tensor]
+ else:
+ return _no_grad_trunc_normal_(tensor, mean, std, a, b)
+
+
+def init_transformer(m):
+ if isinstance(m, nn.Linear):
+ trunc_normal_(m.weight, std=0.02)
+ if isinstance(m, nn.Linear) and m.bias is not None:
+ nn.init.constant_(m.bias, 0)
+ elif isinstance(m, super_core.SuperLinear):
+ trunc_normal_(m._super_weight, std=0.02)
+ if m._super_bias is not None:
+ nn.init.constant_(m._super_bias, 0)
+ elif isinstance(m, super_core.SuperLayerNorm1D):
+ nn.init.constant_(m.weight, 1.0)
+ nn.init.constant_(m.bias, 0)
diff --git a/AutoDL-Projects/xautodl/xmisc/__init__.py b/AutoDL-Projects/xautodl/xmisc/__init__.py
new file mode 100644
index 0000000..e47d2bc
--- /dev/null
+++ b/AutoDL-Projects/xautodl/xmisc/__init__.py
@@ -0,0 +1,36 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.06 #
+#####################################################
+"""The module and yaml related functions."""
+from .module_utils import call_by_dict
+from .module_utils import call_by_yaml
+from .module_utils import nested_call_by_dict
+from .module_utils import nested_call_by_yaml
+from .yaml_utils import load_yaml
+
+from .torch_utils import count_parameters
+
+from .logger_utils import Logger
+
+"""The data sampler related classes."""
+from .sampler_utils import BatchSampler
+
+"""The meter related classes."""
+from .meter_utils import AverageMeter
+
+"""The scheduler related classes."""
+from .scheduler_utils import CosineParamScheduler, WarmupParamScheduler, LRMultiplier
+
+
+def get_scheduler(indicator, lr):
+ if indicator == "warm-cos":
+ multiplier = WarmupParamScheduler(
+ CosineParamScheduler(lr, lr * 1e-3),
+ warmup_factor=0.001,
+ warmup_length=0.05,
+ warmup_method="linear",
+ )
+
+ else:
+ raise ValueError("Unknown indicator: {:}".format(indicator))
+ return multiplier
diff --git a/AutoDL-Projects/xautodl/xmisc/logger_utils.py b/AutoDL-Projects/xautodl/xmisc/logger_utils.py
new file mode 100644
index 0000000..2a8bbd5
--- /dev/null
+++ b/AutoDL-Projects/xautodl/xmisc/logger_utils.py
@@ -0,0 +1,49 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.06 #
+#####################################################
+import sys
+from pathlib import Path
+
+from .time_utils import time_for_file, time_string
+
+
+class Logger:
+ """A logger used in xautodl."""
+
+ def __init__(self, root_dir, prefix="", log_time=True):
+ """Create a summary writer logging to log_dir."""
+ self.root_dir = Path(root_dir)
+ self.log_dir = self.root_dir / "logs"
+ self.log_dir.mkdir(parents=True, exist_ok=True)
+
+ self._prefix = prefix
+ self._log_time = log_time
+ self.logger_path = self.log_dir / "{:}{:}.log".format(
+ self._prefix, time_for_file()
+ )
+ self._logger_file = open(self.logger_path, "w")
+
+ @property
+ def logger(self):
+ return self._logger_file
+
+ def log(self, string, save=True, stdout=False):
+ string = "{:} {:}".format(time_string(), string) if self._log_time else string
+ if stdout:
+ sys.stdout.write(string)
+ sys.stdout.flush()
+ else:
+ print(string)
+ if save:
+ self._logger_file.write("{:}\n".format(string))
+ self._logger_file.flush()
+
+ def close(self):
+ self._logger_file.close()
+ if self.writer is not None:
+ self.writer.close()
+
+ def __repr__(self):
+ return "{name}(dir={log_dir}, prefix={_prefix}, log_time={_log_time})".format(
+ name=self.__class__.__name__, **self.__dict__
+ )
diff --git a/AutoDL-Projects/xautodl/xmisc/meter_utils.py b/AutoDL-Projects/xautodl/xmisc/meter_utils.py
new file mode 100644
index 0000000..c2dd7b0
--- /dev/null
+++ b/AutoDL-Projects/xautodl/xmisc/meter_utils.py
@@ -0,0 +1,163 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2020.06 #
+#####################################################
+# In this python file, it contains the meter classes#
+# , which may need to use PyTorch or Numpy. #
+#####################################################
+import abc
+import torch
+import torch.nn.functional as F
+
+
+class AverageMeter:
+ """Computes and stores the average and current value"""
+
+ def __init__(self):
+ self.reset()
+
+ def reset(self):
+ self.val = 0.0
+ self.avg = 0.0
+ self.sum = 0.0
+ self.count = 0.0
+
+ def update(self, val, n=1):
+ self.val = val
+ self.sum += val * n
+ self.count += n
+ self.avg = self.sum / self.count
+
+ def __repr__(self):
+ return "{name}(val={val}, avg={avg}, count={count})".format(
+ name=self.__class__.__name__, **self.__dict__
+ )
+
+
+class Metric(abc.ABC):
+ """The default meta metric class."""
+
+ def __init__(self):
+ self.reset()
+
+ def reset(self):
+ raise NotImplementedError
+
+ def __call__(self, predictions, targets):
+ raise NotImplementedError
+
+ def get_info(self):
+ raise NotImplementedError
+
+ def perf_str(self):
+ raise NotImplementedError
+
+ def __repr__(self):
+ return "{name}({inner})".format(
+ name=self.__class__.__name__, inner=self.inner_repr()
+ )
+
+ def inner_repr(self):
+ return ""
+
+
+class ComposeMetric(Metric):
+ """The composed metric class."""
+
+ def __init__(self, *metric_list):
+ self.reset()
+ for metric in metric_list:
+ self.append(metric)
+
+ def reset(self):
+ self._metric_list = []
+
+ def append(self, metric):
+ if not isinstance(metric, Metric):
+ raise ValueError(
+ "The input metric is not correct: {:}".format(type(metric))
+ )
+ self._metric_list.append(metric)
+
+ def __len__(self):
+ return len(self._metric_list)
+
+ def __call__(self, predictions, targets):
+ results = list()
+ for metric in self._metric_list:
+ results.append(metric(predictions, targets))
+ return results
+
+ def get_info(self):
+ results = dict()
+ for metric in self._metric_list:
+ for key, value in metric.get_info().items():
+ results[key] = value
+ return results
+
+ def inner_repr(self):
+ xlist = []
+ for metric in self._metric_list:
+ xlist.append(str(metric))
+ return ",".join(xlist)
+
+
+class CrossEntropyMetric(Metric):
+ """The metric for the cross entropy metric."""
+
+ def __init__(self, ignore_batch):
+ super(CrossEntropyMetric, self).__init__()
+ self._ignore_batch = ignore_batch
+
+ def reset(self):
+ self._loss = AverageMeter()
+
+ def __call__(self, predictions, targets):
+ if isinstance(predictions, torch.Tensor) and isinstance(targets, torch.Tensor):
+ batch, _ = predictions.shape() # only support 2-D tensor
+ max_prob_indexes = torch.argmax(predictions, dim=-1)
+ if self._ignore_batch:
+ loss = F.cross_entropy(predictions, targets, reduction="sum")
+ self._loss.update(loss.item(), 1)
+ else:
+ loss = F.cross_entropy(predictions, targets, reduction="mean")
+ self._loss.update(loss.item(), batch)
+ return loss
+ else:
+ raise NotImplementedError
+
+ def get_info(self):
+ return {"loss": self._loss.avg, "score": self._loss.avg * 100}
+
+ def perf_str(self):
+ return "ce-loss={:.5f}".format(self._loss.avg)
+
+
+class Top1AccMetric(Metric):
+ """The metric for the top-1 accuracy."""
+
+ def __init__(self, ignore_batch):
+ super(Top1AccMetric, self).__init__()
+ self._ignore_batch = ignore_batch
+
+ def reset(self):
+ self._accuracy = AverageMeter()
+
+ def __call__(self, predictions, targets):
+ if isinstance(predictions, torch.Tensor) and isinstance(targets, torch.Tensor):
+ batch, _ = predictions.shape() # only support 2-D tensor
+ max_prob_indexes = torch.argmax(predictions, dim=-1)
+ corrects = torch.eq(max_prob_indexes, targets)
+ accuracy = corrects.float().mean().float()
+ if self._ignore_batch:
+ self._accuracy.update(accuracy, 1)
+ else:
+ self._accuracy.update(accuracy, batch)
+ return accuracy
+ else:
+ raise NotImplementedError
+
+ def get_info(self):
+ return {"accuracy": self._accuracy.avg, "score": self._accuracy.avg * 100}
+
+ def perf_str(self):
+ return "accuracy={:.3f}%".format(self._accuracy.avg * 100)
diff --git a/AutoDL-Projects/xautodl/xmisc/module_utils.py b/AutoDL-Projects/xautodl/xmisc/module_utils.py
new file mode 100644
index 0000000..2357f37
--- /dev/null
+++ b/AutoDL-Projects/xautodl/xmisc/module_utils.py
@@ -0,0 +1,88 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.01 #
+#####################################################
+from typing import Union, Dict, Text, Any
+import importlib
+
+from .yaml_utils import load_yaml
+
+CLS_FUNC_KEY = "class_or_func"
+KEYS = (CLS_FUNC_KEY, "module_path", "args", "kwargs")
+
+
+def has_key_words(xdict):
+ if not isinstance(xdict, dict):
+ return False
+ key_set = set(KEYS)
+ cur_set = set(xdict.keys())
+ return key_set.intersection(cur_set) == key_set
+
+
+def get_module_by_module_path(module_path):
+ """Load the module from the path."""
+
+ if module_path.endswith(".py"):
+ module_spec = importlib.util.spec_from_file_location("", module_path)
+ module = importlib.util.module_from_spec(module_spec)
+ module_spec.loader.exec_module(module)
+ else:
+ module = importlib.import_module(module_path)
+
+ return module
+
+
+def call_by_dict(config: Dict[Text, Any], *args, **kwargs) -> object:
+ """
+ get initialized instance with config
+ Parameters
+ ----------
+ config : a dictionary, such as:
+ {
+ 'cls_or_func': 'ClassName',
+ 'args': list,
+ 'kwargs': dict,
+ 'model_path': a string indicating the path,
+ }
+ Returns
+ -------
+ object:
+ An initialized object based on the config info
+ """
+ module = get_module_by_module_path(config["module_path"])
+ cls_or_func = getattr(module, config[CLS_FUNC_KEY])
+ args = tuple(list(config["args"]) + list(args))
+ kwargs = {**config["kwargs"], **kwargs}
+ return cls_or_func(*args, **kwargs)
+
+
+def call_by_yaml(path, *args, **kwargs) -> object:
+ config = load_yaml(path)
+ return call_by_config(config, *args, **kwargs)
+
+
+def nested_call_by_dict(config: Union[Dict[Text, Any], Any], *args, **kwargs) -> object:
+ """Similar to `call_by_dict`, but differently, the args may contain another dict needs to be called."""
+ if isinstance(config, list):
+ return [nested_call_by_dict(x) for x in config]
+ elif isinstance(config, tuple):
+ return (nested_call_by_dict(x) for x in config)
+ elif not isinstance(config, dict):
+ return config
+ elif not has_key_words(config):
+ return {key: nested_call_by_dict(x) for x, key in config.items()}
+ else:
+ module = get_module_by_module_path(config["module_path"])
+ cls_or_func = getattr(module, config[CLS_FUNC_KEY])
+ args = tuple(list(config["args"]) + list(args))
+ kwargs = {**config["kwargs"], **kwargs}
+ # check whether there are nested special dict
+ new_args = [nested_call_by_dict(x) for x in args]
+ new_kwargs = {}
+ for key, x in kwargs.items():
+ new_kwargs[key] = nested_call_by_dict(x)
+ return cls_or_func(*new_args, **new_kwargs)
+
+
+def nested_call_by_yaml(path, *args, **kwargs) -> object:
+ config = load_yaml(path)
+ return nested_call_by_dict(config, *args, **kwargs)
diff --git a/AutoDL-Projects/xautodl/xmisc/sampler_utils.py b/AutoDL-Projects/xautodl/xmisc/sampler_utils.py
new file mode 100644
index 0000000..1ad9a00
--- /dev/null
+++ b/AutoDL-Projects/xautodl/xmisc/sampler_utils.py
@@ -0,0 +1,32 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.06 #
+#####################################################
+import random
+
+
+class BatchSampler:
+ """A batch sampler used for single machine training."""
+
+ def __init__(self, dataset, batch, steps):
+ self._num_per_epoch = len(dataset)
+ self._iter_per_epoch = self._num_per_epoch // batch
+ self._steps = steps
+ self._batch = batch
+ if self._num_per_epoch < self._batch:
+ raise ValueError(
+ "The dataset size must be larger than batch={:}".format(batch)
+ )
+ self._indexes = list(range(self._num_per_epoch))
+
+ def __iter__(self):
+ """
+ yield a batch of indexes using random sampling
+ """
+ for i in range(self._steps):
+ if i % self._iter_per_epoch == 0:
+ random.shuffle(self._indexes)
+ j = i % self._iter_per_epoch
+ yield self._indexes[j * self._batch : (j + 1) * self._batch]
+
+ def __len__(self):
+ return self._steps
diff --git a/AutoDL-Projects/xautodl/xmisc/scheduler_utils.py b/AutoDL-Projects/xautodl/xmisc/scheduler_utils.py
new file mode 100644
index 0000000..773fca8
--- /dev/null
+++ b/AutoDL-Projects/xautodl/xmisc/scheduler_utils.py
@@ -0,0 +1,532 @@
+####################################################
+# Copyright (c) Facebook, Inc. and its affiliates. #
+####################################################
+# Borrowed from https://github.com/facebookresearch/fvcore/blob/master/fvcore/common/param_scheduler.py
+# and https://github.com/facebookresearch/detectron2/blob/master/detectron2/solver/lr_scheduler.py
+####################################################
+import torch
+
+import bisect
+import math
+from typing import List, Optional, Sequence, Union
+
+__all__ = [
+ "ParamScheduler",
+ "ConstantParamScheduler",
+ "CosineParamScheduler",
+ "ExponentialParamScheduler",
+ "LinearParamScheduler",
+ "CompositeParamScheduler",
+ "MultiStepParamScheduler",
+ "StepParamScheduler",
+ "StepWithFixedGammaParamScheduler",
+ "PolynomialDecayParamScheduler",
+ "WarmupParamScheduler",
+ "LRMultiplier",
+]
+
+
+class ParamScheduler:
+ """
+ Base class for parameter schedulers.
+ A parameter scheduler defines a mapping from a progress value in [0, 1) to
+ a number (e.g. learning rate).
+ """
+
+ # To be used for comparisons with where
+ WHERE_EPSILON = 1e-6
+
+ def __call__(self, where: float) -> float:
+ """
+ Get the value of the param for a given point at training.
+
+ We update params (such as learning rate) based on the percent progress
+ of training completed. This allows a scheduler to be agnostic to the
+ exact length of a particular run (e.g. 120 epochs vs 90 epochs), as
+ long as the relative progress where params should be updated is the same.
+ However, it assumes that the total length of training is known.
+
+ Args:
+ where: A float in [0,1) that represents how far training has progressed
+
+ """
+ raise NotImplementedError("Param schedulers must override __call__")
+
+
+class ConstantParamScheduler(ParamScheduler):
+ """
+ Returns a constant value for a param.
+ """
+
+ def __init__(self, value: float) -> None:
+ self._value = value
+
+ def __call__(self, where: float) -> float:
+ if where >= 1.0:
+ raise RuntimeError(
+ f"where in ParamScheduler must be in [0, 1]: got {where}"
+ )
+ return self._value
+
+
+class CosineParamScheduler(ParamScheduler):
+ """
+ Cosine decay or cosine warmup schedules based on start and end values.
+ The schedule is updated based on the fraction of training progress.
+ The schedule was proposed in 'SGDR: Stochastic Gradient Descent with
+ Warm Restarts' (https://arxiv.org/abs/1608.03983). Note that this class
+ only implements the cosine annealing part of SGDR, and not the restarts.
+
+ Example:
+
+ .. code-block:: python
+
+ CosineParamScheduler(start_value=0.1, end_value=0.0001)
+ """
+
+ def __init__(
+ self,
+ start_value: float,
+ end_value: float,
+ ) -> None:
+ self._start_value = start_value
+ self._end_value = end_value
+
+ def __call__(self, where: float) -> float:
+ return self._end_value + 0.5 * (self._start_value - self._end_value) * (
+ 1 + math.cos(math.pi * where)
+ )
+
+
+class ExponentialParamScheduler(ParamScheduler):
+ """
+ Exponetial schedule parameterized by a start value and decay.
+ The schedule is updated based on the fraction of training
+ progress, `where`, with the formula
+ `param_t = start_value * (decay ** where)`.
+
+ Example:
+
+ .. code-block:: python
+ ExponentialParamScheduler(start_value=2.0, decay=0.02)
+
+ Corresponds to a decreasing schedule with values in [2.0, 0.04).
+ """
+
+ def __init__(
+ self,
+ start_value: float,
+ decay: float,
+ ) -> None:
+ self._start_value = start_value
+ self._decay = decay
+
+ def __call__(self, where: float) -> float:
+ return self._start_value * (self._decay**where)
+
+
+class LinearParamScheduler(ParamScheduler):
+ """
+ Linearly interpolates parameter between ``start_value`` and ``end_value``.
+ Can be used for either warmup or decay based on start and end values.
+ The schedule is updated after every train step by default.
+
+ Example:
+
+ .. code-block:: python
+
+ LinearParamScheduler(start_value=0.0001, end_value=0.01)
+
+ Corresponds to a linear increasing schedule with values in [0.0001, 0.01)
+ """
+
+ def __init__(
+ self,
+ start_value: float,
+ end_value: float,
+ ) -> None:
+ self._start_value = start_value
+ self._end_value = end_value
+
+ def __call__(self, where: float) -> float:
+ # interpolate between start and end values
+ return self._end_value * where + self._start_value * (1 - where)
+
+
+class MultiStepParamScheduler(ParamScheduler):
+ """
+ Takes a predefined schedule for a param value, and a list of epochs or steps
+ which stand for the upper boundary (excluded) of each range.
+
+ Example:
+
+ .. code-block:: python
+
+ MultiStepParamScheduler(
+ values=[0.1, 0.01, 0.001, 0.0001],
+ milestones=[30, 60, 80, 120]
+ )
+
+ Then the param value will be 0.1 for epochs 0-29, 0.01 for
+ epochs 30-59, 0.001 for epochs 60-79, 0.0001 for epochs 80-120.
+ Note that the length of values must be equal to the length of milestones
+ plus one.
+ """
+
+ def __init__(
+ self,
+ values: List[float],
+ num_updates: Optional[int] = None,
+ milestones: Optional[List[int]] = None,
+ ) -> None:
+ """
+ Args:
+ values: param value in each range
+ num_updates: the end of the last range. If None, will use ``milestones[-1]``
+ milestones: the boundary of each range. If None, will evenly split ``num_updates``
+
+ For example, all the following combinations define the same scheduler:
+
+ * num_updates=90, milestones=[30, 60], values=[1, 0.1, 0.01]
+ * num_updates=90, values=[1, 0.1, 0.01]
+ * milestones=[30, 60, 90], values=[1, 0.1, 0.01]
+ * milestones=[3, 6, 9], values=[1, 0.1, 0.01] (ParamScheduler is scale-invariant)
+ """
+ if num_updates is None and milestones is None:
+ raise ValueError("num_updates and milestones cannot both be None")
+ if milestones is None:
+ # Default equispaced drop_epochs behavior
+ milestones = []
+ step_width = math.ceil(num_updates / float(len(values)))
+ for idx in range(len(values) - 1):
+ milestones.append(step_width * (idx + 1))
+ else:
+ if not (
+ isinstance(milestones, Sequence)
+ and len(milestones) == len(values) - int(num_updates is not None)
+ ):
+ raise ValueError(
+ "MultiStep scheduler requires a list of %d miletones"
+ % (len(values) - int(num_updates is not None))
+ )
+
+ if num_updates is None:
+ num_updates, milestones = milestones[-1], milestones[:-1]
+ if num_updates < len(values):
+ raise ValueError(
+ "Total num_updates must be greater than length of param schedule"
+ )
+
+ self._param_schedule = values
+ self._num_updates = num_updates
+ self._milestones: List[int] = milestones
+
+ start_epoch = 0
+ for milestone in self._milestones:
+ # Do not exceed the total number of epochs
+ if milestone >= self._num_updates:
+ raise ValueError(
+ "Milestone must be smaller than total number of updates: "
+ "num_updates=%d, milestone=%d" % (self._num_updates, milestone)
+ )
+ # Must be in ascending order
+ if start_epoch >= milestone:
+ raise ValueError(
+ "Milestone must be smaller than start epoch: start_epoch=%d, milestone=%d"
+ % (start_epoch, milestone)
+ )
+ start_epoch = milestone
+
+ def __call__(self, where: float) -> float:
+ if where > 1.0:
+ raise RuntimeError(
+ f"where in ParamScheduler must be in [0, 1]: got {where}"
+ )
+ epoch_num = int((where + self.WHERE_EPSILON) * self._num_updates)
+ return self._param_schedule[bisect.bisect_right(self._milestones, epoch_num)]
+
+
+class PolynomialDecayParamScheduler(ParamScheduler):
+ """
+ Decays the param value after every epoch according to a
+ polynomial function with a fixed power.
+ The schedule is updated after every train step by default.
+
+ Example:
+
+ .. code-block:: python
+
+ PolynomialDecayParamScheduler(base_value=0.1, power=0.9)
+
+ Then the param value will be 0.1 for epoch 0, 0.099 for epoch 1, and
+ so on.
+ """
+
+ def __init__(
+ self,
+ base_value: float,
+ power: float,
+ ) -> None:
+ self._base_value = base_value
+ self._power = power
+
+ def __call__(self, where: float) -> float:
+ return self._base_value * (1 - where) ** self._power
+
+
+class StepParamScheduler(ParamScheduler):
+ """
+ Takes a fixed schedule for a param value. If the length of the
+ fixed schedule is less than the number of epochs, then the epochs
+ are divided evenly among the param schedule.
+ The schedule is updated after every train epoch by default.
+
+ Example:
+
+ .. code-block:: python
+
+ StepParamScheduler(values=[0.1, 0.01, 0.001, 0.0001], num_updates=120)
+
+ Then the param value will be 0.1 for epochs 0-29, 0.01 for
+ epochs 30-59, 0.001 for epoch 60-89, 0.0001 for epochs 90-119.
+ """
+
+ def __init__(
+ self,
+ num_updates: Union[int, float],
+ values: List[float],
+ ) -> None:
+ if num_updates <= 0:
+ raise ValueError("Number of updates must be larger than 0")
+ if not (isinstance(values, Sequence) and len(values) > 0):
+ raise ValueError(
+ "Step scheduler requires a list of at least one param value"
+ )
+ self._param_schedule = values
+
+ def __call__(self, where: float) -> float:
+ ind = int((where + self.WHERE_EPSILON) * len(self._param_schedule))
+ return self._param_schedule[ind]
+
+
+class StepWithFixedGammaParamScheduler(ParamScheduler):
+ """
+ Decays the param value by gamma at equal number of steps so as to have the
+ specified total number of decays.
+
+ Example:
+
+ .. code-block:: python
+
+ StepWithFixedGammaParamScheduler(
+ base_value=0.1, gamma=0.1, num_decays=3, num_updates=120)
+
+ Then the param value will be 0.1 for epochs 0-29, 0.01 for
+ epochs 30-59, 0.001 for epoch 60-89, 0.0001 for epochs 90-119.
+ """
+
+ def __init__(
+ self,
+ base_value: float,
+ num_decays: int,
+ gamma: float,
+ num_updates: int,
+ ) -> None:
+ for k in [base_value, gamma]:
+ if not (isinstance(k, (int, float)) and k > 0):
+ raise ValueError("base_value and gamma must be positive numbers")
+ for k in [num_decays, num_updates]:
+ if not (isinstance(k, int) and k > 0):
+ raise ValueError("num_decays and num_updates must be positive integers")
+
+ self.base_value = base_value
+ self.num_decays = num_decays
+ self.gamma = gamma
+ self.num_updates = num_updates
+ values = [base_value]
+ for _ in range(num_decays):
+ values.append(values[-1] * gamma)
+
+ self._step_param_scheduler = StepParamScheduler(
+ num_updates=num_updates, values=values
+ )
+
+ def __call__(self, where: float) -> float:
+ return self._step_param_scheduler(where)
+
+
+class CompositeParamScheduler(ParamScheduler):
+ """
+ Composite parameter scheduler composed of intermediate schedulers.
+ Takes a list of schedulers and a list of lengths corresponding to
+ percentage of training each scheduler should run for. Schedulers
+ are run in order. All values in lengths should sum to 1.0.
+
+ Each scheduler also has a corresponding interval scale. If interval
+ scale is 'fixed', the intermediate scheduler will be run without any rescaling
+ of the time. If interval scale is 'rescaled', intermediate scheduler is
+ run such that each scheduler will start and end at the same values as it
+ would if it were the only scheduler. Default is 'rescaled' for all schedulers.
+
+ Example:
+
+ .. code-block:: python
+
+ schedulers = [
+ ConstantParamScheduler(value=0.42),
+ CosineParamScheduler(start_value=0.42, end_value=1e-4)
+ ]
+ CompositeParamScheduler(
+ schedulers=schedulers,
+ interval_scaling=['rescaled', 'rescaled'],
+ lengths=[0.3, 0.7])
+
+ The parameter value will be 0.42 for the first [0%, 30%) of steps,
+ and then will cosine decay from 0.42 to 0.0001 for [30%, 100%) of
+ training.
+ """
+
+ def __init__(
+ self,
+ schedulers: Sequence[ParamScheduler],
+ lengths: List[float],
+ interval_scaling: Sequence[str],
+ ) -> None:
+ if len(schedulers) != len(lengths):
+ raise ValueError("Schedulers and lengths must be same length")
+ if len(schedulers) == 0:
+ raise ValueError(
+ "There must be at least one scheduler in the composite scheduler"
+ )
+ if abs(sum(lengths) - 1.0) >= 1e-3:
+ raise ValueError("The sum of all values in lengths must be 1")
+ if sum(lengths) != 1.0:
+ lengths[-1] = 1.0 - sum(lengths[:-1])
+ for s in interval_scaling:
+ if s not in ["rescaled", "fixed"]:
+ raise ValueError(f"Unsupported interval_scaling: {s}")
+
+ self._lengths = lengths
+ self._schedulers = schedulers
+ self._interval_scaling = interval_scaling
+
+ def __call__(self, where: float) -> float:
+ # Find scheduler corresponding to where
+ i = 0
+ running_total = self._lengths[i]
+ while (where + self.WHERE_EPSILON) > running_total and i < len(
+ self._schedulers
+ ) - 1:
+ i += 1
+ running_total += self._lengths[i]
+ scheduler = self._schedulers[i]
+ scheduler_where = where
+ interval_scale = self._interval_scaling[i]
+ if interval_scale == "rescaled":
+ # Calculate corresponding where % for scheduler
+ scheduler_start = running_total - self._lengths[i]
+ scheduler_where = (where - scheduler_start) / self._lengths[i]
+ return scheduler(scheduler_where)
+
+
+class WarmupParamScheduler(CompositeParamScheduler):
+ """
+ Add an initial warmup stage to another scheduler.
+ """
+
+ def __init__(
+ self,
+ scheduler: ParamScheduler,
+ warmup_factor: float,
+ warmup_length: float,
+ warmup_method: str = "linear",
+ ):
+ """
+ Args:
+ scheduler: warmup will be added at the beginning of this scheduler
+ warmup_factor: the factor w.r.t the initial value of ``scheduler``, e.g. 0.001
+ warmup_length: the relative length (in [0, 1]) of warmup steps w.r.t the entire
+ training, e.g. 0.01
+ warmup_method: one of "linear" or "constant"
+ """
+ end_value = scheduler(warmup_length) # the value to reach when warmup ends
+ start_value = warmup_factor * scheduler(0.0)
+ if warmup_method == "constant":
+ warmup = ConstantParamScheduler(start_value)
+ elif warmup_method == "linear":
+ warmup = LinearParamScheduler(start_value, end_value)
+ else:
+ raise ValueError("Unknown warmup method: {}".format(warmup_method))
+ super().__init__(
+ [warmup, scheduler],
+ interval_scaling=["rescaled", "fixed"],
+ lengths=[warmup_length, 1 - warmup_length],
+ )
+
+
+##### LR Scheduler
+
+
+class LRMultiplier(torch.optim.lr_scheduler._LRScheduler):
+ """
+ A LRScheduler which uses fvcore :class:`ParamScheduler` to multiply the
+ learning rate of each param in the optimizer.
+ Every step, the learning rate of each parameter becomes its initial value
+ multiplied by the output of the given :class:`ParamScheduler`.
+ The absolute learning rate value of each parameter can be different.
+ This scheduler can be used as long as the relative scale among them do
+ not change during training.
+ Examples:
+ ::
+ LRMultiplier(
+ opt,
+ WarmupParamScheduler(
+ MultiStepParamScheduler(
+ [1, 0.1, 0.01],
+ milestones=[60000, 80000],
+ num_updates=90000,
+ ), 0.001, 100 / 90000
+ ),
+ max_iter=90000
+ )
+ """
+
+ # NOTES: in the most general case, every LR can use its own scheduler.
+ # Supporting this requires interaction with the optimizer when its parameter
+ # group is initialized. For example, classyvision implements its own optimizer
+ # that allows different schedulers for every parameter group.
+ # To avoid this complexity, we use this class to support the most common cases
+ # where the relative scale among all LRs stay unchanged during training. In this
+ # case we only need a total of one scheduler that defines the relative LR multiplier.
+
+ def __init__(
+ self,
+ optimizer: torch.optim.Optimizer,
+ multiplier: ParamScheduler,
+ max_iter: int,
+ last_iter: int = -1,
+ ):
+ """
+ Args:
+ optimizer, last_iter: See ``torch.optim.lr_scheduler._LRScheduler``.
+ ``last_iter`` is the same as ``last_epoch``.
+ multiplier: a fvcore ParamScheduler that defines the multiplier on
+ every LR of the optimizer
+ max_iter: the total number of training iterations
+ """
+ if not isinstance(multiplier, ParamScheduler):
+ raise ValueError(
+ "_LRMultiplier(multiplier=) must be an instance of fvcore "
+ f"ParamScheduler. Got {multiplier} instead."
+ )
+ self._multiplier = multiplier
+ self._max_iter = max_iter
+ super().__init__(optimizer, last_epoch=last_iter)
+
+ def state_dict(self):
+ # fvcore schedulers are stateless. Only keep pytorch scheduler states
+ return {"base_lrs": self.base_lrs, "last_epoch": self.last_epoch}
+
+ def get_lr(self) -> List[float]:
+ multiplier = self._multiplier(self.last_epoch / self._max_iter)
+ return [base_lr * multiplier for base_lr in self.base_lrs]
diff --git a/AutoDL-Projects/xautodl/xmisc/time_utils.py b/AutoDL-Projects/xautodl/xmisc/time_utils.py
new file mode 100644
index 0000000..a55d9eb
--- /dev/null
+++ b/AutoDL-Projects/xautodl/xmisc/time_utils.py
@@ -0,0 +1,26 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.06 #
+#####################################################
+import time
+
+
+def time_for_file():
+ ISOTIMEFORMAT = "%d-%h-at-%H-%M-%S"
+ return "{:}".format(time.strftime(ISOTIMEFORMAT, time.gmtime(time.time())))
+
+
+def time_string():
+ ISOTIMEFORMAT = "%Y-%m-%d %X"
+ string = "[{:}]".format(time.strftime(ISOTIMEFORMAT, time.gmtime(time.time())))
+ return string
+
+
+def convert_secs2time(epoch_time, return_str=False):
+ need_hour = int(epoch_time / 3600)
+ need_mins = int((epoch_time - 3600 * need_hour) / 60)
+ need_secs = int(epoch_time - 3600 * need_hour - 60 * need_mins)
+ if return_str:
+ str = "[{:02d}:{:02d}:{:02d}]".format(need_hour, need_mins, need_secs)
+ return str
+ else:
+ return need_hour, need_mins, need_secs
diff --git a/AutoDL-Projects/xautodl/xmisc/torch_utils.py b/AutoDL-Projects/xautodl/xmisc/torch_utils.py
new file mode 100644
index 0000000..f873a6e
--- /dev/null
+++ b/AutoDL-Projects/xautodl/xmisc/torch_utils.py
@@ -0,0 +1,26 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.06 #
+#####################################################
+import torch
+import torch.nn as nn
+import numpy as np
+
+
+def count_parameters(model_or_parameters, unit="mb"):
+ if isinstance(model_or_parameters, nn.Module):
+ counts = sum(np.prod(v.size()) for v in model_or_parameters.parameters())
+ elif isinstance(model_or_parameters, nn.Parameter):
+ counts = models_or_parameters.numel()
+ elif isinstance(model_or_parameters, (list, tuple)):
+ counts = sum(count_parameters(x, None) for x in models_or_parameters)
+ else:
+ counts = sum(np.prod(v.size()) for v in model_or_parameters)
+ if unit.lower() == "kb" or unit.lower() == "k":
+ counts /= 1e3
+ elif unit.lower() == "mb" or unit.lower() == "m":
+ counts /= 1e6
+ elif unit.lower() == "gb" or unit.lower() == "g":
+ counts /= 1e9
+ elif unit is not None:
+ raise ValueError("Unknow unit: {:}".format(unit))
+ return counts
diff --git a/AutoDL-Projects/xautodl/xmisc/yaml_utils.py b/AutoDL-Projects/xautodl/xmisc/yaml_utils.py
new file mode 100644
index 0000000..a0b1a70
--- /dev/null
+++ b/AutoDL-Projects/xautodl/xmisc/yaml_utils.py
@@ -0,0 +1,13 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.06 #
+#####################################################
+import os
+import yaml
+
+
+def load_yaml(path):
+ if not os.path.isfile(path):
+ raise ValueError("{:} is not a file.".format(path))
+ with open(path, "r") as stream:
+ data = yaml.safe_load(stream)
+ return data
diff --git a/AutoDL-Projects/xautodl/xmodels/__init__.py b/AutoDL-Projects/xautodl/xmodels/__init__.py
new file mode 100644
index 0000000..147da59
--- /dev/null
+++ b/AutoDL-Projects/xautodl/xmodels/__init__.py
@@ -0,0 +1,7 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.06 #
+#####################################################
+# The models in this folder is written with xlayers #
+#####################################################
+
+from .core import *
diff --git a/AutoDL-Projects/xautodl/xmodels/core.py b/AutoDL-Projects/xautodl/xmodels/core.py
new file mode 100644
index 0000000..5127f25
--- /dev/null
+++ b/AutoDL-Projects/xautodl/xmodels/core.py
@@ -0,0 +1,67 @@
+#######################################################
+# Use module in xlayers to construct different models #
+#######################################################
+from typing import List, Text, Dict, Any
+import torch
+
+__all__ = ["get_model"]
+
+
+from xautodl.xlayers.super_core import SuperSequential
+from xautodl.xlayers.super_core import SuperLinear
+from xautodl.xlayers.super_core import SuperDropout
+from xautodl.xlayers.super_core import super_name2norm
+from xautodl.xlayers.super_core import super_name2activation
+
+
+def get_model(config: Dict[Text, Any], **kwargs):
+ model_type = config.get("model_type", "simple_mlp").lower()
+ if model_type == "simple_mlp":
+ act_cls = super_name2activation[kwargs["act_cls"]]
+ norm_cls = super_name2norm[kwargs["norm_cls"]]
+ mean, std = kwargs.get("mean", None), kwargs.get("std", None)
+ if "hidden_dim" in kwargs:
+ hidden_dim1 = kwargs.get("hidden_dim")
+ hidden_dim2 = kwargs.get("hidden_dim")
+ else:
+ hidden_dim1 = kwargs.get("hidden_dim1", 200)
+ hidden_dim2 = kwargs.get("hidden_dim2", 100)
+ model = SuperSequential(
+ norm_cls(mean=mean, std=std),
+ SuperLinear(kwargs["input_dim"], hidden_dim1),
+ act_cls(),
+ SuperLinear(hidden_dim1, hidden_dim2),
+ act_cls(),
+ SuperLinear(hidden_dim2, kwargs["output_dim"]),
+ )
+ elif model_type == "norm_mlp":
+ act_cls = super_name2activation[kwargs["act_cls"]]
+ norm_cls = super_name2norm[kwargs["norm_cls"]]
+ sub_layers, last_dim = [], kwargs["input_dim"]
+ for i, hidden_dim in enumerate(kwargs["hidden_dims"]):
+ sub_layers.append(SuperLinear(last_dim, hidden_dim))
+ if hidden_dim > 1:
+ sub_layers.append(norm_cls(hidden_dim, elementwise_affine=False))
+ sub_layers.append(act_cls())
+ last_dim = hidden_dim
+ sub_layers.append(SuperLinear(last_dim, kwargs["output_dim"]))
+ model = SuperSequential(*sub_layers)
+ elif model_type == "dual_norm_mlp":
+ act_cls = super_name2activation[kwargs["act_cls"]]
+ norm_cls = super_name2norm[kwargs["norm_cls"]]
+ sub_layers, last_dim = [], kwargs["input_dim"]
+ for i, hidden_dim in enumerate(kwargs["hidden_dims"]):
+ if i > 0:
+ sub_layers.append(norm_cls(last_dim, elementwise_affine=False))
+ sub_layers.append(SuperLinear(last_dim, hidden_dim))
+ sub_layers.append(SuperDropout(kwargs["dropout"]))
+ sub_layers.append(SuperLinear(hidden_dim, hidden_dim))
+ sub_layers.append(act_cls())
+ last_dim = hidden_dim
+ sub_layers.append(SuperLinear(last_dim, kwargs["output_dim"]))
+ model = SuperSequential(*sub_layers)
+ elif model_type == "quant_transformer":
+ raise NotImplementedError
+ else:
+ raise TypeError("Unkonwn model type: {:}".format(model_type))
+ return model
diff --git a/AutoDL-Projects/xautodl/xmodels/transformers.py b/AutoDL-Projects/xautodl/xmodels/transformers.py
new file mode 100644
index 0000000..7098ca9
--- /dev/null
+++ b/AutoDL-Projects/xautodl/xmodels/transformers.py
@@ -0,0 +1,192 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.06 #
+#####################################################
+# Vision Transformer: arxiv.org/pdf/2010.11929.pdf #
+#####################################################
+import copy, math
+from functools import partial
+from typing import Optional, Text, List
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+
+from xautodl import spaces
+from xautodl import xlayers
+from xautodl.xlayers import weight_init
+
+
+def pair(t):
+ return t if isinstance(t, tuple) else (t, t)
+
+
+name2config = {
+ "vit-cifar10-p4-d4-h4-c32": dict(
+ type="vit",
+ image_size=32,
+ patch_size=4,
+ num_classes=10,
+ dim=32,
+ depth=4,
+ heads=4,
+ dropout=0.1,
+ att_dropout=0.0,
+ ),
+ "vit-base-16": dict(
+ type="vit",
+ image_size=224,
+ patch_size=16,
+ num_classes=1000,
+ dim=768,
+ depth=12,
+ heads=12,
+ dropout=0.1,
+ att_dropout=0.0,
+ ),
+ "vit-large-16": dict(
+ type="vit",
+ image_size=224,
+ patch_size=16,
+ num_classes=1000,
+ dim=1024,
+ depth=24,
+ heads=16,
+ dropout=0.1,
+ att_dropout=0.0,
+ ),
+ "vit-huge-14": dict(
+ type="vit",
+ image_size=224,
+ patch_size=14,
+ num_classes=1000,
+ dim=1280,
+ depth=32,
+ heads=16,
+ dropout=0.1,
+ att_dropout=0.0,
+ ),
+}
+
+
+def extend_cifar100(configs):
+ new_configs = dict()
+ for name, config in configs.items():
+ new_configs[name] = config
+ if "cifar10" in name and "cifar100" not in name:
+ config = copy.deepcopy(config)
+ config["num_classes"] = 100
+ a, b = name.split("cifar10")
+ new_name = "{:}cifar100{:}".format(a, b)
+ new_configs[new_name] = config
+ return new_configs
+
+
+name2config = extend_cifar100(name2config)
+
+
+class SuperViT(xlayers.SuperModule):
+ """The super model for transformer."""
+
+ def __init__(
+ self,
+ image_size,
+ patch_size,
+ num_classes,
+ dim,
+ depth,
+ heads,
+ mlp_multiplier=4,
+ channels=3,
+ dropout=0.0,
+ att_dropout=0.0,
+ ):
+ super(SuperViT, self).__init__()
+ image_height, image_width = pair(image_size)
+ patch_height, patch_width = pair(patch_size)
+
+ if image_height % patch_height != 0 or image_width % patch_width != 0:
+ raise ValueError("Image dimensions must be divisible by the patch size.")
+
+ num_patches = (image_height // patch_height) * (image_width // patch_width)
+ patch_dim = channels * patch_height * patch_width
+ self.to_patch_embedding = xlayers.SuperSequential(
+ xlayers.SuperReArrange(
+ "b c (h p1) (w p2) -> b (h w) (p1 p2 c)",
+ p1=patch_height,
+ p2=patch_width,
+ ),
+ xlayers.SuperLinear(patch_dim, dim),
+ )
+
+ self.pos_embedding = nn.Parameter(torch.randn(1, num_patches + 1, dim))
+ self.cls_token = nn.Parameter(torch.randn(1, 1, dim))
+ self.dropout = nn.Dropout(dropout)
+
+ # build the transformer encode layers
+ layers = []
+ for ilayer in range(depth):
+ layers.append(
+ xlayers.SuperTransformerEncoderLayer(
+ dim,
+ heads,
+ False,
+ mlp_multiplier,
+ dropout=dropout,
+ att_dropout=att_dropout,
+ )
+ )
+ self.backbone = xlayers.SuperSequential(*layers)
+ self.cls_head = xlayers.SuperSequential(
+ xlayers.SuperLayerNorm1D(dim), xlayers.SuperLinear(dim, num_classes)
+ )
+
+ weight_init.trunc_normal_(self.cls_token, std=0.02)
+ self.apply(weight_init.init_transformer)
+
+ @property
+ def abstract_search_space(self):
+ raise NotImplementedError
+
+ def apply_candidate(self, abstract_child: spaces.VirtualNode):
+ super(SuperViT, self).apply_candidate(abstract_child)
+ raise NotImplementedError
+
+ def forward_candidate(self, input: torch.Tensor) -> torch.Tensor:
+ raise NotImplementedError
+
+ def forward_raw(self, input: torch.Tensor) -> torch.Tensor:
+ tensors = self.to_patch_embedding(input)
+ batch, seq, _ = tensors.shape
+
+ cls_tokens = self.cls_token.expand(batch, -1, -1)
+ feats = torch.cat((cls_tokens, tensors), dim=1)
+ feats = feats + self.pos_embedding[:, : seq + 1, :]
+ feats = self.dropout(feats)
+
+ feats = self.backbone(feats)
+
+ x = feats[:, 0] # the features for cls-token
+
+ return self.cls_head(x)
+
+
+def get_transformer(config):
+ if isinstance(config, str) and config.lower() in name2config:
+ config = name2config[config.lower()]
+ if not isinstance(config, dict):
+ raise ValueError("Invalid Configuration: {:}".format(config))
+ model_type = config.get("type", "vit").lower()
+ if model_type == "vit":
+ model = SuperViT(
+ image_size=config.get("image_size"),
+ patch_size=config.get("patch_size"),
+ num_classes=config.get("num_classes"),
+ dim=config.get("dim"),
+ depth=config.get("depth"),
+ heads=config.get("heads"),
+ dropout=config.get("dropout"),
+ att_dropout=config.get("att_dropout"),
+ )
+ else:
+ raise ValueError("Unknown model type: {:}".format(model_type))
+ return model
diff --git a/AutoDL-Projects/xautodl/xmodels/transformers_quantum.py b/AutoDL-Projects/xautodl/xmodels/transformers_quantum.py
new file mode 100644
index 0000000..95e35a0
--- /dev/null
+++ b/AutoDL-Projects/xautodl/xmodels/transformers_quantum.py
@@ -0,0 +1,124 @@
+#####################################################
+# Copyright (c) Xuanyi Dong [GitHub D-X-Y], 2021.06 #
+#####################################################
+# Vision Transformer: arxiv.org/pdf/2010.11929.pdf #
+#####################################################
+import copy, math
+from functools import partial
+from typing import Optional, Text, List
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+
+from xautodl import spaces
+from xautodl import xlayers
+from xautodl.xlayers import weight_init
+
+
+class SuperQuaT(xlayers.SuperModule):
+ """The super transformer for transformer."""
+
+ def __init__(
+ self,
+ image_size,
+ patch_size,
+ num_classes,
+ dim,
+ depth,
+ heads,
+ mlp_multiplier=4,
+ channels=3,
+ dropout=0.0,
+ att_dropout=0.0,
+ ):
+ super(SuperQuaT, self).__init__()
+ image_height, image_width = pair(image_size)
+ patch_height, patch_width = pair(patch_size)
+
+ if image_height % patch_height != 0 or image_width % patch_width != 0:
+ raise ValueError("Image dimensions must be divisible by the patch size.")
+
+ num_patches = (image_height // patch_height) * (image_width // patch_width)
+ patch_dim = channels * patch_height * patch_width
+ self.to_patch_embedding = xlayers.SuperSequential(
+ xlayers.SuperReArrange(
+ "b c (h p1) (w p2) -> b (h w) (p1 p2 c)",
+ p1=patch_height,
+ p2=patch_width,
+ ),
+ xlayers.SuperLinear(patch_dim, dim),
+ )
+
+ self.pos_embedding = nn.Parameter(torch.randn(1, num_patches + 1, dim))
+ self.cls_token = nn.Parameter(torch.randn(1, 1, dim))
+ self.dropout = nn.Dropout(dropout)
+
+ # build the transformer encode layers
+ layers = []
+ for ilayer in range(depth):
+ layers.append(
+ xlayers.SuperTransformerEncoderLayer(
+ dim,
+ heads,
+ False,
+ mlp_multiplier,
+ dropout=dropout,
+ att_dropout=att_dropout,
+ )
+ )
+ self.backbone = xlayers.SuperSequential(*layers)
+ self.cls_head = xlayers.SuperSequential(
+ xlayers.SuperLayerNorm1D(dim), xlayers.SuperLinear(dim, num_classes)
+ )
+
+ weight_init.trunc_normal_(self.cls_token, std=0.02)
+ self.apply(_init_weights)
+
+ @property
+ def abstract_search_space(self):
+ raise NotImplementedError
+
+ def apply_candidate(self, abstract_child: spaces.VirtualNode):
+ super(SuperQuaT, self).apply_candidate(abstract_child)
+ raise NotImplementedError
+
+ def forward_candidate(self, input: torch.Tensor) -> torch.Tensor:
+ raise NotImplementedError
+
+ def forward_raw(self, input: torch.Tensor) -> torch.Tensor:
+ tensors = self.to_patch_embedding(input)
+ batch, seq, _ = tensors.shape
+
+ cls_tokens = self.cls_token.expand(batch, -1, -1)
+ feats = torch.cat((cls_tokens, tensors), dim=1)
+ feats = feats + self.pos_embedding[:, : seq + 1, :]
+ feats = self.dropout(feats)
+
+ feats = self.backbone(feats)
+
+ x = feats[:, 0] # the features for cls-token
+
+ return self.cls_head(x)
+
+
+def get_transformer(config):
+ if isinstance(config, str) and config.lower() in name2config:
+ config = name2config[config.lower()]
+ if not isinstance(config, dict):
+ raise ValueError("Invalid Configuration: {:}".format(config))
+ model_type = config.get("type", "vit").lower()
+ if model_type == "vit":
+ model = SuperQuaT(
+ image_size=config.get("image_size"),
+ patch_size=config.get("patch_size"),
+ num_classes=config.get("num_classes"),
+ dim=config.get("dim"),
+ depth=config.get("depth"),
+ heads=config.get("heads"),
+ dropout=config.get("dropout"),
+ att_dropout=config.get("att_dropout"),
+ )
+ else:
+ raise ValueError("Unknown model type: {:}".format(model_type))
+ return model
diff --git a/correlation.py b/correlation.py
index c758284..01a0ebd 100644
--- a/correlation.py
+++ b/correlation.py
@@ -10,6 +10,21 @@ from src.utils.utilities import *
from src.metrics.swap import SWAP
from src.datasets.utilities import get_datasets
from src.search_space.networks import *
+import time
+
+# NASBench-201
+from nas_201_api import NASBench201API as API
+
+# xautodl
+from xautodl.models import get_cell_based_tiny_net
+
+# initalize nasbench-201
+nas_201_path = 'datasets/NAS-Bench-201-v1_1-096897.pth'
+print(f'Loading NAS-Bench-201 from {nas_201_path}')
+start_time = time.time()
+api = API(nas_201_path)
+end_time = time.time()
+print(f'Loaded NAS-Bench-201 in {end_time - start_time:.2f} seconds')
# Settings for console outputs
import warnings
@@ -20,8 +35,8 @@ parser = argparse.ArgumentParser()
# general setting
parser.add_argument('--data_path', default="datasets", type=str, nargs='?', help='path to the image dataset (datasets or datasets/ILSVRC/Data/CLS-LOC)')
-parser.add_argument('--seed', default=0, type=int, help='random seed')
-parser.add_argument('--device', default="cuda:2", type=str, nargs='?', help='setup device (cpu, mps or cuda)')
+parser.add_argument('--seed', default=111, type=int, help='random seed')
+parser.add_argument('--device', default="cuda:1", type=str, nargs='?', help='setup device (cpu, mps or cuda)')
parser.add_argument('--repeats', default=32, type=int, nargs='?', help='times of calculating the training-free metric')
parser.add_argument('--input_samples', default=16, type=int, nargs='?', help='input batch size for training-free metric')
@@ -31,7 +46,7 @@ if __name__ == "__main__":
device = torch.device(args.device)
- arch_info = pd.read_csv(args.data_path+'/DARTS_archs_CIFAR10.csv', names=['genotype', 'valid_acc'], sep=',')
+ # arch_info = pd.read_csv(args.data_path+'/DARTS_archs_CIFAR10.csv', names=['genotype', 'valid_acc'], sep=',')
train_data, _, _ = get_datasets('cifar10', args.data_path, (args.input_samples, 3, 32, 32), -1)
train_loader = torch.utils.data.DataLoader(train_data, batch_size=args.input_samples, num_workers=0, pin_memory=True)
@@ -39,24 +54,46 @@ if __name__ == "__main__":
inputs, _ = next(loader)
results = []
+
+ nasbench_len = 15625
- for index, i in arch_info.iterrows():
- print(f'Evaluating network: {index}')
+ # for index, i in arch_info.iterrows():
+ for i in range(nasbench_len):
+ # print(f'Evaluating network: {index}')
+ print(f'Evaluating network: {i}')
- network = Network(3, 10, 1, eval(i.genotype))
+ config = api.get_net_config(i, 'cifar10')
+ network = get_cell_based_tiny_net(config)
+ nas_results = api.query_by_index(i, 'cifar10')
+ acc = nas_results[111].get_eval('ori-test')
+
+ print(type(network))
+ start_time = time.time()
+
+ # network = Network(3, 10, 1, eval(i.genotype))
network = network.to(device)
+
+ end_time = time.time()
+ print(f'Loaded network in {end_time - start_time:.2f} seconds')
+ print(f'initiliazing SWAP')
swap = SWAP(model=network, inputs=inputs, device=device, seed=args.seed)
swap_score = []
- for _ in range(args.repeats):
+ print(f'Calculating SWAP score')
+ start_time = time.time()
+ for i in range(args.repeats):
+ print(f'Iteration: {i+1}/{args.repeats}', end='\r')
network = network.apply(network_weight_gaussian_init)
swap.reinit()
swap_score.append(swap.forward())
swap.clear()
+ end_time = time.time()
+ print(f'Average SWAP score: {np.mean(swap_score)}')
+ print(f'Elapsed time: {end_time - start_time:.2f} seconds')
- results.append([np.mean(swap_score), i.valid_acc])
+ results.append([np.mean(swap_score), acc])
results = pd.DataFrame(results, columns=['swap_score', 'valid_acc'])
print()