diff --git a/.bumpversion.toml b/.bumpversion.toml new file mode 100644 index 0000000..8dd82c5 --- /dev/null +++ b/.bumpversion.toml @@ -0,0 +1,22 @@ +[tool.bumpversion] +current_version = "v0.2.0" +commit = true +commit_args = "--no-verify" +tag = true +tag_name = "{new_version}" +allow_dirty = true +parse = "(?P\\d+)\\.(?P\\d+)\\.(?P\\d+)(\\.(?Pdev)\\d+\\+[-_a-zA-Z0-9]+)?" +serialize = [ + "v{major}.{minor}.{patch}.{dev}{distance_to_latest_tag}+{short_branch_name}", + "v{major}.{minor}.{patch}" +] +message = "Version updated from {current_version} to {new_version}" + +[[tool.bumpversion.files]] +filename = "pyproject.toml" + +[[tool.bumpversion.files]] +filename = "README.md" + +[[tool.bumpversion.files]] +filename = "src/imageruler/__init__.py" diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..0aada4d --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +version: 2 +updates: + - package-ecosystem: "pip" + directory: "/" # Location of package manifests + schedule: + interval: "daily" + + - package-ecosystem: github-actions + directory: / + schedule: + interval: monthly diff --git a/.github/workflows/build-ci.yml b/.github/workflows/build-ci.yml new file mode 100644 index 0000000..2a15fd5 --- /dev/null +++ b/.github/workflows/build-ci.yml @@ -0,0 +1,79 @@ +name: CI + +on: + pull_request: + push: + branches: + - main + schedule: + - cron: "0 13 * * 1" # Every Monday at 9AM EST + +jobs: + pre-commit: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.10" + cache: "pip" + cache-dependency-path: pyproject.toml + + - name: Test pre-commit hooks + run: | + python -m pip install --upgrade pip + pip install pre-commit + pre-commit run -a + + validate-types-and-docstrings: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.10" + cache: "pip" + cache-dependency-path: pyproject.toml + + - name: Setup environment + run: | + python -m pip install --upgrade pip + pip install ".[tests,dev]" + + - name: mypy type validation + run: | + mypy src + mypy imageruler + + - name: darglint docstring validation + run: | + darglint src --strictness=short --ignore-raise=ValueError + darglint imageruler --strictness=short --ignore-raise=ValueError + + tests: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.10" + cache: "pip" + cache-dependency-path: pyproject.toml + + - name: Setup environment + run: | + python -m pip install --upgrade pip + pip install ".[tests,dev]" + + - name: Run Python tests + run: | + pytest --cov=imageruler tests diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml deleted file mode 100644 index 8b6e8d4..0000000 --- a/.github/workflows/ci-build.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: CI - -on: - # Triggers the workflow on push or pull request events but only for the main branch - push: - branches: [ main ] - pull_request: - branches: [ main ] - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -jobs: - build: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - python-version: [3.7, 3.9] - steps: - - name: Cancel previous - uses: styfle/cancel-workflow-action@0.7.0 - with: - access_token: ${{ github.token }} - if: ${{github.ref != 'refs/head/main'}} - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - name: Get pip cache dir - id: pip-cache - run: | - python -m pip install --upgrade pip wheel - echo "::set-output name=dir::$(pip cache dir)" - - name: pip cache - uses: actions/cache@v2 - with: - path: ${{ steps.pip-cache.outputs.dir }} - key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }} - - name: Test with pytest - run: | - pip install -e ".[complete]" - pytest -n auto imageruler --dist=loadfile diff --git a/.github/workflows/cli_test.yml b/.github/workflows/cli_test.yml new file mode 100644 index 0000000..17dd2f4 --- /dev/null +++ b/.github/workflows/cli_test.yml @@ -0,0 +1,32 @@ +name: CI + +on: + pull_request: + push: + branches: + - main + schedule: + - cron: "0 13 * * 1" # Every Monday at 9AM EST + +jobs: + example: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.10" + cache: "pip" + cache-dependency-path: pyproject.toml + + - name: Setup environment + run: | + python -m pip install --upgrade pip + pip install ".[tests,dev,examples]" + + - name: Run program on reference design + run: | + python imageruler reference_designs/Rasmus70nm.csv diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml new file mode 100644 index 0000000..50fb597 --- /dev/null +++ b/.github/workflows/pages.yml @@ -0,0 +1,51 @@ +name: Sphinx docs to gh-pages + +on: + push: + branches: + - main + workflow_dispatch: + +jobs: + build-docs: + runs-on: ubuntu-latest + name: Sphinx docs to gh-pages + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.10" + cache: "pip" + cache-dependency-path: pyproject.toml + + - name: Setup environment + run: | + python -m pip install --upgrade pip + pip install ".[tests,dev,docs]" + + - name: docs + run: jb build docs + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: "./docs/_build/html/" + + deploy-docs: + needs: build-docs + permissions: + pages: write + id-token: write + + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + + runs-on: ubuntu-latest + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..a5aad78 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,28 @@ +name: Release PyPI + +on: + push: + tags: "v*" + +jobs: + release_pypi: + if: github.event_name == 'push' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: 3.x + cache-dependency-path: pyproject.toml + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install build setuptools twine wheel + - name: Build and publish + env: + TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} + TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} + run: | + python -m build + twine upload dist/* diff --git a/.gitignore b/.gitignore index f909a8f..caa700d 100644 --- a/.gitignore +++ b/.gitignore @@ -129,4 +129,4 @@ dmypy.json cython_debug/ # PyCharm -.idea/ \ No newline at end of file +.idea/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..5e1ddcb --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,55 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.4.0 + hooks: + - id: check-added-large-files + - id: check-case-conflict + - id: check-merge-conflict + - id: check-symlinks + - id: check-yaml + - id: debug-statements + - id: end-of-file-fixer + - id: mixed-line-ending + - id: name-tests-test + args: ["--pytest-test-first"] + - id: trailing-whitespace + + # Black formatting + - repo: https://github.com/psf/black + rev: 23.9.1 + hooks: + - id: black + + # Upgrade python syntax + - repo: https://github.com/asottile/pyupgrade + rev: v3.10.1 + hooks: + - id: pyupgrade + args: [--py37-plus, --keep-runtime-typing] + + # Validate shell scripts + - repo: https://github.com/shellcheck-py/shellcheck-py + rev: v0.9.0.5 + hooks: + - id: shellcheck + + # Security linter + - repo: https://github.com/PyCQA/bandit + rev: 1.7.5 + hooks: + - id: bandit + args: [--exit-zero] + exclude: ^tests/ + + # Linter + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.0.287 + hooks: + - id: ruff + exclude: ^tests/ + + # Strip whitespace from notebooks. + - repo: https://github.com/kynan/nbstripout + rev: 0.6.0 + hooks: + - id: nbstripout diff --git a/LICENSE.md b/LICENSE.md index 650f738..5233c64 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -17,5 +17,4 @@ 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. - +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index 6a0e72f..52cad34 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ [![Build Status](https://github.com/NanoComp/imageruler/workflows/CI/badge.svg)](https://github.com/NanoComp/imageruler/actions) +`v0.2.0` Imageruler is a free Python program to compute the minimum length scale of binary images which are typically designs produced by topology optimization. The algorithm is described in Section 2 of [J. Optical Society of America B, Vol. 42, pp. A161-A176 (2024)](https://opg.optica.org/josab/abstract.cfm?uri=josab-41-2-A161) and is based on morphological transformations implemented using [OpenCV](https://github.com/opencv/opencv). Imageruler also supports 1d binary images. @@ -21,4 +22,4 @@ For a 1d binary image, the algorithm simply finds the minimum length among all s ## Note on Accuracy -The accuracy of the minimum length scale computed by Imageruler is limited by the finite resolution of the input image. A fundamental feature is that length scales smaller than a single pixel cannot be measured. Also, in certain situations, length scales of a few pixels may be indistinguishable from discretization artifacts such as the "staircasing" of curved surfaces. As an example, a sharp 90° corner corresponds to a length scale (radius of curvature) of *zero* at infinite resolution. However, at a finite resolution, a sharp corner is indistinguishable from one that is rounded with a radius of curvature of a few pixels. Imageruler will therefore return a length scale proportional to the pixel size rather than zero. In general, the measured length scale should be viewed as having an "error bar" on the few-pixel level. \ No newline at end of file +The accuracy of the minimum length scale computed by Imageruler is limited by the finite resolution of the input image. A fundamental feature is that length scales smaller than a single pixel cannot be measured. Also, in certain situations, length scales of a few pixels may be indistinguishable from discretization artifacts such as the "staircasing" of curved surfaces. As an example, a sharp 90° corner corresponds to a length scale (radius of curvature) of *zero* at infinite resolution. However, at a finite resolution, a sharp corner is indistinguishable from one that is rounded with a radius of curvature of a few pixels. Imageruler will therefore return a length scale proportional to the pixel size rather than zero. In general, the measured length scale should be viewed as having an "error bar" on the few-pixel level. diff --git a/docs/_config.yml b/docs/_config.yml new file mode 100755 index 0000000..1cc11ce --- /dev/null +++ b/docs/_config.yml @@ -0,0 +1,49 @@ +# Book settings +# Learn more at https://jupyterbook.org/customize/config.html + +title: imageruler +author: imageruler authors + +# Force re-execution of notebooks on each build. +# See https://jupyterbook.org/content/execute.html +execute: + execute_notebooks: cache + timeout: -1 + allow_errors: true + # execute_notebooks: force + # execute_notebooks: "off" + +latex: + latex_engine: pdflatex # one of 'pdflatex', 'xelatex' (recommended for unicode), 'luatex', 'platex', 'uplatex' + use_jupyterbook_latex: true # use sphinx-jupyterbook-latex for pdf builds as default + +# Add a bibtex file so that we can create citations + +html: + home_page_in_navbar: true + use_edit_page_button: true + use_repository_button: true + use_issues_button: true + baseurl: https://github.com/NanoComp/imageruler + +# Information about where the book exists on the web +repository: + url: https://github.com/NanoComp/imageruler + path_to_book: docs # Optional path to your book, relative to the repository root + branch: main # Which branch of the repository should be used when creating links (optional) + +launch_buttons: + notebook_interface: jupyterlab + colab_url: "https://colab.research.google.com" + +sphinx: + extra_extensions: + - "sphinx.ext.autodoc" + - "sphinx.ext.autodoc.typehints" + - "sphinx.ext.autosummary" + - "sphinx.ext.napoleon" + - "sphinx.ext.viewcode" + - "matplotlib.sphinxext.plot_directive" + config: + autodoc_typehints: description + nb_execution_show_tb: True diff --git a/docs/_toc.yml b/docs/_toc.yml new file mode 100644 index 0000000..e9f0624 --- /dev/null +++ b/docs/_toc.yml @@ -0,0 +1,11 @@ +# Table of contents +# Learn more at https://jupyterbook.org/customize/toc.html + +format: jb-book +root: readme +parts: + - caption: Examples + chapters: + - file: notebooks/simple_shapes + - file: notebooks/to_designs + - file: notebooks/advanced diff --git a/docs/notebooks/advanced.ipynb b/docs/notebooks/advanced.ipynb new file mode 100644 index 0000000..c591294 --- /dev/null +++ b/docs/notebooks/advanced.ipynb @@ -0,0 +1,225 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Advanced usage\n", + "\n", + "In this notebook we will look at some advanced usage of the imageruler.\n", + "\n", + "## Ignore schemes\n", + "\n", + "By default, the imageruler will ignore certain violations on the edges of large features, as these generally arise from discretization artifacts and are not particularly meaningful. However, we can configure the imageruler to be either more permissive, or more strict.\n", + "\n", + "We will study designs that consist of two circular solid features _with a discretization artifact_ separated by a variable gap. First, define a function to construct these and make a plot." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as onp\n", + "from imageruler import imageruler\n", + "\n", + "\n", + "def separated_circles(\n", + " separation_distance: int, include_extra_pixel: bool\n", + ") -> onp.ndarray:\n", + " left_circle = imageruler.kernel_for_length_scale(80)\n", + " right_circle = imageruler.kernel_for_length_scale(60)\n", + " right_circle = onp.pad(right_circle, ((10, 10), (0, 0)))\n", + "\n", + " circles = onp.concatenate(\n", + " [left_circle, onp.zeros((80, separation_distance)), right_circle],\n", + " axis=1,\n", + " )\n", + " circles = onp.pad(circles, ((10, 10), (10, 10))).astype(bool)\n", + " if include_extra_pixel:\n", + " circles[9, 50] = True\n", + " return circles\n", + "\n", + "\n", + "_ = plt.imshow(separated_circles(separation_distance=1, include_extra_pixel=True))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Above we see the two circles (with diameters of 80 and 60 pixels, respectively), along with the extra pixel we've added at position `(9, 50)`. Now, let's use the imageruler to measure the minimum width and spacing using the most-strict scheme which does not ignore _any_ violations: `IgnoreScheme.NONE`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "minimum_width, minimum_spacing = imageruler.minimum_length_scale(\n", + " x=separated_circles(separation_distance=1, include_extra_pixel=True),\n", + " ignore_scheme=imageruler.IgnoreScheme.NONE,\n", + ")\n", + "print(\n", + " f\"Minimum width and spacing are {minimum_width} and {minimum_spacing}, respectively\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As we can see, the measured minimum spacing is a single pixel, as we would hope. However, the minimum width is reported as only three pixels---much smaller the 60 pixel value we might expect. At issue here is the extra pixel; let's measure the length scale for the two circles _without_ the extra pixel." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "minimum_width, minimum_spacing = imageruler.minimum_length_scale(\n", + " x=separated_circles(separation_distance=1, include_extra_pixel=False),\n", + " ignore_scheme=imageruler.IgnoreScheme.NONE,\n", + ")\n", + "print(\n", + " f\"Minimum width and spacing are {minimum_width} and {minimum_spacing}, respectively\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "These are the expected values. In order to obtain these values from the imageruler even for a design that includes an errant pixel, we need to tell the imageruler to ignore certain violations. Let's start with the most permissive scheme, `IgnoreScheme.EDGES`, which ignores violations on the edges of all features." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "minimum_width, minimum_spacing = imageruler.minimum_length_scale(\n", + " x=separated_circles(separation_distance=1, include_extra_pixel=True),\n", + " ignore_scheme=imageruler.IgnoreScheme.EDGES,\n", + ")\n", + "print(\n", + " f\"Minimum width and spacing are {minimum_width} and {minimum_spacing}, respectively\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here, we see that the width is now correctly reported, but we are also over-estimating the spacing. Fortunately, there is a third scheme for ignoring iolations, `IgnoreScheme.LARGE_FEATURE_EDGES`, which only ignores violations on the edges of _large_ features. This is actually the default choice, so if we simply call `imageruler.minimum_length_scale` without specifying an ignore scheme, this is what we will get." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "minimum_width, minimum_spacing = imageruler.minimum_length_scale(\n", + " x=separated_circles(separation_distance=1, include_extra_pixel=True),\n", + ")\n", + "print(\n", + " f\"Minimum width and spacing are {minimum_width} and {minimum_spacing}, respectively\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "These are the values we hoped for." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "invrs", + "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.10.12" + }, + "latex_envs": { + "LaTeX_envs_menu_present": true, + "autoclose": false, + "autocomplete": true, + "bibliofile": "biblio.bib", + "cite_by": "apalike", + "current_citInitial": 1, + "eqLabelWithNumbers": true, + "eqNumInitial": 1, + "hotkeys": { + "equation": "Ctrl-E", + "itemize": "Ctrl-I" + }, + "labels_anchors": false, + "latex_user_defs": false, + "report_style_numbering": false, + "user_envs_cfg": false + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/notebooks/simple_shapes.ipynb b/docs/notebooks/simple_shapes.ipynb new file mode 100644 index 0000000..d207aec --- /dev/null +++ b/docs/notebooks/simple_shapes.ipynb @@ -0,0 +1,380 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Simple shapes\n", + "\n", + "In this notebook we will exercise the `imageruler` algorithm with some simple shapes." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "from imageruler import imageruler\n", + "from matplotlib import pyplot as plt\n", + "\n", + "# Import functions that generate regular shapes.\n", + "from imageruler.regular_shapes import disc, rounded_square, stripe" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Examples based on regular 2d shapes are as follows." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "resolution = 1 # number of pixels per unit length\n", + "phys_size = (200, 200) # physical size of the entire image\n", + "declared_mls = 50 # declared minimum length scale\n", + "\n", + "image = rounded_square(\n", + " resolution, phys_size, declared_mls, angle=20\n", + ") # generate a rounded square\n", + "\n", + "plt.figure()\n", + "plt.imshow(image)\n", + "plt.show()\n", + "\n", + "solid_mls, _ = imageruler.minimum_length_scale(\n", + " image\n", + ") # estimate the minimum length scale of the solid region\n", + "print(\"Declared minimum length scale of the solid region: \", declared_mls)\n", + "print(\"Estimated minimum length scale of the solid region: \", solid_mls)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "diameter = 50\n", + "image = disc(resolution, phys_size, diameter) # generate a disc\n", + "\n", + "plt.figure()\n", + "plt.imshow(image)\n", + "plt.show()\n", + "\n", + "# estimate the minimum length scale of the solid region\n", + "solid_mls = imageruler.minimum_length_scale_solid(image)\n", + "print(\"Declared minimum length scale of the solid region: \", diameter)\n", + "print(\"Estimated minimum length scale of the solid region: \", solid_mls)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "outer_diameter, inner_diameter = 120, 50\n", + "declared_solid_mls, declared_void_mls = (\n", + " outer_diameter - inner_diameter\n", + ") / 2, inner_diameter\n", + "\n", + "solid_disc = disc(resolution, phys_size, diameter=outer_diameter)\n", + "void_disc = disc(resolution, phys_size, diameter=inner_diameter)\n", + "image = solid_disc ^ void_disc # ring\n", + "\n", + "plt.figure()\n", + "plt.imshow(image)\n", + "plt.show()\n", + "\n", + "solid_mls, void_mls = imageruler.minimum_length_scale(image)\n", + "mls = min(solid_mls, void_mls)\n", + "\n", + "print(\n", + " f\"Declared minimum length scale: {declared_solid_mls} (solid), \"\n", + " f\"{declared_void_mls} (void)\"\n", + ")\n", + "print(\n", + " f\"Estimated minimum length scale: {solid_mls} (solid), {void_mls} \"\n", + " f\"(void), {mls} (minimum)\"\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "resolution = 1 # number of pixels per unit length\n", + "phys_size = (400, 400) # physical size of the entire image\n", + "\n", + "outer_diameter, middle_diameter, inner_diameter = 300, 200, 100\n", + "declared_solid_mls, declared_void_mls = (\n", + " outer_diameter - inner_diameter\n", + ") / 2, inner_diameter\n", + "\n", + "outer_solid_disc = disc(resolution, phys_size, diameter=outer_diameter, center=(0, 0))\n", + "void_disc = disc(resolution, phys_size, diameter=middle_diameter, center=(-20, 0))\n", + "inner_solid_disc = disc(resolution, phys_size, diameter=inner_diameter, center=(-10, 0))\n", + "image = outer_solid_disc ^ void_disc ^ inner_solid_disc\n", + "\n", + "plt.figure()\n", + "plt.imshow(image)\n", + "plt.show()\n", + "\n", + "solid_mls, void_mls = imageruler.minimum_length_scale(image)\n", + "mls = min(solid_mls, void_mls)\n", + "\n", + "print(f\"Declared minimum length scale: {30} (solid), {40} (void)\")\n", + "print(\n", + " f\"Estimated minimum length scale: {solid_mls} (solid), {void_mls} \"\n", + " f\"(void), {mls} (minimum)\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The images that illustrate the areas of violation at various probe diameters are shown as follows. The three rows from top to bottom show violations at solid, void, and either region." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "diameters = [31, 41, 61, 71, 101]\n", + "nd = len(diameters)\n", + "plt.figure(figsize=(20, 12))\n", + "\n", + "for idx in range(nd):\n", + " plt.subplot(3, nd, idx + 1)\n", + " ax = plt.gca()\n", + " ax.set_axis_off()\n", + " image_violation_solid = imageruler.length_scale_violations_solid(\n", + " image, length_scale=diameters[idx]\n", + " )\n", + " plt.imshow(image_violation_solid)\n", + " plt.title(\"probe diameter = \" + str(diameters[idx]))\n", + "\n", + " plt.subplot(3, nd, nd + idx + 1)\n", + " ax = plt.gca()\n", + " ax.set_axis_off()\n", + " image_violation_void = imageruler.length_scale_violations_solid(\n", + " ~image, length_scale=diameters[idx]\n", + " )\n", + " plt.imshow(image_violation_void)\n", + "\n", + " plt.subplot(3, nd, 2 * nd + idx + 1)\n", + " ax = plt.gca()\n", + " ax.set_axis_off()\n", + " image_violation = image_violation_solid | image_violation_void\n", + " plt.imshow(image_violation)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "resolution = 50\n", + "width, height = 6, 4 # size of the binary image\n", + "phys_size = (width, height)\n", + "\n", + "stripe_width = 0.8\n", + "image = stripe(resolution, phys_size, stripe_width)\n", + "\n", + "plt.figure()\n", + "plt.imshow(\n", + " image,\n", + " extent=[-phys_size[1] / 2, phys_size[1] / 2, -phys_size[0] / 2, phys_size[0] / 2],\n", + ")\n", + "plt.show()\n", + "\n", + "solid_mls = imageruler.minimum_length_scale_solid(image)\n", + "\n", + "print(f\"Declared minimum length scale of the solid region: {stripe_width}\")\n", + "print(f\"Estimated minimum length scale of the solid region: {solid_mls / resolution}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "image = stripe(resolution, phys_size, stripe_width, center=(0, -2)) | stripe(\n", + " resolution, phys_size, stripe_width, center=(0, 2)\n", + ")\n", + "\n", + "plt.figure()\n", + "plt.imshow(\n", + " image,\n", + " extent=[-phys_size[1] / 2, phys_size[1] / 2, -phys_size[0] / 2, phys_size[0] / 2],\n", + ")\n", + "plt.show()\n", + "\n", + "# Assume this image is periodic along the horizontal direction, which corresponds to the axis 1.\n", + "solid_mls = imageruler.minimum_length_scale_solid(image, periodic=(False, True))\n", + "\n", + "print(f\"Declared minimum length scale of the solid region: {stripe_width}\")\n", + "print(f\"Estimated minimum length scale of the solid region: {solid_mls / resolution}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "stripe_width, intercept, angle = 1, 1 / np.sqrt(2), 0.25 * np.pi\n", + "image = stripe(resolution, phys_size, stripe_width, center=(intercept, 0), angle=135)\n", + "\n", + "plt.figure()\n", + "plt.imshow(\n", + " image,\n", + " extent=[-phys_size[1] / 2, phys_size[1] / 2, -phys_size[0] / 2, phys_size[0] / 2],\n", + ")\n", + "plt.show()\n", + "\n", + "solid_mls = imageruler.minimum_length_scale_solid(image)\n", + "\n", + "print(f\"Declared minimum length scale of the solid region: {stripe_width}\")\n", + "print(f\"Estimated minimum length scale of the solid region: {solid_mls / resolution}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Some tests based on 1d images are as follows." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "phys_size = 10.1\n", + "image = np.sin(np.linspace(0, 100, 101) / 5) > 0.5\n", + "image = image[:, np.newaxis]\n", + "resolution = image.size / phys_size\n", + "\n", + "plt.plot(np.linspace(-phys_size / 2, phys_size / 2, len(image)), image)\n", + "\n", + "solid_mls, void_mls = imageruler.minimum_length_scale(image, periodic=(True, True))\n", + "print(\n", + " f\"Estimated minimum length scales: {solid_mls / resolution} (solid), \"\n", + " f\"{void_mls / resolution} (void)\"\n", + ")\n", + "\n", + "# disregard the short void and solid regions at both ends\n", + "solid_mls, void_mls = imageruler.minimum_length_scale(image)\n", + "print(\n", + " f\"Estimated minimum length scales with some end regions disregarded: \"\n", + " f\"{solid_mls / resolution} (solid), {void_mls / resolution} (void)\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This package can also be used via the command line, which allows you to invoke the function `minimimum_length_scale`. The syntax is \"imageruler file\", where \"file\" is a string of the path of the text file that contains the array of the input image. All other arguments of the function take default options." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "invrs", + "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.10.12" + }, + "latex_envs": { + "LaTeX_envs_menu_present": true, + "autoclose": false, + "autocomplete": true, + "bibliofile": "biblio.bib", + "cite_by": "apalike", + "current_citInitial": 1, + "eqLabelWithNumbers": true, + "eqNumInitial": 1, + "hotkeys": { + "equation": "Ctrl-E", + "itemize": "Ctrl-I" + }, + "labels_anchors": false, + "latex_user_defs": false, + "report_style_numbering": false, + "user_envs_cfg": false + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/notebooks/to_designs.ipynb b/docs/notebooks/to_designs.ipynb new file mode 100644 index 0000000..0b8f9c3 --- /dev/null +++ b/docs/notebooks/to_designs.ipynb @@ -0,0 +1,204 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Inverse designs\n", + "\n", + "In this notebook we will investigate a complex design created by topology optimization. The specific design is the `Rasmus70nm.csv` file from the RGB metalens problem of the [photonics-opt-testbed repo](https://github.com/NanoComp/photonics-opt-testbed)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as onp\n", + "import matplotlib.pyplot as plt\n", + "from skimage import measure\n", + "\n", + "design = onp.genfromtxt(\"../../reference_designs/Rasmus70nm.csv\", delimiter=\",\")\n", + "design = design > 0.5 # Binarize\n", + "design = onp.rot90(design)\n", + "\n", + "plt.figure(figsize=(7, 1))\n", + "ax = plt.subplot(111)\n", + "im = ax.imshow(1 - design, cmap=\"gray\")\n", + "im.set_clim([-2, 1])\n", + "for c in measure.find_contours(design):\n", + " ax.plot(c[:, 1], c[:, 0], \"k\")\n", + "_ = ax.axis(False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we'll measure the length scale of solid and void features (i.e. the minimum width and spacing of features) using the imageruler." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import imageruler\n", + "\n", + "min_width, min_spacing = imageruler.minimum_length_scale(design)\n", + "print(f\"Minimum width is {min_width} pixels, minimum spacing is {min_spacing} pixels.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We find that the minimum width is 7 pixels, which means that we should find violations when checking for length scales greater than 7 pixels. We can identify these violations using the `length_scale_violations_solid` function:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from scipy import ndimage\n", + "\n", + "plt.figure(figsize=(7, 6))\n", + "for i, dim in enumerate(range(min_width, min_width + 3)):\n", + " width_violations = imageruler.length_scale_violations_solid(\n", + " design, length_scale=dim\n", + " )\n", + " width_violations = ndimage.binary_dilation(width_violations, onp.ones((10, 10)))\n", + "\n", + " ax = plt.subplot(3, 1, i + 1)\n", + " im = ax.imshow(1 - design, cmap=\"gray\")\n", + " im.set_clim([-2, 1])\n", + " for c in measure.find_contours(design):\n", + " ax.plot(c[:, 1], c[:, 0], \"k\")\n", + "\n", + " for c in measure.find_contours(width_violations):\n", + " ax.fill(c[:, 1], c[:, 0], \"r\", alpha=0.5, ec=\"r\")\n", + "\n", + " ax.set_title(f\"Violations for solid length scale = {dim}\")\n", + " ax.axis(False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And similarly, we can find void length scale violations:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plt.figure(figsize=(7, 6))\n", + "for i, dim in enumerate(range(min_spacing, min_spacing + 3)):\n", + " width_violations = imageruler.length_scale_violations_solid(\n", + " ~design, length_scale=dim\n", + " )\n", + " width_violations = ndimage.binary_dilation(width_violations, onp.ones((10, 10)))\n", + "\n", + " ax = plt.subplot(3, 1, i + 1)\n", + " im = ax.imshow(1 - design, cmap=\"gray\")\n", + " im.set_clim([-2, 1])\n", + " for c in measure.find_contours(design):\n", + " ax.plot(c[:, 1], c[:, 0], \"k\")\n", + "\n", + " for c in measure.find_contours(width_violations):\n", + " ax.fill(c[:, 1], c[:, 0], \"r\", alpha=0.5, ec=\"r\")\n", + "\n", + " ax.set_title(f\"Violations for void length scale = {dim}\")\n", + " ax.axis(False)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "invrs", + "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.10.12" + }, + "latex_envs": { + "LaTeX_envs_menu_present": true, + "autoclose": false, + "autocomplete": true, + "bibliofile": "biblio.bib", + "cite_by": "apalike", + "current_citInitial": 1, + "eqLabelWithNumbers": true, + "eqNumInitial": 1, + "hotkeys": { + "equation": "Ctrl-E", + "itemize": "Ctrl-I" + }, + "labels_anchors": false, + "latex_user_defs": false, + "report_style_numbering": false, + "user_envs_cfg": false + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/readme.md b/docs/readme.md new file mode 100644 index 0000000..451beda --- /dev/null +++ b/docs/readme.md @@ -0,0 +1,2 @@ +```{include} ../README.md +``` diff --git a/imageruler/__init__.py b/imageruler/__init__.py deleted file mode 100644 index acc9772..0000000 --- a/imageruler/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -"""Imageruler.""" - -__version__ = '1.0' - -import imageruler.imageruler -import imageruler.regular_shapes -from .imageruler import ( - KernelShape, - PaddingMode, - binary_close, - binary_dilate, - binary_erode, - binary_open, - get_kernel, - length_violation, - length_violation_solid, - length_violation_void, - minimum_length, - minimum_length_solid, - minimum_length_solid_void, - minimum_length_void, -) diff --git a/imageruler/__main__.py b/imageruler/__main__.py new file mode 100644 index 0000000..4c4f4ca --- /dev/null +++ b/imageruler/__main__.py @@ -0,0 +1,31 @@ +"""Command line interface for imageruler. + +Invoke by running `python imageruler FILENAME` from the imageruler directory. +""" + +import argparse + +import numpy as onp + +import imageruler + + +def main() -> None: + parser = argparse.ArgumentParser( + description=( + "A python package for estimating minimum lengthscales in binary images" + ) + ) + parser.add_argument( + "file", type=str, help="Path of the text file containing the image array." + ) + args = parser.parse_args() + + design = onp.loadtxt(args.file, delimiter=",") + binarized_design = design > 0.5 + solid_mls, void_mls = imageruler.minimum_length_scale(binarized_design) + print("Minimum lengthscales of solid and void regions: ", solid_mls, void_mls) + + +if __name__ == "__main__": + main() diff --git a/imageruler/cli.py b/imageruler/cli.py deleted file mode 100644 index 0df624f..0000000 --- a/imageruler/cli.py +++ /dev/null @@ -1,27 +0,0 @@ -"""Command line interface for imageruler.""" - -import argparse -import imageruler -import numpy as np - - -def main(): - parser = argparse.ArgumentParser( - description=( - "A python package for estimating minimum lengthscales in binary" - " images" - ) - ) - parser.add_argument( - "file", type=str, help="Path of the text file containing the image array." - ) - args = parser.parse_args() - - solid_mls, void_mls = imageruler.minimum_length_solid_void( - np.loadtxt(args.file) - ) - print("Minimum lengthscales of solid and void regions: ", solid_mls, void_mls) - - -if __name__ == "__main__": - main() diff --git a/imageruler/imageruler.py b/imageruler/imageruler.py deleted file mode 100644 index 8a05fb5..0000000 --- a/imageruler/imageruler.py +++ /dev/null @@ -1,931 +0,0 @@ -"""Imageruler for measuring minimum lengthscales in binary images.""" - -import enum -from typing import Callable, Optional, Tuple, Union -import warnings -import cv2 as cv -import numpy as np - -warnings.simplefilter('always') - -# Threshold used for binarization. -_BINARIZATION_THRESHOLD = 0.5 - -_PLUS_KERNEL = np.array( - [ - [0, 1, 0], - [1, 1, 1], - [0, 1, 0], - ], - dtype=np.uint8, -) - -Array = np.ndarray -PhysicalSize = Tuple[float, ...] -PixelSize = Tuple[float, ...] -MarginSize = Tuple[Tuple[float, float], ...] -PeriodicAxes = Tuple[int, ...] -Padding = Tuple[Tuple[int, int], Tuple[int, int]] - - -@enum.unique -class Direction(enum.Enum): - IN = 'in' - OUT = 'out' - BOTH = 'both' - - -@enum.unique -class PaddingMode(enum.Enum): - EDGE = 'edge' - SOLID = 'solid' - VOID = 'void' - - -@enum.unique -class KernelShape(enum.Enum): - CIRCLE = 'circle' - RECTANGLE = 'rectangle' - - -def minimum_length_solid( - array: Array, - phys_size: Optional[PhysicalSize] = None, - periodic_axes: Optional[PeriodicAxes] = None, - margin_size: Optional[MarginSize] = None, - pad_mode: PaddingMode = PaddingMode.SOLID, - kernel_shape: KernelShape = KernelShape.CIRCLE, - warn_cusp: bool = False, -) -> float: - """Computes the minimum length scale of the solid regions of an image. - - Args: - array: The 1D or 2D binarized image array. - phys_size: The extent of the image in physical units. If not specified, - pixel units are used for the returned length scale. - periodic_axes: The axes which are periodic. x is 0 and y is 1. If not - specified, no axes are treated as periodic. - margin_size: The physical dimensions of the image margins. If specified, - this subregion is excluded from the length scale measurement. Default is - no margins. - pad_mode: The padding mode to use at the image boundaries. Defaults to - solid. - kernel_shape: The kernel shape to use for probing the length scale. Defaults - to a circular kernel. - warn_cusp: Whether to warn about the presence of sharp corners or cusps - detected in the image. Default is False (no warning). - - Returns: - The minimum length scale of the solid regions in the input image. The units - are the same as those of `phys_size`. If `phys_size` is not specified, pixel - units are used. - """ - - array, pixel_size, short_pixel_side, short_entire_side = _initialize_ruler( - array, phys_size, periodic_axes, warn_cusp - ) - - # If all of the elements in the array are the same, - # the shorter length of the image is considered to - # be its minimum length scale. - if len(np.unique(array)) == 1: - return short_entire_side - - if array.ndim == 1: - if margin_size is not None: - array = _trim_margins(array, margin_size, pixel_size) - solid_min_length, _ = _minimum_length_1d(array) - return solid_min_length * short_pixel_side - - def _interior_pixel_number(diameter: float, array: Array) -> bool: - """Determines whether an image violates a given length scale.""" - return _length_violation_solid( - array=array, - diameter=diameter, - pixel_size=pixel_size, - margin_size=margin_size, - pad_mode=pad_mode, - kernel_shape=kernel_shape, - ).any() - - min_len, _ = _search( - (short_pixel_side, short_entire_side), - min(pixel_size) / 2, - lambda d: _interior_pixel_number(d, array), - ) - - return min_len - - -def minimum_length_void( - array: Array, - phys_size: Optional[PhysicalSize] = None, - periodic_axes: Optional[PeriodicAxes] = None, - margin_size: Optional[MarginSize] = None, - pad_mode: PaddingMode = PaddingMode.VOID, - kernel_shape: KernelShape = KernelShape.CIRCLE, - warn_cusp: bool = False, -) -> float: - """Computes the minimum length scale of the void regions of an image. - - Args: - array: The 1D or 2D binarized image array. - phys_size: The extent of the image in physical units. If not specified, - pixel units are used for the returned length scale. - periodic_axes: The axes which are periodic. x is 0 and y is 1. If not - specified, no axes are treated as periodic. - margin_size: The physical dimensions of the image margins. If specified, - this subregion is excluded from the length scale measurement. Default is - no margins. - pad_mode: The padding mode to use at the image boundaries. Defaults to void. - kernel_shape: The kernel shape to use for probing the length scale. Defaults - to a circular kernel. - warn_cusp: Whether to warn about the presence of sharp corners or cusps - detected in the image. Default is False (no warning). - - Returns: - The minimum length scale of the void regions in the input image. The units - are the same as those of `phys_size`. If `phys_size` is not specified, pixel - units are used. - """ - array, _, _, _ = _initialize_ruler(array, phys_size) - if pad_mode is PaddingMode.SOLID: - pad_mode = PaddingMode.VOID - elif pad_mode is PaddingMode.VOID: - pad_mode = PaddingMode.SOLID - else: - pad_mode = PaddingMode.EDGE - - return minimum_length_solid( - array=~array, - phys_size=phys_size, - periodic_axes=periodic_axes, - margin_size=margin_size, - pad_mode=pad_mode, - kernel_shape=kernel_shape, - warn_cusp=warn_cusp, - ) - - -def minimum_length_solid_void( - array: Array, - phys_size: Optional[PhysicalSize] = None, - periodic_axes: Optional[PeriodicAxes] = None, - margin_size: Optional[MarginSize] = None, - pad_mode: Tuple[PaddingMode, PaddingMode] = ( - PaddingMode.SOLID, - PaddingMode.VOID, - ), - kernel_shape: KernelShape = KernelShape.CIRCLE, - warn_cusp: bool = False, -) -> Tuple[float, float]: - """Computes the minimum length scale for both phases of an image. - - Args: - array: The 1D or 2D binarized image array. - phys_size: The extent of the image in physical units. If not specified, - pixel units are used for the returned length scale. - periodic_axes: The axes which are periodic. x is 0 and y is 1. If not - specified, no axes are treated as periodic. - margin_size: The physical dimensions of the image margins. If specified, - this subregion is excluded from the length scale measurement. Default is - no margins. - pad_mode: The padding mode to use at the image boundaries for each phase. - Defaults to solid for the solid phase and void for the void phase. - kernel_shape: The kernel shape to use for probing the length scale. Defaults - to a circular kernel. - warn_cusp: Whether to warn about the presence of sharp corners or cusps - detected in the image. Default is False (no warning). - - Returns: - The minimum length scale of the solid and void phases in the input image. - The units are the same as those of `phys_size`. If `phys_size` is not - specified, pixel units are used. - """ - return minimum_length_solid( - array=array, - phys_size=phys_size, - periodic_axes=periodic_axes, - margin_size=margin_size, - pad_mode=pad_mode[0], - kernel_shape=kernel_shape, - warn_cusp=warn_cusp, - ), minimum_length_void( - array=array, - phys_size=phys_size, - periodic_axes=periodic_axes, - margin_size=margin_size, - pad_mode=pad_mode[1], - kernel_shape=kernel_shape, - warn_cusp=warn_cusp, - ) - - -def minimum_length( - array: Array, - phys_size: Optional[PhysicalSize] = None, - periodic_axes: Optional[PeriodicAxes] = None, - margin_size: Optional[MarginSize] = None, - pad_mode: Union[PaddingMode, Tuple[PaddingMode, PaddingMode]] = ( - PaddingMode.SOLID, - PaddingMode.VOID, - ), - kernel_shape: KernelShape = KernelShape.CIRCLE, - warn_cusp: bool = False, -) -> float: - """Computes the minimum length scale of an image. - - Th returned value is the smaller of the minimum length scale of the solid and - void regions. For a 2D image, this is computed using the difference between - morphological opening and closing. For a 1d image, this is computed using - a brute-force search. - - Args: - array: The 1D or 2D binarized image array. - phys_size: The extent of the image in physical units. If not specified, - pixel units are used for the returned length scale. - periodic_axes: The axes which are periodic. x is 0 and y is 1. If not - specified, no axes are treated as periodic. - margin_size: The physical dimensions of the image margins. If specified, - this subregion is excluded from the length scale measurement. Default is - no margins. - pad_mode: The padding mode to use at the image boundaries for each phase. - Defaults to solid for the solid phase and void for the void phase. - kernel_shape: The kernel shape to use for probing the length scale. Defaults - to a circular kernel. - warn_cusp: Whether to warn about the presence of sharp corners or cusps - detected in the image. Default is False (no warning). - - Returns: - The minimum length scale of the solid and void phases in the input image. - The units are the same as those of `phys_size`. If `phys_size` is not - specified, pixel units are used. - """ - array, pixel_size, short_pixel_side, short_entire_side = _initialize_ruler( - array, phys_size, periodic_axes, warn_cusp - ) - - # If all of the elements in the array are the same, - # the shorter length of the image is considered to - # be its minimum length scale. - if len(np.unique(array)) == 1: - return short_entire_side - - if array.ndim == 1: - if margin_size is not None: - array = _trim_margins(array, margin_size, pixel_size) - solid_min_length, void_min_length = _minimum_length_1d(array) - return min(solid_min_length, void_min_length) * short_pixel_side - - if isinstance(pad_mode, PaddingMode): - pad_mode = (pad_mode, pad_mode) - - def _interior_pixel_number(diameter: float, arr: Array) -> bool: - """Determines whether an image violates a given length scale.""" - return _length_violation( - array=arr, - diameter=diameter, - pixel_size=pixel_size, - margin_size=margin_size, - pad_mode=pad_mode, - kernel_shape=kernel_shape, - ).any() - - min_len, _ = _search( - (short_pixel_side, short_entire_side), - min(pixel_size) / 2, - lambda d: _interior_pixel_number(d, array), - ) - - return min_len - - -def _length_violation_solid( - array: Array, - diameter: float, - pixel_size: PixelSize, - margin_size: Optional[Tuple[Tuple[float, float], ...]] = None, - pad_mode: PaddingMode = PaddingMode.SOLID, - kernel_shape: KernelShape = KernelShape.CIRCLE, -) -> Array: - """Identifies the solid subregions which contain length scale violations.""" - kernel = get_kernel(diameter, pixel_size, kernel_shape) - open_diff = binary_open(array, kernel, pad_mode) ^ array - interior_diff = open_diff & _get_interior(array, Direction.IN, pad_mode) - if margin_size is not None: - interior_diff = _trim_margins(interior_diff, margin_size, pixel_size) - - return interior_diff - - -def _length_violation( - array: Array, - diameter: float, - pixel_size: PixelSize, - margin_size: Optional[MarginSize] = None, - pad_mode: Tuple[PaddingMode, PaddingMode] = ( - PaddingMode.SOLID, - PaddingMode.VOID, - ), - kernel_shape: KernelShape = KernelShape.CIRCLE, -) -> Array: - """Identifies the subregions which contain length scale violations.""" - kernel = get_kernel(diameter, pixel_size, kernel_shape) - close_open_diff = binary_open(array, kernel, pad_mode[0]) ^ binary_close( - array, kernel, pad_mode[1] - ) - interior_diff = close_open_diff & _get_interior( - array, Direction.BOTH, pad_mode - ) - if margin_size is not None: - interior_diff = _trim_margins(interior_diff, margin_size, pixel_size) - return interior_diff - - -def length_violation_solid( - array: Array, - diameter: float, - phys_size: Optional[PhysicalSize] = None, - periodic_axes: Optional[PeriodicAxes] = None, - margin_size: Optional[MarginSize] = None, - pad_mode: PaddingMode = PaddingMode.SOLID, - kernel_shape: KernelShape = KernelShape.CIRCLE, -) -> Array: - """Identifies the solid subregions which contain length scale violations. - - Args: - array: The 2D binarized image array. - diameter: The diameter of the kernel for detecting length scale violations. - phys_size: The extent of the image in physical units. If not specified, - pixel units are used for the returned length scale. - periodic_axes: The axes which are periodic. x is 0 and y is 1. If not - specified, no axes are treated as periodic. - margin_size: The physical dimensions of the image margins. If specified, - this subregion is excluded from the length scale measurement. Default is - no margins. - pad_mode: The padding mode to use at the image boundaries. Defaults to void. - kernel_shape: The kernel shape to use for probing the length scale. Defaults - to a circular kernel. - - Returns: - An array indicating the solid length scale violations in the input image. - """ - - array, pixel_size, _, _ = _initialize_ruler(array, phys_size, periodic_axes) - assert array.ndim == 2 - return _length_violation_solid( - array=array, - diameter=diameter, - pixel_size=pixel_size, - margin_size=margin_size, - pad_mode=pad_mode, - kernel_shape=kernel_shape, - ) - - -def length_violation_void( - array: Array, - diameter: float, - phys_size: Optional[PhysicalSize] = None, - periodic_axes: Optional[PeriodicAxes] = None, - margin_size: Optional[MarginSize] = None, - pad_mode: str = 'void', - kernel_shape: KernelShape = KernelShape.CIRCLE, -) -> Array: - """Identifies the void subregions which contain length scale violations. - - Args: - array: The 2D binarized image array. - diameter: The diameter of the kernel for detecting length scale violations. - phys_size: The extent of the image in physical units. If not specified, - pixel units are used for the returned length scale. - periodic_axes: The axes which are periodic. x is 0 and y is 1. If not - specified, no axes are treated as periodic. - margin_size: The physical dimensions of the image margins. If specified, - this subregion is excluded from the length scale measurement. Default is - no margins. - pad_mode: The padding mode to use at the image boundaries. Defaults to void. - kernel_shape: The kernel shape to use for probing the length scale. Defaults - to a circular kernel. - - Returns: - An array indicating the void length scale violations in the input image. - """ - - array, pixel_size, _, _ = _initialize_ruler(array, phys_size, periodic_axes) - assert array.ndim == 2 - - if pad_mode is PaddingMode.SOLID: - pad_mode = PaddingMode.VOID - elif pad_mode is PaddingMode.VOID: - pad_mode = PaddingMode.SOLID - else: - pad_mode = PaddingMode.EDGE - - return _length_violation_solid( - array=~array, - diameter=diameter, - pixel_size=pixel_size, - margin_size=margin_size, - pad_mode=pad_mode, - kernel_shape=kernel_shape, - ) - - -def length_violation( - array: Array, - diameter: float, - phys_size: Optional[PhysicalSize] = None, - periodic_axes: Optional[PeriodicAxes] = None, - margin_size: Optional[MarginSize] = None, - pad_mode: Tuple[PaddingMode, PaddingMode] = ( - PaddingMode.SOLID, - PaddingMode.VOID, - ), - kernel_shape: KernelShape = KernelShape.CIRCLE, -) -> Array: - """Identifies the subregions which contain length scale violations. - - Args: - array: The 2D binarized image array. - diameter: The diameter of the kernel for detecting length scale violations. - phys_size: The extent of the image in physical units. If not specified, - pixel units are used for the returned length scale. - periodic_axes: The axes which are periodic. x is 0 and y is 1. If not - specified, no axes are treated as periodic. - margin_size: The physical dimensions of the image margins. If specified, - this subregion is excluded from the length scale measurement. Default is - no margins. - pad_mode: The padding mode to use at the image boundaries for each phase. - Defaults to solid for the solid phase and void for the void phase. - kernel_shape: The kernel shape to use for probing the length scale. Defaults - to a circular kernel. - - Returns: - An array indicating the length scale violations in the input image. - """ - - array, pixel_size, _, _ = _initialize_ruler(array, phys_size, periodic_axes) - assert array.ndim == 2 - if isinstance(pad_mode, PaddingMode): - pad_mode = (pad_mode, pad_mode) - - return _length_violation( - array=array, - diameter=diameter, - pixel_size=pixel_size, - margin_size=margin_size, - pad_mode=pad_mode, - kernel_shape=kernel_shape, - ) - - -def _initialize_ruler( - array: Array, - phys_size: PhysicalSize, - periodic_axes: Optional[PeriodicAxes] = None, - warn_cusp: bool = False, -) -> Tuple[Array, PixelSize, float, float]: - """Initializes the ruler. - - This function converts the input array to a boolean array without redundant - dimensions and computes some basic information about the image. - - Args: - array: The 2D binarized image array. - phys_size: The extent of the image in physical units. If not specified, - pixel units are used for the returned length scale. - periodic_axes: The axes which are periodic. x is 0 and y is 1. If not - specified, no axes are treated as periodic. - warn_cusp: Whether to warn about the presence of sharp corners or cusps - detected in the image. Default is False (no warning). - - Returns: - A tuple with four elements. The first is a Boolean array obtained by - squeezing and binarizing the input array, the second is an array that - contains the pixel size, the third is the length of the shorter side of - the pixel, and the fourth is the length of the shorter side of the image. - - Raises: - ValueError: If the physical size `phys_size` does not have the - expected format or the length of `phys_size` does not match the dimension - of the input array. - """ - - array = np.squeeze(array) - - if ( - isinstance(phys_size, Array) - or isinstance(phys_size, list) - or isinstance(phys_size, tuple) - ): - phys_size = np.squeeze(phys_size) - phys_size = phys_size[phys_size.nonzero()] # keep nonzero elements only - elif isinstance(phys_size, float) or isinstance(phys_size, int): - phys_size = [phys_size] - elif phys_size is None: - phys_size = array.shape - else: - raise ValueError('Invalid format of the physical size.') - - assert array.ndim == len( - phys_size - ), 'The physical size and the dimension of the input array do not match.' - assert array.ndim in ( - 1, - 2, - ), 'The current version of imageruler only supports 1d and 2d.' - - short_entire_side = min(phys_size) # shorter side of the entire design region - pixel_size = _get_pixel_size(array, phys_size) - short_pixel_side = min(pixel_size) # shorter side of a pixel - array = _binarize(array) # Boolean array - - if periodic_axes is not None: - if array.ndim == 2: - periodic_axes = np.array(periodic_axes) - reps = (2 if 0 in periodic_axes else 1, 2 if 1 in periodic_axes else 1) - array = np.tile(array, reps) - phys_size = np.array(phys_size) * reps - short_entire_side = min( - phys_size - ) # shorter side of the entire design region - else: # arr.ndim == 1 - array = np.tile(array, 2) - short_entire_side *= 2 - - if warn_cusp and array.ndim == 2: - harris = cv.cornerHarris( - array.astype(np.uint8), blockSize=5, ksize=5, k=0.04 - ) - if np.max(harris) > 5e-10: - warnings.warn('This image may contain sharp corners or cusps.') - - return array, pixel_size, short_pixel_side, short_entire_side - - -def _search( - arg_range: Tuple[float, float], - arg_threshold: float, - function: Callable[[float], bool], -) -> Tuple[float, bool]: - """Performs a binary search. - - Args: - arg_range: Initial range of the argument under search. - arg_threshold: Threshold of the argument range, below which the search - stops. - function: A function that returns True if the viariable is large enough but - False if the variable is not large enough. - - Returns: - A tuple with two elements. The first is a float that represents the search - result. The second is a Boolean value, which is True if the search indeed - happens, False if the condition for starting search is not satisfied in - the beginning. - - Raises: - RuntimeError: If `function` returns True at a smaller input viariable - but False at a larger input viariable. - """ - - args = [min(arg_range), (min(arg_range) + max(arg_range)) / 2, max(arg_range)] - - if not function(args[0]) and function(args[2]): - while abs(args[0] - args[2]) > arg_threshold: - arg = args[1] - if not function(arg): - args[0], args[1] = ( - arg, - (arg + args[2]) / 2, - ) # The current value is too small - else: - args[1], args[2] = ( - arg + args[0] - ) / 2, arg # The current value is still large - return args[1], True - elif not function(args[0]) and not function(args[2]): - return args[2], False - elif function(args[0]) and function(args[2]): - return args[0], False - else: - raise RuntimeError('The function is not monotonically increasing.') - - -def _minimum_length_1d(array: Array) -> Tuple[int, int]: - """Searches the minimum lengths of solid and void segments in a 1d array. - - Args: - array: A 1D boolean array. - - Returns: - A tuple of two integers. The first and second intergers represent the - numbers of pixels in the shortest solid and void segments, respectively. - """ - - array = np.append(array, ~array[-1]) - solid_lengths, void_lengths = [], [] - counter = 0 - - for idx in range(len(array) - 1): - counter += 1 - - if array[idx] != array[idx + 1]: - if array[idx]: - solid_lengths.append(counter) - else: - void_lengths.append(counter) - counter = 0 - - if len(solid_lengths) > 0: - solid_min_length = min(solid_lengths) - else: - solid_min_length = 0 - - if len(void_lengths) > 0: - void_min_length = min(void_lengths) - else: - void_min_length = 0 - - return solid_min_length, void_min_length - - -def _get_interior( - array: Array, - direction: Direction, - pad_mode: Union[PaddingMode, Tuple[PaddingMode, PaddingMode]], -) -> Array: - """Gets inner borders, outer borders, or union of inner and outer borders. - - Args: - array: A 2D array that represents an image. - direction: The direction indicating inner borders, outer borders, or a union - of inner and outer borders. - pad_mode: The padding mode to use. - - Returns: - A Boolean array in which all True elements are at and only at borders. - """ - if direction is Direction.IN: - return binary_erode(array, _PLUS_KERNEL, pad_mode) - elif direction is Direction.OUT: - return ~binary_dilate(array, _PLUS_KERNEL, pad_mode) - elif direction is Direction.BOTH: - eroded = binary_erode(array, _PLUS_KERNEL, pad_mode[0]) - dilated = binary_dilate(array, _PLUS_KERNEL, pad_mode[1]) - return ~dilated | eroded - else: - raise ValueError(f'Unknown direction: {direction.name}.') - - -def _get_pixel_size(array: Array, phys_size: PhysicalSize) -> PixelSize: - """Gets the pixel size from an array and physical size.""" - return tuple(p / s for p, s in zip(phys_size, array.shape)) - - -def _binarize(array: Array) -> Array: - """Binarizes the input array.""" - - return array > _BINARIZATION_THRESHOLD * max(array.flatten()) + ( - 1 - _BINARIZATION_THRESHOLD - ) * min(array.flatten()) - - -def get_kernel( - diameter: float, - pixel_size: PixelSize = (1.0, 1.0), - kernel_shape: KernelShape = KernelShape.CIRCLE, -) -> Array: - """Gets the kernel with a given diameter and pixel size. - - Args: - diameter: A float that represents the diameter of the kernel, which acts - like a probe. - pixel_size: A tuple, list, or array that represents the physical size of one - pixel in the image. - kernel_shape: The kernel shape to use. - - Returns: - An array of unsigned integers 0 and 1 representing the kernel for - morpological operations. - """ - - pixel_size = np.asarray(pixel_size) - shape = np.array(np.round(diameter / pixel_size), dtype=int) - - if shape[0] <= 2 and shape[1] <= 2: - return np.ones(shape, dtype=np.uint8) - - rounded_size = np.round(diameter / pixel_size - 1) * pixel_size - - if kernel_shape is KernelShape.CIRCLE: - x_tick = np.linspace(-rounded_size[0] / 2, rounded_size[0] / 2, shape[0]) - y_tick = np.linspace(-rounded_size[1] / 2, rounded_size[1] / 2, shape[1]) - x, y = np.meshgrid(x_tick, y_tick, sparse=True, indexing='ij') - return np.array(x**2 + y**2 <= diameter**2 / 4, dtype=np.uint8) - elif kernel_shape is KernelShape.RECTANGLE: - return np.ones(shape, dtype=np.uint8) - else: - raise ValueError(f'Unknown kernel shape: {kernel_shape.name}.') - - -def _get_padding_for_kernel(kernel: Array) -> Tuple[Padding, Padding]: - """Gets padding and unpadding width for a given kernel.""" - shape = kernel.shape - pad_width = ((shape[0],) * 2, (shape[1],) * 2) - unpad_width = ( - ( - pad_width[0][0] + (shape[0] + 1) % 2, - pad_width[0][1] - (shape[0] + 1) % 2, - ), - ( - pad_width[1][0] + (shape[1] + 1) % 2, - pad_width[1][1] - (shape[1] + 1) % 2, - ), - ) - return pad_width, unpad_width - - -def binary_open( - array: Array, - kernel: Array, - pad_mode: PaddingMode = PaddingMode.EDGE, -) -> Array: - """Applies a binary morphological opening. - - Args: - array: A binarized 2D array that represents a binary image. - kernel: The kernel to use. - pad_mode: The padding mode. - - Returns: - A boolean array that represents the outcome of morphological opening. - """ - pad_width, unpad_width = _get_padding_for_kernel(kernel) - array = _apply_padding(array, pad_width, pad_mode) - opened = cv.morphologyEx(src=array, kernel=kernel, op=cv.MORPH_OPEN) - return _remove_padding(opened, unpad_width).view(bool) - - -def binary_close( - arr: Array, - kernel: Array, - pad_mode: PaddingMode = PaddingMode.EDGE, -) -> Array: - """Applies a binary morphological closing. - - Args: - arr: A binarized 2D array that represents a binary image. - kernel: The kernel to use. - pad_mode: The padding mode. - - Returns: - A boolean array that represents the outcome of morphological closing. - """ - pad_width, unpad_width = _get_padding_for_kernel(kernel) - arr = _apply_padding(arr, pad_width, pad_mode) - closed = cv.morphologyEx(src=arr, kernel=kernel, op=cv.MORPH_CLOSE) - return _remove_padding(closed, unpad_width).view(bool) - - -def binary_erode( - array: Array, - kernel: Array, - pad_mode: PaddingMode = PaddingMode.EDGE, -) -> Array: - """Applies a binary morphological erosion. - - Args: - array: A binarized 2D array that represents a binary image. - kernel: The kernel to use. - pad_mode: The padding mode. - - Returns: - A boolean array that represents the outcome of morphological erosion. - """ - pad_width, unpad_width = _get_padding_for_kernel(kernel) - array = _apply_padding(array, pad_width, pad_mode) - eroded = cv.erode(array, kernel) - return _remove_padding(eroded, unpad_width).view(bool) - - -def binary_dilate( - array: Array, - kernel: Array, - pad_mode: PaddingMode = PaddingMode.EDGE, -) -> Array: - """Applies a binary morphological dilation. - - Args: - array: A binarized 2D array that represents a binary image. - kernel: The kernel to use. - pad_mode: The padding mode. - - Returns: - A boolean array that represents the outcome of morphological dilation. - """ - pad_width, unpad_width = _get_padding_for_kernel(kernel) - array = _apply_padding(array, pad_width, pad_mode) - dilated = cv.dilate(array, kernel) - return _remove_padding(dilated, unpad_width).view(bool) - - -def _apply_padding( - array: Array, pad_width: Padding, pad_mode: PaddingMode -) -> Array: - """Applies padding to the input array.""" - ((top, bottom), (left, right)) = pad_width - if pad_mode is PaddingMode.EDGE: - return cv.copyMakeBorder( - array.view(np.uint8), - top=top, - bottom=bottom, - left=left, - right=right, - borderType=cv.BORDER_REPLICATE, - ) - elif pad_mode is PaddingMode.SOLID: - return cv.copyMakeBorder( - array.view(np.uint8), - top=top, - bottom=bottom, - left=left, - right=right, - borderType=cv.BORDER_CONSTANT, - value=1, - ) - elif pad_mode is PaddingMode.VOID: - return cv.copyMakeBorder( - array.view(np.uint8), - top=top, - bottom=bottom, - left=left, - right=right, - borderType=cv.BORDER_CONSTANT, - value=0, - ) - else: - raise ValueError(f'Unknown padding mode: {pad_mode.name}.') - - -def _remove_padding(array: Array, pad_width: Padding) -> Array: - """Removes padding from the input array.""" - slices = tuple( - slice(pad_lo, dim - pad_hi) - for (pad_lo, pad_hi), dim in zip(pad_width, array.shape) - ) - return array[slices] - - -def _trim_margins( - array: Array, margin_size: MarginSize, pixel_size: PixelSize -) -> Array: - """Trims margins from an array. - - Args: - array: The 1D or 2D binarized image array. - margin_size: The physical dimensions of the image margins. If specified, - this subregion is excluded from the length scale measurement. Default is - no margins. - pixel_size: The physical size of one pixel in the image. - - Returns: - The input array with the sepecified margins trimmed. - """ - - array = np.squeeze(array) - arr_dim = array.ndim - margin_size = abs(np.reshape(margin_size, (-1, 2))) - margin_dim = len(margin_size) - - if margin_dim > arr_dim: - raise ValueError( - 'The number of rows of margin_size should not ' - 'exceed the dimension of the input array.' - ) - - pixel_size = np.asarray(pixel_size) - margin_number = np.array(margin_size) / pixel_size[ - 0 : len(margin_size) - ].reshape(len(margin_size), 1) - margin_number = np.round(margin_number).astype( - int - ) # numbers of pixels of marginal regions - - if ( - np.array(array.shape)[0:margin_dim] - np.sum(margin_number, axis=1) < 2 - ).all(): - raise ValueError( - 'The design region is too narrow or contains ' - 'margins which are too wide.' - ) - - if margin_dim == 1: - return array[margin_number[0][0] : -margin_number[0][1]] - elif margin_dim == 2: - return array[ - margin_number[0][0] : -margin_number[0][1], - margin_number[1][0] : -margin_number[1][1], - ] - else: - raise ValueError('The input array has too many dimensions.') diff --git a/imageruler/regular_shapes.py b/imageruler/regular_shapes.py deleted file mode 100644 index cc90829..0000000 --- a/imageruler/regular_shapes.py +++ /dev/null @@ -1,171 +0,0 @@ -"""Regular shapes.""" - -from typing import Tuple -import numpy as np - - -def rounded_square( - resolution: float, - phys_size: Tuple[float, float], - declared_mls: float, - center: Tuple[float, float] = (0, 0), - angle: float = 0, -) -> np.ndarray: - """Return a Boolean array where all True elements form a square with rounded corners. - - Args: - resolution: A float that represents the number of points per unit length. - phys_size: A tuple with two elements that describe the physical size of - the entire pattern. - declared_mls: A float that represents the declared minimum length scale, - which is equal to the diameter of round corners. - center: A tuple with two elements that describe the coordinates of the - center of the square. - angle: A float that represents the angle of rotation in degree. - - Returns: - An array with Boolean elements. - """ - - phys_size = np.array(phys_size) - angle = np.radians(angle) - - n = np.round(phys_size * resolution).astype( - int - ) # number of pixels along each dimension - grid_size = ( - n - 1 - ) / resolution # size of the entire pattern formed by centers of pixels - - x_coord = np.linspace(-grid_size[0] / 2, grid_size[0] / 2, n[0]) - y_coord = np.linspace(-grid_size[1] / 2, grid_size[1] / 2, n[1]) - xv, yv = np.meshgrid(x_coord, y_coord, sparse=True, indexing='ij') - - side, diameter = 2 * declared_mls, declared_mls - rect_vert = ( - abs(np.sin(angle) * (xv - center[0]) - np.cos(angle) * (yv - center[1])) - <= (side - diameter) / 2 - ) & ( - abs(np.cos(angle) * (xv - center[0]) + np.sin(angle) * (yv - center[1])) - <= side / 2 - ) - rect_hori = ( - abs(np.sin(angle) * (xv - center[0]) - np.cos(angle) * (yv - center[1])) - <= side / 2 - ) & ( - abs(np.cos(angle) * (xv - center[0]) + np.sin(angle) * (yv - center[1])) - <= (side - diameter) / 2 - ) - - disc_centers = ( - np.array([ - [ - side - diameter, - diameter - side, - diameter - side, - side - diameter, - ], - [ - side - diameter, - side - diameter, - diameter - side, - diameter - side, - ], - ]) - / 2 - ) - disc_centers_x = ( - disc_centers[0, :] * np.cos(angle) - - disc_centers[1, :] * np.sin(angle) - + center[0] - ) - disc_centers_y = ( - disc_centers[0, :] * np.sin(angle) - + disc_centers[1, :] * np.cos(angle) - + center[1] - ) - disc_centers = np.vstack((disc_centers_x, disc_centers_y)) - - disc0 = (xv - disc_centers[0, 0]) ** 2 + ( - yv - disc_centers[1, 0] - ) ** 2 <= diameter**2 / 4 - disc1 = (xv - disc_centers[0, 1]) ** 2 + ( - yv - disc_centers[1, 1] - ) ** 2 <= diameter**2 / 4 - disc2 = (xv - disc_centers[0, 2]) ** 2 + ( - yv - disc_centers[1, 2] - ) ** 2 <= diameter**2 / 4 - disc3 = (xv - disc_centers[0, 3]) ** 2 + ( - yv - disc_centers[1, 3] - ) ** 2 <= diameter**2 / 4 - - return rect_vert | rect_hori | disc0 | disc1 | disc2 | disc3 - - -def disc( - resolution: float, - phys_size: Tuple[float, float], - diameter: float, - center: Tuple[float, float] = (0, 0), -) -> np.ndarray: - """Return a Boolean array where all True elements form a disc. - - Args: - resolution: A float that represents the number of points per unit length. - phys_size: A tuple with two elements that describe the physical size of - the entire pattern. - diameter: A float that represents the diameter of the disc. - center: A tuple with two elements that describe the coordinates of the - center of the square. - - Returns: - An array with Boolean elements. - """ - - phys_size = np.array(phys_size) - grid_size = phys_size - 1 / resolution - n = np.round(phys_size * resolution).astype(int) - - x_coord = np.linspace(-grid_size[0] / 2, grid_size[0] / 2, n[0]) - y_coord = np.linspace(-grid_size[1] / 2, grid_size[1] / 2, n[1]) - xv, yv = np.meshgrid(x_coord, y_coord, sparse=True, indexing='ij') - - return (xv - center[0]) ** 2 + (yv - center[1]) ** 2 <= diameter**2 / 4 - - -def stripe( - resolution: float, - phys_size: Tuple[float, float], - width, - center: Tuple[float, float] = (0, 0), - angle: float = 0, -) -> np.ndarray: - """Return a Boolean array where all True elements form a disc. - - Args: - resolution: A float that represents the number of points per unit length. - phys_size: A tuple with two elements that describe the physical size of - the entire pattern. - width: A float that represents the width of the stripe. - center: A tuple with two elements that describe the coordinates of the - center of the stripe. - angle: A float that represents the angle of rotation in degree. - - Returns: - An array with Boolean elements. - """ - - phys_size = np.array(phys_size) - angle = np.radians(angle) - - grid_size = phys_size - 1 / resolution - n = np.round(phys_size * resolution).astype(int) - - x_coord = np.linspace(-grid_size[0] / 2, grid_size[0] / 2, n[0]) - y_coord = np.linspace(-grid_size[1] / 2, grid_size[1] / 2, n[1]) - xv, yv = np.meshgrid(x_coord, y_coord, sparse=True, indexing='ij') - - return ( - abs(np.sin(angle) * (xv - center[0]) - np.cos(angle) * (yv - center[1])) - <= width / 2 - ) diff --git a/imageruler/test_imageruler.py b/imageruler/test_imageruler.py deleted file mode 100755 index 986e01f..0000000 --- a/imageruler/test_imageruler.py +++ /dev/null @@ -1,181 +0,0 @@ -"""Tests for imageruler.""" - -import unittest -import imageruler -import numpy as np - -try: - from imageruler.regular_shapes import disc, rounded_square, stripe -except: - from regular_shapes import disc, rounded_square, stripe - - -# properties of design weights array -resolution = 1 -phys_size = (200, 200) - - -class TestDuality(unittest.TestCase): - diameters = [2.2, 45.2, 50.1, 80.2, 101.5] - - def duality_dilation_erosion(self, weights: np.ndarray, diam: float) -> bool: - """Checks the duality of the dilation and erosion operators for solid - - and void features of the design weights. - - Args: - weights: the design weights as a 2d array. - diam: the diameter of the circular-ball kernel. - - Returns: - A Boolean indicating whether duality is satisfied or not. - """ - kernel = imageruler.get_kernel(diam) - erosion_of_negation = imageruler.binary_erode(~weights, kernel) - negation_of_dilation = ~imageruler.binary_dilate(weights, kernel) - dilation_of_negation = imageruler.binary_dilate(~weights, kernel) - negation_of_erosion = ~imageruler.binary_erode(weights, kernel) - return (erosion_of_negation == negation_of_dilation).all() and ( - negation_of_erosion == dilation_of_negation - ).all() - - def duality_closing_opening(self, weights: np.ndarray, diam: float) -> bool: - """Checks the duality of the opening and closing morphological transform - - operators for solid and void features of the design weights. - - Args: - weights: the design weights as a 2d array. - diam: the diameter of the circular-ball kernel. - - Returns: - A Boolean indicating whether duality is satisfied or not. - """ - kernel = imageruler.get_kernel(diam) - opening_of_negation = imageruler.binary_open(~weights, kernel) - negation_of_closing = ~imageruler.binary_close(weights, kernel) - closing_of_negation = imageruler.binary_close(~weights, kernel) - negation_of_opening = ~imageruler.binary_open(weights, kernel) - return (opening_of_negation == negation_of_closing).all() and ( - closing_of_negation == negation_of_opening - ).all() - - def test_rounded_square(self): - print("------ Testing duality property using rounded squares ------") - - declared_mls: float = 50.0 - for angle in [0, 10.5, 44.3, 73.9]: - print(f"Rotation angle of the rounded square: {angle}°") - pattern = rounded_square(resolution, phys_size, declared_mls, angle=angle) - for diameter in self.diameters: - print(f"Kernel diameter: {diameter:.2f}") - self.assertTrue(self.duality_dilation_erosion(pattern, diameter)) - self.assertTrue(self.duality_closing_opening(pattern, diameter)) - - def test_disc(self): - print("------ Testing duality property using a disc ------") - - diam = 50.0 - pattern = disc(resolution, phys_size, diam) - for diameter in self.diameters: - print(f"Kernel diameter: {diameter:.2f}") - self.assertTrue(self.duality_dilation_erosion(pattern, diameter)) - self.assertTrue(self.duality_closing_opening(pattern, diameter)) - - def test_ring(self): - print("------ Testing duality property using concentric circles ------") - - outer_diameter, inner_diameter = 120, 50 - declared_solid_mls, declared_void_mls = ( - outer_diameter - inner_diameter - ) / 2, inner_diameter - print( - f"Declared minimum length scale: {declared_solid_mls:.2f} " - f"(solid), {declared_void_mls:.2f} (void)" - ) - - solid_disc = disc(resolution, phys_size, diameter=outer_diameter) - void_disc = disc(resolution, phys_size, diameter=inner_diameter) - pattern = solid_disc ^ void_disc # ring - - for diameter in self.diameters: - print(f"Kernel diameter: {diameter:.2f}") - self.assertTrue(self.duality_dilation_erosion(pattern, diameter)) - self.assertTrue(self.duality_closing_opening(pattern, diameter)) - - -class TestMinimumLengthScale(unittest.TestCase): - - def test_rounded_square(self): - print("------ Testing minimum length scale of rounded squares ------") - - declared_mls = 50 - print("Declared minimum length scale: ", declared_mls) - - for angle in [5.6, 25.2, 49.3, 69.5]: - pattern = rounded_square(resolution, phys_size, declared_mls, angle=angle) - solid_mls = imageruler.minimum_length_solid(pattern) - print(f"Rotation angle of the rounded square: {angle}°") - print(f"Estimated minimum length scale: {solid_mls:.2f}") - self.assertAlmostEqual(solid_mls, declared_mls, delta=4) - - def test_disc(self): - print("------ Testing minimum length scale of a disc ------") - - diameter = 50 - print(f"Declared minimum length scale: {diameter}") - pattern = disc(resolution, phys_size, diameter) - solid_mls = imageruler.minimum_length_solid(pattern, phys_size) - print(f"Estimated minimum length scale: {solid_mls:.2f}") - self.assertAlmostEqual(solid_mls, diameter, delta=1) - - def test_ring(self): - print("------ Testing minimum length scale of concentric circles ------") - - outer_diameter, inner_diameter = 120, 50 - declared_solid_mls, declared_void_mls = ( - outer_diameter - inner_diameter - ) / 2, inner_diameter - print( - f"Declared minimum length scale: {declared_solid_mls:.2f} " - f"(solid), {declared_void_mls:.2f} (void)" - ) - - solid_disc = disc(resolution, phys_size, diameter=outer_diameter) - void_disc = disc(resolution, phys_size, diameter=inner_diameter) - pattern = solid_disc ^ void_disc # ring - - solid_mls = imageruler.minimum_length_solid(pattern) - void_mls = imageruler.minimum_length_void(pattern) - dual_mls = imageruler.minimum_length(pattern) - print( - f"Estimated minimum length scale: {solid_mls:.2f} (solid), ", - f"{void_mls:.2f} (void)", - ) - - self.assertAlmostEqual(solid_mls, declared_solid_mls, delta=1) - self.assertAlmostEqual(void_mls, declared_void_mls, delta=1) - self.assertAlmostEqual( - dual_mls, min(declared_solid_mls, declared_void_mls), delta=1 - ) - self.assertEqual(dual_mls, min(solid_mls, void_mls)) - - def test_periodicity(self): - print("------ Testing minimum length scale on a periodic image ------") - - stripe_width = 50 - print(f"Declared minimum length scale: {stripe_width}") - pattern = stripe( - resolution, phys_size, stripe_width, center=(0, -phys_size[1] / 2) - ) | stripe( - resolution, phys_size, stripe_width, center=(0, phys_size[1] / 2) - ) - solid_mls = imageruler.minimum_length_solid( - pattern, phys_size, periodic_axes=1 - ) - print(f"Estimated minimum length scale: {solid_mls:.2f}") - self.assertAlmostEqual(solid_mls, stripe_width, delta=1) - - -if __name__ == "__main__": - unittest.main() diff --git a/notebooks/examples.ipynb b/notebooks/examples.ipynb deleted file mode 100644 index 5899cee..0000000 --- a/notebooks/examples.ipynb +++ /dev/null @@ -1,540 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "#import sys # Uncomment this and the next line if imageruler is cloned rather than installed.\n", - "#sys.path.append(\"../imageruler\")\n", - "import imageruler\n", - "from matplotlib import pyplot as plt\n", - "# In the next line, remove \"imageruler.\" if imageruler is cloned rather than installed.\n", - "from imageruler.regular_shapes import disc, rounded_square, stripe # Import functions that generate regular shapes." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Examples based on regular 2d shapes are as follows." - ] - }, - { - "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" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Declared minimum length scale of the solid region: 50\n", - "Estimated minimum length scale of the solid region: 50.9443359375\n" - ] - } - ], - "source": [ - "resolution = 1 # number of pixels per unit length\n", - "phys_size = (200, 200) # physical size of the entire image\n", - "declared_mls = 50 # declared minimum length scale\n", - "\n", - "image = rounded_square(resolution, phys_size, declared_mls, angle=20) # generate a rounded square\n", - "\n", - "plt.figure()\n", - "plt.imshow(image)\n", - "plt.show()\n", - "\n", - "solid_mls = imageruler.minimum_length_solid(image) # estimate the minimum length scale of the solid region\n", - "print(\"Declared minimum length scale of the solid region: \", declared_mls)\n", - "print(\"Estimated minimum length scale of the solid region: \", solid_mls)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAQEAAAD8CAYAAAB3lxGOAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAARvUlEQVR4nO3df7DVdZ3H8eeLexFD8gebsgiI6EAz2rQ3ZbRgc23d8se4gZUJqWE6iznQ1E7tpG2ZZW3NlrmWxQ4WI26KsiLFNIylzG6sq5VgpKIJiCiXn6WpGWbcy3v/ON+bJ7y3e/d8v1++55zP6zFz55zzOd9zvu8PR1/3++Pc71sRgZmla1jVBZhZtRwCZolzCJglziFgljiHgFniHAJmiSstBCSdJekJSZskXVnWeswsH5XxPQFJHcAG4J1AN/AgMDsiHit8ZWaWS1lbAqcAmyJic0T8AbgdmFHSuswsh86S3nccsLXucTdw6kALH6QRcTCHlFSKmQH8lt/8OiKO3H+8rBBQP2N/st8haS4wF+BgRnKqziipFDMDuDfufLq/8bJ2B7qBCXWPxwPb6xeIiIURMTUipg5nREllmNlgygqBB4HJkiZJOgiYBawoaV1mlkMpuwMR0SNpPvBDoANYFBHry1iXmeVT1jEBImIlsLKs9zezYvgbg2aJcwiYJc4hYJY4h4BZ4hwCZolzCJglziFgljiHgFniHAJmiXMImCXOIWCWOIeAWeIcAmaJcwiYJc4hYJY4h4BZ4hwCZolzCJglruEQkDRB0n9JelzSekkfzcavkbRN0rrs55ziyjWzouW5xmAP8PGIeEjS64G1ku7Jnrs+Ir6avzwzK1vDIRARO4Ad2f3fSnqcWuchM2shhRwTkHQs8Bbgp9nQfEkPS1ok6Ygi1mFm5cgdApJGAcuAj0XEi8AC4Higi9qWwnUDvG6upDWS1uzllbxlmFmDcoWApOHUAuDWiLgLICJ2RURvROwDbqLWofg13IbMrDnkOTsg4DvA4xHxtbrxsXWLnQc82nh5Zla2PGcHpgMXA49IWpeNfQqYLamLWhfiLcDlOdZhZiXLc3bgPvpvQe7WY2YtxN8YNEucQ8AscQ4Bs8Q5BMwS5xAwS5xDwCxxDgGzxDkEzBLnEDBLnEPALHEOAbPEOQTMEucQMEucQ8AscQ4Bs8Q5BMwS5xAwS5xDwCxxDgGzxOW50CiStgC/BXqBnoiYKmk0cAdwLLULjb4/In6Tr0wzK0sRWwLviIiuiJiaPb4SWBURk4FV2WMza1Jl7A7MABZn9xcDM0tYh5kVJG8IBPAjSWslzc3GxmTNSvualh7V3wvdhsysOeQ6JgBMj4jtko4C7pH0y6G+MCIWAgsBDtXoyFmHmTUo15ZARGzPbncDy6n1HdzV14osu92dt0gzK0+eXoSHSHp9333gXdT6Dq4A5mSLzQG+n7dIMytPnt2BMcDyWl9SOoHbIuJuSQ8CSyVdBjwDnJ+/TDMrS55ehJuBv+pn/FngjDxFmdmB428MmiXOIWCWOIeAWeIcAmaJcwiYJc4hYJY4h4BZ4hwCZolzCJglziFgljiHgFniHAJmiXMImCXOIWCWOIeAWeIcAmaJcwiYJc4hYJa4hi8vJumN1NqN9TkOuBo4HPgH4FfZ+KciYmWj6zGzcuW5xuATQBeApA5gG7XLjn8IuD4ivlpEgWZWrrzNR/qcATwZEU9nVx+2NtE57mj2TjxySMsOf2oXPTt2llyRFa2oEJgFLKl7PF/SB4E1wMf760qctS2bC3AwIwsqw/LqHD8OOl49VLRh3ng2XrRgSK+dcssVTF4w/NWBnl56tm0vukQrmCLydQCTdBCwHTgxInZJGgP8mlqfwmuBsRFx6Z97j0M1Ok6Vr1JepWEja0H8iUd+yhmv6y3kPe/eM4Ib3nwyAPv27CnkPa1x98ada+u6h/9REVsCZwMPRcQugL5bAEk3AT8oYB1WJokfbLyPDhV7suiska9w1qb76Y19nDPupELf24pTxKc+m7pdgb4+hJnzqLUmsybUOWkiK7c9xMrutYUHQL0ODautZ9tDdB57TGnrscbk+uQljQTeCdxVN/yvkh6R9DDwDuAf86zDyhHTu/j2j2+lQ8NKDYA+fev59urbiLe9pnGVVSjX7kBE7AH+Yr+xi3NVZKXa+bFpXDvvZg7vWMfYzlEHfP1jO0fx6VsX83zvSK7++iWM+cb9B7wG+1NFnR2wFvDM1dP40sW38O5Dqj1Id9rBAHvY+5Hv8pnDLmLCFxwEVfLXhhOx5Qtv45MfuJOZh7xUdSl/9N5RL/LxC+/i6c+/repSkuYQSMAzV0/jqvct45JDd1ddymtcdthO/un85Wz9zLSqS0mWQ6DN7fxYbRegGQOgz2WH7eTai7/Lzo86CKrgEGhz1867ual2AQby3lEv8rn5t1RdRpIcAm0spndxeEfrfFPv8GF7iOldVZeRHIdAm+qcNJHFS27MjsS3htNft49FS26kc9LEqktJikOgTa24b3kl3wPIa3znKL53312DL2iFcQi0o3b4c+52mEOLcAi0mWEjR5b+twBlG64OVnavZdjBLbQv08Ja978UG1ArB0CfdphDq/C/dBvpHD+OTzzy06rLKMwn1j9I59i/rLqMtucQaCcdwwq7IEgzOON1vdDRUXUZbc8hYJY4h4BZ4hwCbaJz3NFsmDe+6jIKt+Ejx/i4QMkcAm1i78Qjh3xV4Fay8eIF9Ew8quoy2ppDwCxxg4aApEWSdkt6tG5stKR7JG3Mbo+oe+4qSZskPSHpzLIKN7NiDGVL4GbgrP3GrgRWRcRkYFX2GEknUGtEcmL2mm9lLcrMrEkNGgIRsRp4br/hGcDi7P5iYGbd+O0R8UpEPAVsAk4pplQzK0OjxwTGRMQOgOy278jNOGBr3XLd2ZiZNamirzbc359+9dvnzL0IzZpDo1sCu/o6DWW3fRew6wYm1C03nlqfwteIiIURMTUipg5nRINlmFlejYbACmBOdn8O8P268VmSRkiaBEwGfpavRDMr06C7A5KWAKcDb5DUDXwW+DKwVNJlwDPA+QARsV7SUuAxoAeYFxHt8xctZm1o0BCIiNkDPNVvL/GI+CLwxTxF2f/f8Kd2MeWWK9jwwfb61uCUxVcwectmeqoupI35G4NtomfHTiYv6K66jMJN/uYz9OzcNfiC1jCHgFniHAJmiXMItJOeXu7e0z6nW+/eMwJ6fVy5bA6BNtKzbTs3vPnkqssozA1vegs9O3ZWXUbbcwi0od7YV3UJubXDHFqFQ6DN7Nuzh3PGndTS/xPtjV7OGXcS+37/+6pLSYJDwCxxDoE29e5pM9jR0/wtyffX3fMSM6fNrLqMpDgE2lTP01uZc8E8VrfQFvV/vzyMSy+YR8/TWwdf2ArjEGhjeuAXPN/bOn+m/fy+keiBX1RdRnIcAm3u6q9fwrKXDq26jEEtfekwPnfDB6suI0kOgTY35hv385lbLuI7LzTvtfsXvnA0n7v5Qo668f6qS0mSQyABE75wP1/5z/OaMggWvnA0198xk/H/4gCoikMgEROvfoDrbntPU+0aLH3pMG74j5kcc40DoEpFX2PQmtiEa+/n8y9eBPO+y+Edv6usg/Gqlzt4vvcQvvT1CxnvXYDKKaLf64AeUIdqdJyqfq9RYiWJ6V0sWnIj4ztHHdD1dve8xKUXzPNZgArcG3eujYip+497dyBR+t91XP43F7I3etl7AK4A17eey0/7gAOgyQzlGoOLgHOB3RHxpmzsK8DfA38AngQ+FBHPSzoWeBx4Inv5TyLiw2UUbvn1PPU05447GSRWdq+lQ+X8TuiNfbX1ALVLUlozabQN2T3AmyLizcAG4Kq6556MiK7sxwHQCiI49/hpnH3cW1n1cnFd4+7eM4Kzj3sr5x4/rbD3tOIN5UKjq7Pf8PVjP6p7+BPgfQXXZQdY31/sfe2v38nXOl4Ngg0fOYaNFw/t4qVTFl/B5G/W/abv7WXf7309gGZXxNmBS4E76h5PkvRz4EXg0xHxPwWsww6Q/S/iMeXfejlz+dC+yTd5y2ZfFLQF5QoBSf9Mrb/ArdnQDuCYiHhW0snA9ySdGBEv9vNatyFrAT07dsIQr+7jy4K3poaPBEmaQ+2A4YWRnWfMuhE/m91fS+2g4ZT+Xu82ZGbNoaEQkHQW8Eng3RGxp278SEkd2f3jqLUh21xEoWZWjkbbkF0FjADukQSvngo8Dfi8pB6gF/hwRDxXUu1mVoBG25B9Z4BllwHL8hZlZgeOvzFoljiHgFniHAJmiXMImCXOIWCWOIeAWeIcAmaJcwiYJc4hYJY4h4BZ4hwCZolzCJglziFgljiHgFniHAJmiXMImCXOIWCWOIeAWeIGDQFJiyTtlvRo3dg1krZJWpf9nFP33FWSNkl6QtKZZRVuZsVotA0ZwPV17cZWAkg6AZgFnJi95lt9Vx82s+Y0aAhExGpgqFcMngHcnvUfeArYBJySoz4zK1meYwLzJT2c7S4ckY2NA7bWLdOdjZlZk2o0BBYAxwNd1FqPXZeNq59lo783kDRX0hpJa/bySoNlmFleDYVAROyKiN6I2AfcxKub/N3AhLpFxwPbB3gPtyEzawKNtiEbW/fwPKDvzMEKYJakEZImUWtD9rN8JZpZmRptQ3a6pC5qm/pbgMsBImK9pKXAY9Sa1M6LiN5SKjezQihrKFypQzU6TtUZVZdh1tbujTvXRsTU/cf9jUGzxDkEzBLnEDBLnEPALHEOAbPEOQTMEucQMEucQ8AscQ4Bs8Q5BMwS5xAwS5xDwCxxDgGzxDkEzBLnEDBLnEPALHEOAbPEOQTMEtdoG7I76lqQbZG0Lhs/VtLLdc/9e4m1m1kBBr3QKLU2ZDcCt/QNRMQFffclXQe8ULf8kxHRVVB9ZlayQUMgIlZLOra/5yQJeD/wtwXXZWYHSN5jAm8HdkXExrqxSZJ+LunHkt6e8/3NrGRD2R34c2YDS+oe7wCOiYhnJZ0MfE/SiRHx4v4vlDQXmAtwMCNzlmFmjWp4S0BSJ/Ae4I6+sawb8bPZ/bXAk8CU/l7vNmRmzSHP7sDfAb+MiO6+AUlHSurI7h9HrQ3Z5nwlmlmZhnKKcAnwAPBGSd2SLsuemsWf7goAnAY8LOkXwJ3AhyPiuSILNrNiDeXswOwBxi/pZ2wZsCx/WWZ2oPgbg2aJcwiYJc4hYJY4h4BZ4hwCZolzCJglziFgljiHgFniHAJmiXMImCXOIWCWOIeAWeIcAmaJcwiYJc4hYJY4h4BZ4hwCZolzCJglziFgljiHgFniHAJmiXMImCVOEVF1DUj6FfA74NdV11KCN9Ce84L2nVu7zmtiRBy5/2BThACApDURMbXqOorWrvOC9p1bu85rIN4dMEucQ8Ascc0UAgurLqAk7TovaN+5teu8+tU0xwTMrBrNtCVgZhWoPAQknSXpCUmbJF1ZdT15Sdoi6RFJ6yStycZGS7pH0sbs9oiq6xyMpEWSdkt6tG5swHlIuir7DJ+QdGY1VQ/NAHO7RtK27HNbJ+mcuudaZm6NqDQEJHUA3wTOBk4AZks6ocqaCvKOiOiqO810JbAqIiYDq7LHze5m4Kz9xvqdR/aZzQJOzF7zreyzbVY389q5AVyffW5dEbESWnJu/29VbwmcAmyKiM0R8QfgdmBGxTWVYQawOLu/GJhZXSlDExGrgef2Gx5oHjOA2yPilYh4CthE7bNtSgPMbSAtNbdGVB0C44CtdY+7s7FWFsCPJK2VNDcbGxMROwCy26Mqqy6fgebRLp/jfEkPZ7sLfbs67TK3AVUdAupnrNVPV0yPiJOo7eLMk3Ra1QUdAO3wOS4Ajge6gB3Addl4O8ztz6o6BLqBCXWPxwPbK6qlEBGxPbvdDSyntum4S9JYgOx2d3UV5jLQPFr+c4yIXRHRGxH7gJt4dZO/5ec2mKpD4EFgsqRJkg6idgBmRcU1NUzSIZJe33cfeBfwKLU5zckWmwN8v5oKcxtoHiuAWZJGSJoETAZ+VkF9DesLt8x51D43aIO5DaazypVHRI+k+cAPgQ5gUUSsr7KmnMYAyyVB7d/2toi4W9KDwFJJlwHPAOdXWOOQSFoCnA68QVI38Fngy/Qzj4hYL2kp8BjQA8yLiN5KCh+CAeZ2uqQuapv6W4DLofXm1gh/Y9AscVXvDphZxRwCZolzCJglziFgljiHgFniHAJmiXMImCXOIWCWuP8DofQ/mVLAWGsAAAAASUVORK5CYII=\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Declared minimum length scale of the solid region: 50\n", - "Estimated minimum length scale of the solid region: 49.0009765625\n" - ] - } - ], - "source": [ - "diameter = 50\n", - "image = disc(resolution, phys_size, diameter) # generate a disc\n", - "\n", - "plt.figure()\n", - "plt.imshow(image)\n", - "plt.show()\n", - "\n", - "solid_mls = imageruler.minimum_length_solid(image) # estimate the minimum length scale of the solid region\n", - "print(\"Declared minimum length scale of the solid region: \", diameter)\n", - "print(\"Estimated minimum length scale of the solid region: \", solid_mls)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Declared minimum length scale: 35.0 (solid), 50 (void)\n", - "Estimated minimum length scale: 35.0087890625 (solid), 49.0009765625 (void), 35.0087890625 (minimum)\n" - ] - } - ], - "source": [ - "outer_diameter, inner_diameter = 120, 50\n", - "declared_solid_mls, declared_void_mls = (outer_diameter - inner_diameter) / 2, inner_diameter\n", - "\n", - "solid_disc = disc(resolution, phys_size, diameter=outer_diameter)\n", - "void_disc = disc(resolution, phys_size, diameter=inner_diameter)\n", - "image = solid_disc ^ void_disc # ring\n", - "\n", - "plt.figure()\n", - "plt.imshow(image)\n", - "plt.show()\n", - "\n", - "solid_mls = imageruler.minimum_length_solid(image)\n", - "void_mls = imageruler.minimum_length_void(image)\n", - "mls = imageruler.minimum_length(image)\n", - "\n", - "print(\"Declared minimum length scale: \", declared_solid_mls, \"(solid), \", declared_void_mls, \"(void)\")\n", - "print(\"Estimated minimum length scale: \", solid_mls, \"(solid), \", void_mls, \"(void), \", mls, \"(minimum)\")" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Declared minimum length scale: 30 (solid), 40 (void)\n", - "Estimated minimum length scale: 30.41845703125 (solid), 40.54931640625 (void), 30.41845703125 (minimum)\n" - ] - } - ], - "source": [ - "resolution = 1 # number of pixels per unit length\n", - "phys_size = (400, 400) # physical size of the entire image\n", - "\n", - "outer_diameter, middle_diameter, inner_diameter = 300, 200, 100\n", - "declared_solid_mls, declared_void_mls = (\n", - " outer_diameter - inner_diameter) / 2, inner_diameter\n", - "\n", - "outer_solid_disc = disc(resolution, phys_size, diameter=outer_diameter, center= (0, 0))\n", - "void_disc = disc(resolution, phys_size, diameter=middle_diameter, center= (-20, 0))\n", - "inner_solid_disc = disc(resolution, phys_size, diameter=inner_diameter, center= (-10, 0))\n", - "image = outer_solid_disc^void_disc^inner_solid_disc\n", - "\n", - "plt.figure()\n", - "plt.imshow(image)\n", - "plt.show()\n", - "\n", - "solid_mls = imageruler.minimum_length_solid(image)\n", - "void_mls = imageruler.minimum_length_void(image)\n", - "mls = imageruler.minimum_length(image)\n", - "print(\"Declared minimum length scale: \", 30, \"(solid), \", 40, \"(void)\")\n", - "print(\"Estimated minimum length scale: \", solid_mls, \"(solid), \", void_mls, \"(void), \", mls, \"(minimum)\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The images that illustrate the areas of violation at various probe diameters are shown as follows. The three rows from top to bottom show violations at solid, void, and either region." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABGkAAAKqCAYAAACJuAOLAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAACXNElEQVR4nOzdd3RUdf7/8dedkoQUQq+hQ0CRJiqoYMdeWBUUdcWKBVFQcb+7ur/97nerZRWk2gA7YsW29i7Y6CK9905CEpJMub8/EpSSnnvn3jvzfJyTPZJMPvdDee5M3jNzr2GapgAAAAAAAOAsn9MbAAAAAAAAAEMaAAAAAAAAV2BIAwAAAAAA4AIMaQAAAAAAAFyAIQ0AAAAAAIALMKQBAAAAAABwgYQb0hiGcZphGBttWrutYRimYRiB0l//1zCMoXYcC4g3tAm4E20C7kSbgDvQIqyWcEOaWDJN8zzTNJ+N9XENw/jCMIybYn3cshiG8YJhGFsMw8g1DGP5wfsyDCPJMIzXDMNYW/p/Pqc5t1MkEtr8jWEYnQzDKDQM44WDPkebcARtljAM40rDMJYYhpFvGMYqwzD6l36eNuEI2pQMw8g77CNiGMa40q/RJmKCFiXDMO4wDOMnwzCKDMOYVsbXzzQMY6lhGAWGYXxuGEabg752eunncgzDWBvLfVdH3A1pDkwZUXOGYfgtXO5fktqapllX0sWS/m4YRu+Dvv6NpGskbbXwmHAh2qw9i9s8YIKkH8v4PG0mCNqsPSvbNAxjgKQHJV0vKUPSKZJWH3QT2kwQtFl7VrZpmmb6gQ9JTSXtl/TqQTehzThFi7Vn8WPYzZL+LmlKGcdpJOkNSX+W1EDST5JeOegm+aXfN9rC/VjOE0Oa0qn0Hw3D+MUwjD2GYUw1DCOl9GunGYax0TCMPxiGsVXSVMMwkg3DGGMYxubSjzGGYSQftuafDMPYWbr21Qd9PtkwjEcMw1hvGMY2wzAmG4ZRp5x9+Utvu9MwjNWSLjjs679OHA3D6GAYxmeGYewqvf2LhmHUO+z3ONowjIWlz5w9YxhG09KXtO0zDOMTwzDqH3T7voZhzDIMY69hGAsOTOwNw/iHpP6SxpdO+ceXfr6LYRgfG4ax2zCMZYZhDD5orWmGYUwyDON9wzDyJZ1ek7+nspimudg0zaIDvyz96FD6tWLTNMeYpvmNpIhVx0Ts0KZ32yxd/0pJeyV9evDnadP7aNPTbf5V0v+ZpvmdaZpR0zQ3maa5SaLNeECbnm7zYJdL2i7pa4k2vYgWvduiaZpvmKb5lqRdZXz5UkmLTdN81TTNQkn/K6mHYRhdSr/3B9M0n9ehT364j2marv+QtFbSz5JaqWQi9q2kv5d+7TRJYZU865QsqY6k/5P0naQmkhpLmiXpb4fd/tHS25+qkola59Kvj5H0dulxMiS9I+lf5ezrVklLD9rX5yoZQgRKv/6FpJtK/7ujpAGlx2ws6StJYw77PX6nksl8S5X8H/9cSb1Kv+czSX8pvW1LlfyjPF8lg7YBpb9ufPhxS3+dJmmDSp6VC0g6VtJOSV1Lvz5NUo6kk0vXSynj9zpRJT/MlfWxsJK/v4mSCkr/bOZKSi/jNhslneb0vzU+aDNR2pRUV9Ly0j+j/5X0Qjm3o00PftCmN9uU5JdULOl/JK0s7W+8pDpl3JY2PfhBm95ss4w1PpP0v+V8jTY98EGL3m9RJa+mmXbY58ZKmnTY536WdNlhnztL0lqn/x2W+3tzegPViOjWg359vqRVB0VRfPBfvKRVks4/6NfnHPhLOCiitIO+PkMlL4kySoPqcNDXTpS0ppx9fXbYvs4uL6IyvnegpHmH/R6vPujXrx/8D0zSCElvlf73HyQ9f9h6H0oaWtZxJV0h6evDbv/EQVFOk/SczX+Hfkn9JD0gKVjG17lD8+AHbXq3TZXcif2h9L//Vwxp4uqDNr3ZpqQWpX8eP0lqLqmRSn5w+EcZt6VND37QpjfbPOx4rVXyapl25XydNj3wQYtx0WJZQ5pnJP37sM99K+m6wz7n6iGNl95ft+Gg/16nkgcyB+wwS17OdECL0tuUd/s9pmnml/H1xpJSJc0xDOPA1wyVDBjK0qKMfZXJMIwmkh5XyUvFMlQyUdxz2M22HfTf+8v4dXrpf7eRNMgwjIsO+npQJZPWsrSR1McwjL0HfS4g6fmDfr1BNjJNMyLpG8MwrpF0m0r+LBAfaNNjbRqG0VMld069rF4brkKbHmtTJXuWpHGmaW6RJMMwHlXJExz323A8OIM2vdfmwa6V9I1pmmtsPg7sR4vebrEseSp5tfjB6kra58BeasxLQ5pWB/13a5WcMOgA87DbblbJP5zF5dy+vmEYaQeF1FolL4PaqZJ/rF3N0vd/V2JLGfsqz79K99ndNM1dhmEMVMlLmGtig0omnTeX8/XD/zw2SPrSNM0BFax5+PccwjCMySo5GVpZ1pmm2bWi7z9IQKXnpEHcoM3feKXN0yS1lbS+9AFDuiS/YRhHm6Z5bEXHg6fQ5m880aZpmnuMksu4Vrg2PI82f+OJNg9zraR/V3IbeAMt/saLLZZlsaShBx0jTSU/ey4u9ztcyBMnDi413DCMLMMwGkj6kw49S/PhXpb0gGEYjY2SMzz/P0kvHHabvxoll8vrL+lCSa+aphmV9JSkx0onkzIMo6VhGOeUc5wZku4s3Vd9lbyHvDwZKpns7TUMo6Vqd0bpFyRdZBjGOaUnl0opPcFVVunXt0lqf9Dt35WUbRjG7w3DCJZ+HG8YxlFVPaBpmreaB53V/rCPMgMyDKOJUXIZ0fTSfZ4jaYhKXsZ34DbJRulJuiQllf5ejLLWg2vR5m880aakJ1Vyh9Wz9GOypPdU8tJdSbQZJ2jzN15pU5KmShpReh9aX9LI0v1Ios04QZu/8VKbMgzjJJWcu+PVMr5Gm95Di7/xTIuGYQRKW/Or5EnGFOO3K3C9KekYwzAuK73N/1PJ+W2Wln6vr/TzwZJfGimGYSRVdc+x4qUhzUuSPlLJmZhXq+Q9aOX5u0rez71Q0iKVnCDp4NtvVclLwTZLelEl7/tbWvq1P6jkZH3fGYaRK+kTSZ3LOc5TKnmv3oLSY7xRwZ7+qpITKuWo5Iehim5bIdM0N0i6RCX/Z7JDJZPM0frt73OspMuNkjOVP26a5j6VvJ/xSpX8nrfqtxNh2clUyVubNqrkz/sRSSNN05x50G2WqWS63FIlf5b7VTKlhnfQZimvtGmaZoFpmlsPfKjkDr7QNM0dB92MNr2PNkt5pc1Sf5P0o0pO7L1E0jxJ/zjo67TpfbRZymNtSiXP0L9Ruo/D0ab30GIpj7X4gEr6+h+VvBJnf+nnVPpY9jKV3G/ukdSndI8HnFJ6+/dV8iql/Sr5N+Aqhmm6/xW1hmGsVcmJij5xei8AfkObgDvRJuBOtAm4Ay3Czbz0ShoAAAAAAIC4xZAGAAAAAADABTzxdicAAAAAAIB4xytpAAAAAAAAXCBQ0RcH+AbxMhskrI+jr7r2som0iURGm4A70SbgTrQJuFN5bfJKGgAAAAAAABdgSAMAAAAAAOACDGkAAAAAAABcgCENAAAAAACACzCkAQAAAAAAcAGGNAAAAAAAAC7AkAYAAAAAAMAFGNIAAAAAAAC4AEMaAAAAAAAAF2BIAwAAAAAA4AIMaQAAAAAAAFyAIQ0AAAAAAIALMKQBAAAAAABwAYY0AAAAAAAALsCQBgAAAAAAwAUY0gAAAAAAALgAQxoAAAAAAAAXYEgDAAAAAADgAgxpAAAAAAAAXIAhDQAAAAAAgAswpAEAAAAAAHABhjQAAAAAAAAuwJAGAAAAAADABQJObyDRGIGA/K2zfv216TO0dkhz7W8ertL319kcUNvpW2REzdIFTEU2bJIZrtr3AygbbQLuRJuAO9Em4E606X0MaWzkr5cptWymaEpAy29Il5kaVkp6sd44/gmlGNFfb9cikKxkI1ilNYvMkDbfXPTrrwtMvy77YZiK8pNkFASUPSVPvsKwtGmrIntzLP89AfGANgF3ok3AnWgTcCfajE+GaZrlfnGAb1D5X0TFDEMrH+2jhy54SafW2aJG/rSYHHZnJF+f7W+hP747RB3v+V6q4O8XFfs4+qrh9B7KQ5vV40tLk3lUO+V2TNeu3xWoV9ZGPd76HfmkmLYZlXTn+os0b2OWGr6Zqror82QsWaNofn5M9hAvaDN+0GZ8oc34QZvxhTbjB23Gl/LaZEhjIyOYJHXvpGXD62jx2ROV6kuy9XgF0WJ1/fB2dZ64X1q4Qmao2NbjxTvu0LzN37Gd9nVvotxrc9Wu/m690GGmfPLZ3mFVFUSLFVVU16y6RKv3NFDms3WVsWi7IivXOL0116NNb6PN+EWb3kab8Ys2vY0241d5bfJ2JxuZoWJpzmJ1vi1Zxzw6QksGjq/yy8yqqyBarGPeHKHO986XWVRU+TcAcSjQro1yezZT4Y17NLLTpxqcvl1Bw1/61RRH93a4A3esb3X6UJIUOj6iGXlNNGbFmarzdD1lzN+q8Nr1Tm4RsAxtAu5Em4A70WZi45U0MWIkJ2vZmB5aevEEywc1RWZIR711h7LvZkBjJZ518I7wGb21uX+yRl35loZlbnZ6O5aYvLelxk6/RC2+KVLgszlOb8dVaNM7aDOx0KZ30GZioU3voM3EwtudXCDQvJku+nSRbq23ydJ1J+xtpffPOFrhrdssXTfRcYfmfsXnHKf8O3P0RrepygqkO70dW2wM5+nSRdcrfWymgh/95PR2XIE23Y82ExNtuh9tJibadD/aTEy83ckFwlu26sHvztOt5z5t6bqPzDpH2Vv5h44E4fOr+OxjlT9ir17rNkatA+mS4vPOTJKyAun6oderWvNUngYvukHp4zOV9NFcKRpxemvAoWiTNuFOtEmbcCfapM1yMKSJsfYvmtozoED1/amWrLczkq/2LzGARvwzAgEVDuil/OE5mt7tMXUIxvcd2eHaBdP147EztOqJPA1eeIPqTshU8ifzZIbDTm8NCY42aRPuRJu0CXeiTdqsDEOaGEvemqeQrBuqRCUlb90n5o+IV0YwSYUDeij/9sS8Iztch2C65vSeoeVP5GvIwuuVMTFTKZ8s4GpuiDnaPBRtwi1o81C0CbegzUPRZvkY0gBwrUDzZlo5pone78sd2eGyg2ma03uGVk3O03mzb1enkds4LxVihjbLR5twEm2WjzbhJNosH20eyef0BhLNtn4NlG7h1Z1SDb+29Wto2XqAG/gyMrT+Lyfpis9/0s/9ppbemaEsHYLpWtx/qgZ9MU/r/3KSfBkZTm8JcYw2q442EUu0WXW0iViizaqjzd8wpIkln1/7Ts//9VryVkj3pSj3tP2Sz2/ZmoCTQmcfp70zmmjhsHG6tu5OBQ3+bVcmaPh1Xd3tWjhsnPbOaKLQWb2d3hLiEG1WH20iFmiz+mgTsUCb1UebJXi7UwwZvbpoZt/Jko48afAX+33aFal4strQn6fT6kSP+PxbJ03SPT1ukjlvsVVbBWLOl5amVQ9012ODpuqC1EJJ7rgjq02bsRY0/Jrd43W9PSlV9746VB3+vkDRggKntwWPo83ao03YgTZrjzZhB9qsvURv0zDN8k9iy3XrrePv1F5tX9qsaxt+q4VFrTRnXxvNerWXDpxDuNXMrTK37qhwDaN5E224uGnpL6STBs1T74x16p68QVN39tOGq5srsmK1zb+TxFHedevdIN7a9Hdqr6X319eyAU869izDd4URW9rsm+LM7ydkRpT90TAd9Y/diqxc48ge7EKbsUOb1qNNZ9Cm9WjTO2gzdmjTeonYJkOaGPClpGjrTcfKiJhqPCdPxoLlUtSs9ZmrjWCS5DNk9uqsHb3SZPoNNXt6rqKFhRbtPLFxhxYb4TN76/ZJr2pg2l75jdi9A3NhcaH+u6+bnlrYTxnf1lGTn/bZ0ub2Y9O1r1+Bbu72rc7LWKTuSSkW/Q4qFzGjej2/vp649XIFPpsTs+PajTZjgzbtQ5uxR5u1R5veRZuxQZv2SbQ2GdLEimFIFfxZe+YYCYQ7NHv5UlKUM7Cn7vvbCxqYlhez4z66u72mPnuumv2wX76vF0pmNDZtGj5FTumhbcen6PqhH+juBrF71dtb+el66IFrlDlzflwMcWnTXrRJmzVFm/aiTdqsKdq0F23SZk0xpAGqiTs0+/hSUrR0THctvWiCki282ll51oTydMm8m5XxUqYyP1+lyI6KX+ppN3/jxso5vYP2XZWjmb2eUrsYnOm/yAypyzvD1WXkQs/fqdGmfWiTNmuDNu1Dm7RZG7RpH9qkzdpgSANUE3do9jCSk7VsbI+Y3Jk9uru9nnnxXLWYtV++L+fZeqyaip7aS5tPqqObr3lfI+uvtfVYRWZIXd4ers4jF8gsKrL1WHaiTXvQ5qFos/po0x60eSjarD7atAdtHoo2q48hDVBN3KFZz9fzaC0dkaql506y9c5sSzhPZz51n9pNXafwxk22HcdKgVZZWn1Da31240NqHrDvWYiCaLG6fnC7uozLV3TBEtuOYyfatB5tlo82q442rUeb5aPNqqNN69Fm+Wiz6hjSANXEHZq1zBN76NJnPtGt9ey7g9kTKdBpc25U4zF15P9qgRSN2HYsW/j8ipzaQ7tGFuiL3lOV6atj26Em7G2lt284XfpuoW3HsAttWos2q4A2q4Q2rUWbVUCbVUKb1qLNKqDNKimvzdiddhpAwrL7zqzIDOnBXZ10yrh71fzyFfJ/Mdd7d2aSFI3I//lcNb1spU4ed48e3t1BRWbIlkMNr7dBF0/5XOrb3Zb14Q20WUW0iRijzSqiTcQYbVYRbdYKQxoAtvL1PNrWO7O8aKGOef5OfXV2B7V4aJbMcNiW48SSGQ6r5YOz9MU5nXXMC3cqL2rPSdGG19ug3035VL4eR9myPtyNNquPNhELtFl9tIlYoM3qo82aYUgDwDZGcrKWjki17c5szJ62Oumxu9Xhz3MU3rLVlmM4Kbxpszo8MEcnjrlb4/a0seUYt9bbpKV3pMtITrZlfbgTbdYObcIutFk7tAm70Gbt0Gb1MKQBYAtfSkrJGe/PnWTL+g/v7qAPrjlZzf8zS2ao2JZjuIEZKlaLR2bpvWv76dHd7W05xtLzJ2rZmB7ypaTYsj7chTatQZuwGm1agzZhNdq0Bm1WHUMaAJbzpaRo6ZjutlySMC9aqHYf3qjPrukjc95iS9d2M3POYn30+xPV/qMbLX+paLIR1NKLJ2jpmO6ev1NDxWjTerQJK9Cm9WgTVqBN69Fm5RjSALBczsCettyZ5UT3q+fLo9T55gWKzv/F0rW9wJy3WNk3LVDP6SPtuVO7aIJyLulp6bpwF9q0B22itmjTHrSJ2qJNe9BmxRjSALBU+Mzeuu9vL9jybEPvl+9Wxz/+GBcnUqspMxxWx//5ST1fsedO7Z6/vaTwGb0tXRfuQJv2ok3UFG3aizZRU7RpL9osH0MaAJbxd2qv2ye9qoFpeZaumxctVM+XRyX8ndkBJXdqc225U7ssPVe3TH5N/o7tLF0XzqLN2KBNVBdtxgZtorpoMzZos2wMaQBYwpeWpqX319fAtL1aE8rTjev7/fpx84aTtT2SX6N1C6LF6jl9JHdmhzFDxer4P3PVY8ZIFURrdpK57ZF83bzh5EP+rtaE8nRZ2h4tub+BfKmpFu8aTji4TSvRZtmsaLM8tBlfaDO2aBNVRZuxRZtHYkgDwBKr7u+uW3p/pe7j79Cwa0doY9+8Xz/W9y3QkOvuVOdnbtO03CZVXrMgWqxuM+5Uxz/O5c6sDGaoWJ3+MFfdXrtTRWaoyt/3TE4zdXn6Ng0ZeqfW9y045O9q2LUj1H38Hbr9+C+0+k89bNw9YmXVA921bMCT8hvW3eXTZsVq2mZl/IZPy89+Uqvvp814QJuxR5uoCtqMPdo8FEMaALVmntxTmSukr87LVta/Zsn35bzDbmAq8Okctf3zbL16/knq+NKtVXpJ47g9XdX5wdVxfTnC2jJDxery7zV6fE+XSm+bFy1Uxxdv0xsX9FWb/zdbgc/mSKZ5yG18X85T1r9m6YvzjlLdVZJ5krfu1HCo0NnH6bFBUxU0/JauS5uVq06b1RE0/Hp48LMKneXN99mjBG06hzZREdp0Dm3+hiENgFoLrt2uBs/+oPDGTZXeNrx6rTr+ca56vTiqwkHNmD1t9fkNfRXZtt3Krcal8NZt+uSGkzRuT5tyb5MXLdSxL4xSxz/NUXj12srX3LBRDZ79QcF1OyzcKWLJl5Gh/aP26IJUa9/jTZtVV5U2a+LitALljcqVLy3N0nURG7TpPNpEWWjTebRZgiENgFoLb9osRSNVvr0ZKlaHB+ao1wtlD2p2RvL19l1nyvxxkZXbjG8/LNIbdw/QzjLO/XNgQNP+z3Oq9wxONFLydwtPWnt3N33VfYala9JmDVTQZm1823O61t3NK928iDZdgjZxGNp0CdpkSAPAGWaoWB3+PEdnLbzmkM/nRQt10ov3KulL7syqK/mzhTrxxXuPGHydseD31R/QwNMCzZvpj0NmWPpybdqsufLarI2g4dd9V7+mQLOmlq0J+9Gmu9AmDqBNd0n0NhnSAHCMGSpW6ph6h0zKz/35KgYKNXRg8HXhL1f++rmdkXylP1aXP88EYgSTtHJMEw3J2GbpurRZc2W1aYWrM7ZoxZimMoJJlq4Le9Cm+9AmJNp0o0RvkyENAEclfTZf1626XFLJQCE4piF3ZrVghoqlMY21J1IgSbp25SAlfbHA4V0hlgoH9ND7fSda+mwgbdbe4W1aIWj49e6Jk1R0pjdevp3oaNOdaBO06U6J3CZDGgCOMsNhrf64nSTp5OfuVdJHcx3ekfclfzBXfV64R5K07qO2XOoxgRiBgPJvz1GHYLql69KmNQ5u0yrZwTTl3J4rIxCwdF1YizbdjTYTF226W6K2yZAGgOOa/VisJ3NaqONTm6p1AmKUIxpRpyc365mcZmr6Y5HTu0EMFQ7opendpli65jM5zWjTKqVtTsttYumy03tMUdFZvSxdE9aiTZejzYRFmy6XoG0ypAHguEBeSOOeGajw2vVObyVuhNes05gplyqQz6toEobPr/zh1j4buD2SrzFTLqVNC4XXrNN/plyu7RZetSI7mKbc4TmSYVi2JixEm55AmwmINj0hEdtkSAPAccasBWrxyCyntxF3Wjw8S8ZszkeTKIrPPtbyZwMHL7laLR6ZbemakFo8PFtXLL3K0jVndJ+i4rN7W7omrEGb3kGbiYU2vSPR2mRIAwBAHMgfsdfSZwM3hvNkPt5EMk3L1kQp01T08abaGM6zbMkOwXTl3pFr2XqwDm16CG0mFNr0kARrkyENAAAeV3zOcXqt21RL13xub2+lvD/H0jXxmzr/nasXc6x9P/xr3acodJY7nxVMVLTpPbSZGGjTexKpTYY0AAB4XP6dOWodsPbKFM+9eSYnPbSRGQ5r6ptnWbpmu2C69o3cZ+maqB3a9B7aTAwJ16bPLyMQkP+oTtp9/YllfviP6lRyxSOfdZcit1Iitene604BAIBKhc/orTe6jZVk3YPN1/PqqsNT68Rpp+3V4akNemtIugamWffy7Te7T9F1p98p/+dc+tVptOldtBnfEqVNIxBQ/kW9ldfCr+aXr9XpjZfp6JSfdUFqYZm3f68gRb8UttSn27to2+ttlLEprNR358oMu+d3lShtMqQBAMDDNvdPVpbFzwY+vPJs1du61tI1caTIlq16cOU5GtjjdcvWzAqka1P/FLX+3LIlUUO06V20Gd/iuk3DUCCrpTYMbq3G523Uy9n/qfLv9YLUQl2QukqjG6yS7i85x87QO67Sjv9mqdUr6xTeuMnmzVcuUdrk7U4AAHhUoF0bjbryLUvXXBXKU8qE+q565ixemeGwkiY21JqQdc8IStJdV85UoG1rS9dE9dCmt9Fm/IrnNv2NGmrt3/pq6Kdfa97d4/Xp0W/XahiVFUjXp0e/rXl3j9fQz77R2r+dKH/DBhbuuPoSpU2GNAAAeFRuz2YalrnZ0jU/yD9Kdb74xdI1Ub7UL5bo44JsS9e8OXOD9vVoZumaqB7a9D7ajE/x2ub+S07Q/pfT9cv1EzQ4PUd+w7of8/2GT4PTc/TLDRNU8HJdFV50gmVr10QitMmQBgAAjyq8cY/la45960JF8/MtXxdli+7bp0dmXmLpmn7Dp7wbcyxdE9VDm95Hm/Ep3tr018vU6gdP1EOPTdLnXWdaOpw54liGT18c85b+OXayVj94ovz1Mm07VkUSoU2GNAAAeJC/YzuN7PSppWsWmSGl7DQsXROVS95pqMgMWbrmyOxP5e/YztI1UTW0GT9oM77EW5v+epla+3QrLb1mgvqmxO6KTCen+PTLNeO19ulWjg1q4r1NhjQAAHjQvu5NNDh9u6Vrzi5MVtaLKy1dE5Vr/cIq/VRk7QPsIRnbtK9bE0vXRNXQZvygzfgST23662Vq3TNZWnTic7a+eqY8QcOvRSc+59igJt7bZEgDAIAH5V6bq6Bh7QOUH/e3k/aXfWlO2McsLNT3BR0tXTNo+JUzNNfSNVE1tBk/aDO+xEub/nqZWj8lSwv7Pu/IgObXfRg+LTrxOa17Jivmg5p4b5MhDQAAHuNLS1O7+rstX/fJ985WJNcdD1ASSWRvjib+9xzL121bf498aWmWr4vy0WZ8oc34EU9tLh3bQT/3fdHRAc0BfsOnxSe+qKVjrB2YVCbe23T+bxYAAFSLeVQ7vdBhpuXrGqblS6KK7Pizf77DmzKz21q/MMpFm/GHNuNDvLS574q+euOUSbE9aBW8cepE5Q3qE9NjxnObDGkAAPCY3I7p8ll8F74qlKd2b3HlGKe0e6tAq0J5lq4ZlF+52RmWromK0Wb8oc34EA9t+hs20HGj56hncnLMjllVPZOT1eu++fI3bBCzY8ZzmwxpAADwmF2/K1CqL8nSNfdFgwqss/aEiqi64LodyjcDlq6Z6kvSzoH7LV0TFaPN+EOb8SEe2lzyYHs93uLHmB2vusa3/F5L/t0hZseL5zYZ0gAA4CH+epnqlbXR6W3AI7pnbZK/bl2nt5EQaBPVQZuxEw9t+rp30WtnTnR6G5V67awJ8h3Txelt1Iob2mRIAwCAl7Rspsdbv2P5spN2nCZzv/PPHiUqMz9fk3ecZvm6E9vOlLKaWb4uykCbcYk240ActLl0eIZ6J1v7SiA79E5O0tI7YjPgiOc2GdIAAOAh0ZSALXfeH3/fXZG9OTasjKqI7M3Rf3/sbsva0eSgLeviULQZn2jT+7zepr9RQ5137CLbj2OVs3otjsm5aeK5TYY0AAB4yPIb0tXI7/zlIeENTfxpWn5DutPbSAi0ieqgzdjxepvbLsvWI82/cnobVfZYy0+17bLOTm+jxtzQJkMaAAA8xEwNO70FeIyZGnF6CwmBNlFdtBkbXm9zd99iy096bKd0X4p29wk5vY1acbpNhjQAAHiEEQgoJb3Y6W3AY5LSi2UErL0CBg5Fm6gJ2rSf19v0N2qoy3vMdXob1XZJz/nyN2ro9DZqzOk2GdIAAOAR/tZZeuP4J5zeBjzmjT5PyJ/VwultxDXaRE3Qpv283qZRN0O3N/za6W1U24hGX8jI8O7b+ZxukyENAAAekmJEnd4CPCbFiEiG4fQ24h5torpoMza83GaoeT2lePCfSLJRsnevcrpNhjQAAAAAALjMyiHJah7w3itSsgLpWnllitPb8CyGNAAAeITp8+DTaUACoE3Anbzepukznd5CzXn7j95RDGkAAPCItUOaq0Ug2Z7FeTAVt7ICyVpzVUuntxHXaBM1QZv2o03UhNNtMqQBAMAj9jcPK9kI2rL2PWe87+krMXidv3Fj/fH0d21ZO9kIqrAZl/q1E23GL9r0NtqMX/HcJkMaAACgk+uslBG054EsKmckBdW3zmqntwEXok1n0SbKQ5vOiuc2GdIAAAAAAAC4AEMaAACgpv6Q9vVp7fQ2ElbuCa3U2Bd2ehtwIdp0Fm2iPLFos/5Cv/KihbYeww450f2qv8jeUUM8t8mQBgAAqHkgXVv7+p3eRsLaeqLPk5dZhf1o01m0ifLEos3mH23Rjoj3BhE7IxE1+3izrceI5zYZ0gAAAElSODUqGVyuIuYMQ5G0qNO7gIvRpkNoE5Wwvc1oVJsjqfatb5NNkXQpamM7cd4mQxoAACBJevS8F+WvV8/pbSQcf4P6GnP2805vAy5Gm86gTVTG7jbD6zZo6OwbbVvfLtd9c4PC6zfatn68t8mQBgAASJKa+XOkxg2c3kbiadRALQN7nd4FXIw2HUKbqITtbZqmzO3JipjeedVIxIzKtyNJMk37DhLnbTKkAQAAkqS+KX6tHdTU6W0knDVXNFHv5CSntwEXo01n0CYqE4s2O0/aoa8LA7Yew0pfFAaVPXm7rceI9zYZ0gAAgF8Vtohw7otY8vlV2Nx7J4VE7NFmjNEmqsjuNiPLV+nWOVfbtr7VbvvxakVWrLbvAAnQJkMaAAA8os7mgIrMkK3HeHjAy/Klx+fVEtzIl5aqx856ydZjFJkh1dnC1YHsRJvxhzbjQ7y02eCNNBVEi209hhUKosVq/Ia9JzpOhDYZ0gAA4BFtp2/R5nCRrcc4o85W7br0GFuPgd/svPwYnZpi78vCN4aL1PblTbYeI9HRZvyhzfgQL21mvrdY164539ZjWOGa1Reo7n8X23qMRGiTIQ0AAB5hRG08CV+p+v5Udb3tZxnB+H2vt1sYwSR1v2WR6vu9d3lVHIo24wttxo94aTO6b592/aOdvtjv3h/fP93v155/tlV03z7bjpEobbr3bxkAADhiaONvZRzdweltxD3j6A4a2uQbp7cBD6HN2KBNVFcs2kz64Efd8P7NrrzSU8iM6Ob3blLSBz/aepxEaZMhDQAAXmGaKjDtf4/0aXWiWnprBicptZNhaOltGTolxf5D5ZsBey+FCtqMJ7QZX+Kszc7/87OuX3+arceoievXnanO/7PI3oMkUJsMaQAA8IjIhk267IdhMTnWXad8JF9yckyOlYh8derorv4fxeRYl383TJGNm2NyrERFm/GDNuNLvLUZzc/X5j911Iy8TFuPUx3T99XX1j+1V7SgwNbjJFKbDGkAAPAIMxxWUX5szkcxLHO5dg7pFZNjJaIdQ3poWObymBwrlJ8kMxzflyt1Gm3GD9qML/HYpv/zuXpy2GWavq++7ceqzIv7GuqZYQPl/2Ku7cdKpDYZ0gAA4CFGQSAmx0n1JanP7XPlS43vk/M5wZeWpn63/6hUn/0/OETMqIwCLvEbC7TpfbQZn+KxTf8Xc/XMsIF6LreR7ccqz3O5jTTtpovl+3Ke7cdKtDYZ0gAA4CHZU/K0M5Jf63W2hPP0el7dQz7eK0g55ISEj7WYpaX/4ZK/Vlv6n656uNn3v/46Ykb1XkHKEX8f2y34e94V3a/sKXm1XgeVs6rNqqBNexzepp1oM3bitU3fl/P0/M0X6Z87O6vIDMXkmJJUEC3W33d20fM3XyTf1/YPaKTEazM2Y0UAAGAJX2FYNb2uw0cFQT299RQteauzMjZGlfne4kPXTk/Tnwa3V2ETU3f+7l1dlL5Ez57zpP7Z62qZ8xaXsyqqw+jdVS+cPVlbIvs1c19XjX/zfKXsMJT1yipF8w99P/9/LrhK+7J86vq7pbq52Zc6s06kRsf0FYVUs+9EddSmzeoKGn7atNiBNoNG7J5Bp83YiOc2fV/P0zenNNNTD56i186eoN7J9r7SZE5RsS7/8A4ddd9S+XJjM6BJxDYNs4KzFg/wDeJ040hYH0dfde2lE2gTiSzR2/TXy1Td9/ya3u6zKn/PnkiBer81Sl0m7VF0xVqZoeJKv8dITlbBeT3UYvRKzV3fSh2GrVZ0377abD3h+TIytOqpduqZtUlbH+6g1A8WyCwqqvT7jGCSfJ3aault9TXvd2OU6atT5WNevuosFVxQrEhubm22XiW0Wf02ayv7y6G0aYEDbS4/5bmYHZM2S9CmRXx+FQ/opVMemq0HGi20fKARMiP6646emnXvCQp+Nl+KxmaEkaht8nYnAAA8JLI3R/M2ZlX59g/u6qQLRt+tTnf9pMgvy6s0oJEks6hIdd76QfuuqCP/0jTtO+fomm4ZpXLPPVr+X9KVf2WK6sz8oUoDGkkyQ8WK/LJcne76SeeOHqWHd3eo8jEXbmwZkweaqH6bVlhyylTtuoy3PdXWzsuP0ZL+02J6TNqMnYRoMxpR0oc/6cf+DXXCP0fo9k19Nb+K9zEVmV9UpNs39dUJ/xihOf3rKfjJnJgNaKTEbZMhDQAAHtPwzVQVRCsethREi9X+9Vv05eCeypj+XY0fVIU3blLrv85S3SV7a/T9+E3dJTlq/X+zFN64qWYLRCOq+/J3+nzQsWr/xi1V+jfQ+M2qv+oGtVeVNq3kN3zqcdtC+eu553K8XuOvl6ljb5svvxG7H4toM/YSpc1Ibq6aTJilVccX6r5rblH2V9fqxvX9tDxU9XPyLA/l68b1/ZT95VDdd80tWnV8oZpMnBXzV+wlcpuckwYAAI+puzJP0QreYV8QLVa3GXcq+w9zFaniK2cqE1m8zJJ1Eln056WWrBNZskLZo5LULXynfhk0TslGsMzbhRRRxop94v2xsVNZm3Z4qtW36vrM1Wpzven4s79e469bV+unZOn9rBdjelzajL1EbNP4dr7afSttlDS833AV10/SzmMC6nTuqjJvv+KDDmr0c1hJe4rl+2a+2mlBbDd8kERvk1fSAADgMcaSNbpm1SXlfn3cnq7q/ODqKr+1Cd5jhorV5d9r9PieLuXe5verfidj2ZoY7gqVtWmXH/tM1e6LeUtide0a2FVz+kyL+XFpM/YSvU3fN/OV8s4PyvrXLO0/dVuZH1n/mqWUd36Q75v5Tm834dtkSAMAgMdE8/O1ek+DMr+2JZynj+/sr8i27THeFWItvHWbPrjztHIv1b1mdwNFCwrK/BrsUVGbdkr1JWnM/01Q/uV9Yn5sr8ob1Edj/3d8ua9EsxNtxh5tegdtMqQBAMCTMp+tq5B56HlmQmZEp7w0WoFvfnZoV4i14NeLdPLL95b5b6H+s+kO7SqxldVmLPRN8euBf09ToH3bmB/ba/wd2+kv/5qivimxu6TvAbTpHNp0P9oswZAGAAAPyli0XTPymhzyucl72yt7wgbe5pRAzFCxsids1OS97Q/5/Iv7mitjIa+mckJZbcbKgDr7tWVMsvwNY/+KAa/wN2qobY8FdWad2l/5piZo0zm06W60+RuGNAAAeFBk5RqNWXHmIZ8b//OpCm/Y6NCO4JTwug2asPiUQz73+PLTFV691pkNJbiy2owVv+HTj71f1pYpTfhhsAz+Rg21dUoj/XDs9JheMeZgtOkc2nQv2jwUQxoAADyqztP1fv3vkBlRy2eSnNsMHNX8meRfX8YfMaNKf4ZLMjvp4DZjzW/49NNxL2nr1Mb8MHgQf6OG2ja1oX7s/bJjPwTSpvNo031o80gMaQAA8KiM+Vs1eW9LSdKWyH4l7XHmJcJwXvLuIm2J7JckTc5po4z5WxzeUWI7uE0nHHjWnh8GSxz4IdDJZ+kl2nQD2nQX2iwbQxoAADwqvHa9xk4vuaTojSuGyPyJEwYnKvOnnzVs5RWSpAkvX6Twug0O7yixHdymU/hhsIS/YQNX/BAo0aYb0KZ70Gb5GNIAAOBhLb4p0sZwnkIRv2SaTm8HTjFNhaJ+bQznqcU3hU7vBvqtTScd+GGw6XuhhLwEcN6gPmr+XrHm9J7h+A+BtOketOk82qwYQxoAADws8NkcXbroeqe3AZe4ZMEN8n8+1+ltQO5p02/4NLX11xr78DjlDUqcHwb3XdFXjz80Ts+0/sbprUiiTTehTWfRZuUY0gAA4HHpYzO1Kz/V6W3AYTvy0pQ5NsPpbeAg6WMztSbk7DP2B/ROTtKEhx7Ximm95a/nnhNkWs1fL1Mrnj1WE/89Vr2T3XEy9TWhPNp0GdqMPdqsOoY0AAB4XPCjnxT8KH4f2KFqAh/WU/CTOU5vAwcJfvSTBi+6welt/KpncrJWn/2MNkxtKfPEHk5vx3LmST20YWpLrR4wRT2Tk53ezq8uW3AjbboMbcYWbVYPQxoAAOJA09k5CrTKcnobcEigTSs1nZ3j9DZQhvTxmVrlkmfsD1jU5yX9/aWntXzKcfLXrev0dmrNX7euVkzrrX+9+JQW9XnJ6e0cYlUoT/XGu++ZetBmLNBmzTCkAQAgDkTn/6Lwho1ObwMOCa/boOj8X5zeBsqQ9NFcDV7onmfsDzghOajl5zyh47/epe3DT5IvJcXpLVWbLzVV2+84SX2+3qllA550zVsoDjZ44Q0Kfuy+Z+pBm3aizdphSAMAAADYJRpR3QmZWh7Kd3onRwgafv218WJ996exWjmli8yTe8oIBJzeVqWMQEDRfj216plO+u6PY/WXxr8oaPid3tYRlofyVXdCJlfecyvatBxtWsP9f9MAAACAhyV/Mk9DFl6vOb1nOL2VMiUbQa04bZrmn1iky2fdqozZddT8hcWK7HXXW+j89TK15Zqu2nfifr1x8iR1T0qRFHR6W+W6Yv6NavrJPLnzx0BItGkV2rQWQxoAAADARmY4rIyJmVo1OU8dgulOb6dcPZOTtfL0qco7tVD/vul4vfJhP3V4LU+at0RmOOzInoxAQOaxR2n1Zem66tyvNLrho0r3pUhy91tAlofyVW9ShmN/bqga2qw52rQPQxoAAADAZimfLNB5s2/X4v5TXfny/4Ol+1L09yaL9PffL9LyK/N1wbfDlT4rVS3e3ywzJ1eRXbttPb6/YQMZmXW16YIWyj+xQO+dPEHZwbTSr7r7B0BJCpkRXfDtcHX4dIFrn6nHb2iz6mgzNhjSAAAAADYzQ8XqNHKbXvyiua6ru93p7VRZdjBNK06bprxTCrVjdFgPbz9L//25txp9naTG3++WiooVWbmmVsfwd2wnJSdpe98G2tWvWOcds1ijm7ytxv5A6TPzaZWu4SbP5bZUp1GbFQkVO70VVAFtlo82ncGQBgAAAIiB8NZtevDly3X1sHGuf8b+cOm+FKX7pIktv5Nafqe8AYUqMCP6pThDt865WqZpyDSlZtNTlLqxoMK18lulafuV+yVJhmFqcu8XdXTSPqUa/tIf/CTJvW89qUiRGdJ/XrpUrbbNcnorqAbaLEGb7sCQBgAAAIiRto8u0il9B2t2j9ed3kqtpPtSlC6pSZ2olvZ7/tfPF/QrVlTRCr/XJ59SfYdfktdbz8iXp//8q9Tm0QWV/AnAjWiTNt2CS3ADAAAAMRLdt091/lNPb+enOr0VW6T6kkqf2S//48gfAuPD2/mpyni0rqL57rukMypHm7TpFgxpAAAAgBgKfjJH9746VCEz4vRWYJGQGdHoV4Yq8Okcp7eCWqDN+OPFNhnSAAAAADHW4e8LlP3RMEVML7z4HhWJmFFlf3CL2v9zgdNbgQVoM354tU2GNAAAAECMRQsKdNQ/duv1/PpObwW19Hp+fR39j52KFlR8UlZ4A23GD6+2yZAGAAAAcEBk5Ro9cevleivfm1dLgfR6Xl09cevlCq9e6/RWYCHa9D4vt8mQBgAAAHBI4LM5euiBa1RkhpzeCqqpyAzp0QeuUuAz75zrAlVHm97l9TYZ0gAAAAAOypw5X13eGc4Pgx5SZIbUZeZw1X17vtNbgY1o03vioU2GNAAAAICDooWF6jJyobq8PVwF0WKnt4NKFESLddRbd6jzqAWKFhY6vR3YiDa9JV7aZEgDAAAAOCxaWKjOIxeo6we3O70VVKLr+8OVffd8mUVFTm8FMUCb3hEvbTKkAQAAAFzALCpSl3H5mrC3ldNbQTkm7G2lLuP3ef6HQFQPbbpfPLXJkAYAAABwieiCJXr7htP5YdCFxu1po7evO03RhUud3gocQJvuFW9tMqQBAAAA3OS7hXr7htM1eW9Lp3eCUhP2ttK7158i/bDI6a3ASbTpOvHYJkMaAAAAwG2+W6iZQ05Ru/du5soyDiqIFqvduzfr3StPjqsfAlELtOkK8dwmQxoAAADAhaILlqjzHSVXluGHwdgrMkM6ZuYIdR6xMG7eRgFr0Kaz4r1NhjQAAACAS5lFReoyaqG6vMMPg7FUZIbUZWZ8XCkG9qBNZyRCmwxpAAAAABeLFhaqy8iFOv3uEXo9r67T24l7r+fV1RmjRqjL3Qvj9odAWIM2YytR2mRIAwAAALhctLBQGa98p4m3DtKMvExFzKjTW4o7ETOqGXmZmnjrIKXP+E7RwkKntwQPoE37JVqbDGkAAAAAjwh8NkfTzj9DHT+6WSEz4vR24kbIjKjjB8P07LmnK/DZHKe3Aw+iTXskYpsMaQAAAAAPiaxcoy7Dl+iYaXfo7fxUp7fjeW/np+qYqXeoy4hfFF691untwMNo01qJ2mbA6Q0AAAAAqJ5oQYHa3j9bYz4for+PytW3PacraPid3panFJkh9Z9/lTIerau2n84Wb1KBFWiz9hK9TV5JAwAAAHhU8JM5ajh4s3pMHqFpuU14m0UVhMyInslppl6T71LDwZsV+DQx3kKB2KLN6qPNEgxpAAAAAA+L5uer1d9m6dXTeqnr19dreSjf6S251vJQvo7+8ka9flp3tfrbLEXz+bOCfWiz6mjzN7zdCQAAAIgD4a3b1P73e3TLmSOVc3uupveYouxgmtPbcoXloXxdMf9G1ZuUoQ6fLlAkVOz0lpBAaLN8tHkkhjQAAABAnDBDxUr64Ec1+SSgW84aqdzhOZrRfYo6BNOd3pojVoXyNHjhDao7IVNNP5knMxyW6fSmkJBo81C0WT6GNAAAAECcMcNhJX3woxp9aOims0cq945cvdZ9itolyA+Ea0J5umzBjao3PkONPp4jmSY/AMIVaJM2K8OQBgAAAIhXpqmkD39Sow+lG8+6S/tG7tOb3acoKxCfPxBuDOfpkgU3KHNshhp/kpgnHYVH0CbKwZAGAAAASADBT+aowSfSdaffqU39U3TXlTN1c+YG+Q1vX0skYkY1OaeNJrx8kVp8U6hGn891ektAtdAmDsaQBgAAAEgg/s/nqvXn0jvP9dZLPS5Q3o05Gpn9qYZkbFPQ8Du9vSoJmRG9uK+5Hl9+utKfyVTG/C1qtW6W09sCaoU2ITGkAQAAABJSeO161Vm7XnVmStM79tdT3ZooZ2iu2tbfo+c7vKmg/Er1JTm9TUlSQbRYIUX0+1W/05rdDVT/2XRlLNyuxquXSZLCDu8PsBJtJjaGNAAAAECCi6xco9SVa5T6phRKS9MV2TcpNztDOwfuV/esTZrYdqYkqYnf/ssGR8yodkX3S5JuX3uJFm5sqcZv1lHGin0ylq1Ri4KtkvjhD4mBNhMPQxoAAAAAv4rm50vzFitjnpTxilRQt66uy7pe0eSglt+QLjM1oqT0Yr3R5wmlGJFfvy8rkKxkI1ilYxSZIW0MF/3663wzoMu/G6ZQfpKMAr+yp+TJVxSSNm5Vu9wFkiSz9ANIVLSZGBjSAAAAAChXJDdX+iVXktRpRMnnjEBA92VdIRnGr7dbc1VLFTaLlLXEEeps8avty5t++4Rpqv3GX2SGS56DNyVVbSUgcdFmfGJIAwAAAKBazHBY4bXrD/lcq3+sq9YavCUCsB5tep+3r+kFAAAAAAAQJxjSAAAAAAAAuABDGgAAAAAAABdgSAMAAAAAAOACDGkAAAAAAABcgCENAAAAAACACzCkAQAAAAAAcAGGNAAAAAAAAC7AkAYAAAAAAMAFGNIAAAAAAAC4AEMaAAAAAAAAF2BIAwAAAAAA4AIMaQAAAAAAAFyAIQ0AAAAAAIALMKQBAAAAAABwAYY0AAAAAAAALsCQBgAAAAAAwAUY0gAAAAAAALgAQxoAAAAAAAAXYEgDAAAAAADgAgxpAAAAAAAAXIAhDQAAAAAAgAswpAEAAAAAAHABwzRNp/cAAAAAAACQ8HglDQAAAAAAgAswpAEAAAAAAHABhjQAAAAAAAAuwJAGAAAAAADABRjSAAAAAAAAuABDGgAAAAAAABdgSAMAAAAAAOACDGkAAAAAAABcgCENAAAAAACACzCkAQAAAAAAcAGGNAAAAAAAAC7AkAYAAAAAAMAFGNIAAAAAAAC4AEMaAAAAAAAAF2BIAwAAAAAA4AIMaQAAAAAAAFyAIQ0AAAAAAIALMKQBAAAAAABwAYY0AAAAAAAALsCQBgAAAAAAwAUY0gAAAAAAALgAQxoAAAAAAAAXYEgDAAAAAADgAgxpAAAAAAAAXIAhDQAAAAAAgAswpAEAAAAAAHABhjQAAAAAAAAuwJAGAAAAAADABRjSAAAAAAAAuABDGgAAAAAAABdgSAMAAAAAAOACDGkAAAAAAABcgCENAAAAAACACzCkAQAAAAAAcAGGNAAAAAAAAC7AkAYAAAAAAMAFGNIAAAAAAAC4AEMaAAAAAAAAFwhU9MUBvkFmrDYCuM3H0VcNp/dQHtpEIqNNwJ1oE3An2gTcqbw2eSUNAAAAAACACzCkAQAAAAAAcAGGNAAAAAAAAC7AkAYAAAAAAMAFGNIAAAAAAAC4AEMaAAAAAAAAF2BIAwAAAAAA4AIMaQAAAAAAAFyAIQ0AAAAAAIALMKQBAAAAAABwAYY0AAAAAAAALsCQBgAAAAAAwAUY0gAAAAAAALgAQxoAAAAAAAAXYEgDAAAAAADgAgxpAAAAAAAAXIAhDQAAAAAAgAswpAEAAAAAAHABhjQAAAAAAAAuwJAGAAAAAADABRjSAAAAAAAAuABDGgAAAAAAABdgSAMAAAAAAOACDGkAAAAAAABcgCENAAAAAACACzCkAQAAAAAAcAGGNAAAAAAAAC7AkAYAAAAAAMAFGNIAAAAAAAC4AEMaAAAAAAAAF2BIAwAAAAAA4AIMaQAAAAAAAFyAIQ0AAAAAAIALMKQBAAAAAABwAYY0AAAAAAAALsCQBgAAAAAAwAUY0gAAAAAAALhAwOkNAAAAVJf/6GxFU5MqvI0vv0iRJStitCMAEm0CbkWb3sGQBgAAuJa/YzuFmmWqoHmyCq7JkWGYMgxTj3edrh5JxRV+74LiJN25+EqZpiHTNJT6QqZStxQpuDVHkZVrYvQ7AOITbQLuRJvex5AGAAC4RqBVlvYf1UybT05Sy5M36tpWX2lw+nZJUtDwH3RLn6SUCtc6OUWa03vGr78OHReRJM3Ia6IpG07W5m+y1HxWseos2arwho1W/1aAuEKbgDvRZvwxTNMs94sDfIPK/yIQ5z6Ovmo4vYfy0CYSGW3Gp/AZvbXzzgLd1GmWRtRfF9Njj9vTRk+tOElNxtaR//O5MT12PKHN+ESb3keb8Yk2va+8NnklDQAAcIS/aRNtGNpRJ10+T/c3G6vWgXRH9jGi/jqNOGGd1kzL0z+3nqPvXuuhVtNWKLJjhyP7AZxGm4A70WZi4JU0QDl41gFwJ9r0OMNQ5LRe2nJHkW4/6isNr7fB6R2VadyeNpq0pL9ajE+S/8t5UgWPl1CCNj2ONuMWbXocbcYtXkkDAAAc5W/UUCvHZenNEyeoa1Idp7dToRH112nESeu08LhCXTrrVmWPWK/Irt1ObwuwBW0C7kSbicnn9AYAAEB882VkaPN9J+m8L1dqySlTXf9A82Ddk1K05NRndPZXq7V59EnyZWQ4vSXAMrQJuBNtJjaGNAAAwBZGcrJCZ/XWpuez9NNdYzWi/jr5De899Agafo2sv1Y/jRyrjc+1UvjM3jKSk53eFlBjtAm4E21C4u1OAADABr7UVC19/Gh9MmCMOgTTJQWd3lKtJRtBLerzkpYfm69zPhqpLnctVrSgwOltAdVCm4A70SYO8N5YDgAAuFrk9GO1/ZUsLT1vUukDzfiSHUzT0vMnatv0VoqcdqzT2wGqjDYBd6JNHIwhDQAAsEz4jN667YnXNKf3DCUb3n8WsDzJRlBzj3tFw558XZHTecAJ96NNwJ1oE4djSAMAAGrNl5qqNf8+USOeeEWXpec6vZ2YGZyeo9ueeE1r/nWifKmpTm8HOAJt0ibciTZpszwMaQAAQK34UlO19LGuWvz78RqYluf0dmLusvRcLb52vJY+eox8KSlObwf4FW3SJtyJNmmzIgxpAABAjflSUrT0sa5afuFkBQ2/09txTNDwa/lFk7R0THcecMIVaLMEbcJtaLMEbZaPIQ0AAKgRX0qKlo7pnvAPNA8IGn4tvWgCDzjhONo8FG3CLWjzULRZNoY0AACg2ozkZC0d011LL5rAA82DJBvBkgecj3aXkZzs9HaQgGizbLQJp9Fm2WjzSAxpAABAtRX3P0Zfnv9oXF+JoqaSjaA+u+BRhfod4/RWkIBos3y0CSfRZvlo81AMaQAAQLVET+2lGye8pdaBdKe34lrtgukaOmGmov17Ob0VJBDarBxtwgm0WTna/A1DGgAAUGX++vV11vhvdHXGLqe34nrX1t2p0yfMkr9eptNbQQKgzaqjTcQSbVYdbZZgSAMAAKrEl5qqJY900MgGvzi9Fc+4p+HPWvJIJ/lSU53eCuIYbVYfbSIWaLP6aJMhDQAAqKKtN/TU0nMn8X76akg2glp63iRtvb6n01tBHKPN6qNNxAJtVh9tMqQBAABV4K9bVwNv/oIHmjWQbAR18bAv5a9b1+mtIA7RZs3RJuxEmzWX6G0ypAEAAJVa+ngn/anRIqe34VkPNFqoJWOynd4G4hBt1g5twi60WTuJ3CZDGgAAUCHzpB569dRJChp+p7fiWUHDr1dOnyT17e70VhBHaLP2aBN2oM3aS+Q2GdIAAIBy+etlasvokHonJzm9Fc87ITmoTfdFEv6qFbAGbVqHNmEl2rROorbJkAYAAJRr65CjtajPS05vI2783PdFbbviaKe3gThAm9aiTViFNq2ViG0ypAEAAGXyN2ygAcNmO72NuHPGLd/J37CB09uAh9GmPWgTtUWb9ki0NgNObwAAALjT/uPa68Gmnzm9jTJFzKi+LgxozMYBZX59ZNbH6p8Slt9w3/NR/246RwN63azgJ7ud3go8ijbtQZuoLdq0R6K1yZAGAACUacPQsNNb+FXIjGj01j6avytLea80V911xUrenq/owqVl3v7B7oP1f03SlNs2SemDt6hnw416uNn3rjiJo9/wad11UXX8xOmdwKto0x60idqiTXskWpsMaQAAwBGM3l31zkkTJaU6uo8lxQW69ufrFHm3oZq9tlzJO9cqWWslSdEKvi+6cKmCkhpK0tPS8kYN1WfQHQpcuFMvHDNN2cE0+zdfgXf7TdCoXjfLnLfY0X3Ae2jTXrSJmqJNeyVSmwxpAADAEbb0y1R2MMWx428M5+nUL0eo09iQGsxZLJnLFanFepGdu9R40mxpsqE7e9+iFSOD+vKUccoKpFu25+rIDqZoa/9MNZ3nyOHhYbRpL9pETdGmvRKpTfe94QwAADgq0KypLrjuG8fel37PlmN18T9Hq+PQhTJ/+lkyTesWN02ZP/2sjtcu1MX/Gq3RW3tZt3Y1+A2fzrl+lvxNmzhyfHgTbdqPNlETtGm/RGqTIQ0AADhEcecW+lPjH2J+3O2RfLX74CYtubKtGk+eLUVr8xxgJaIRNZ40W4uvaKd2H9yk7ZF8+45Vjj83/k6hTi1iflx4F23GBm2iumgzNhKlTYY0AADgEKtuNJTui+1LtrdH8nXGhNHKvmmeIitWx+y4kRWrlX3TPJ0+cXTMH3Cm+1K06ibnT8gI76DN2KBNVBdtxkaitMmQBgAA/MoIJql+/byYHvPAA82WD31v77OA5YlGlPXg94484KzXIE9GgFMEonK0SZtwJ9qkTasxpAEAAL/ydWqrN3tMidnxtkfydcb40Wr5oM0v065MNKKsf8/WGRNi+4Dz9R7PyNehbcyOB++iTdqEO9EmbVqNIQ0AAPhVYYsMZcToxIfbI/k6c9xotXxotrUnOawp01TLB2frjPGxe8CZ4TNU1DIzJseCt9EmbcKdaJM2rcaQBgAA/GrNVYbq+1Njcqz+z96rFg/NcscDzQNMUy0fmq1+z98bk8M18qdp9VVGTI4Fb6NN2oQ70SZtWo0hDQAA+I0Rmwd+16/vr45PbYzJsarNNNXpyU26cX2/2Bwvvh9rwiq0SZtwJ9qkTYsxpAEAAJKkQMsW+uuJM20/zsZwnlY+dLTC6zbYfqyaCq9dr2UPd9XGsP0ng/zLyW8r0LyZ7ceBd9Hmb2gTbkKbv6FN6zCkAQAAJZKT1L/OWtsPc/rLo5X65g+2H6e20t74Qae9Mtr24/Svs1pKSbb9OPAw2jwEbcI1aPMQtGkNhjQAACBm3itIUfYTW9z1fvrymKayn9iqDwri94EgcABtAu5Em4mHIQ0AAJAk7T2umTJ89r7R+66Z1ym8Zp2tx7BSZNVaDX/neluPkekzlNM7fl+2jdqjzSPRJtyANo9Em7XHkAYAAEiSNp8WVSN/mm3rbwznqdls0xvPBh5gmmo2W9pi43vsG/nTtPlU25ZHHKDNMtAmXIA2y0CbtcaQBgAAxMTQ5Vcp490FTm+j2uq+u1DXrbjS6W0AtqFNwJ1oMzExpAEAADGx4aeWihYWOr2NaosWFGj1nFZObwOwDW0C7kSbiYkhDQAAsF3JS7YjTm+jxprNjtr60m3AKbQJuBNtJi6GNAAAwHY7I0Fl/LDe6W3UWN0fNmhHNOD0NgDL0SbgTrSZuBjSAAAA280pbCMz7N1nBM1wWHMLWzu9DcBytAm4E20mLoY0AADAdv/49BJFduxwehs1Ftm2XX/9fKDT2wAsR5uAO9Fm4mJIAwAA7Oehq4eWKx5+D8Dh4uHfdTz8HoDDxcO/63j4PTiAIQ0AAJAkGabh9BYAlIE2AXeiTdiBIQ0AAJAkdZhRzJUYHLAxnKcOM4qd3gZcjDadQZuoDG06I97bZEgDAAAkSUkb9qiQlybHXJEpJW3c7fQ24GK06QzaRGVo0xnx3iZDGgAAAAAAABdgSAMAACRJZu4+jd95ii1rdzh6s3xpabasHQu+tDRld95sy9pjd5wuM3efLWsjPtBm+WgTTqLN8tFmzTGkAQAAkqTIzl16Y2EvW9Z+uP1r8tXNsGXtWPDVy9TDHV6zZe13FvRQZFf8vmwbtUeb5aNNOIk2y0ebNceQBgAA/MooCNiybtCIyszw7jOCZt00BRW1fN2IGZVR4Ld8XcQf2iwbbcJptFk22qw5hjQAAOBX2VPytDOSb/m6XYLJWvX7JpavGyurrmmko5JSLV93V3S/sqdwZRBUjjbLRptwGm2WjTZrjiENAAD4lS93v5aF6li+rt/wqbhxRPJ58Nkvn1/FjcK2LL0iVEe+fQW2rI34QptloE24AG2WgTZrhSENAAD4VWTFat00Z6gta79w9mT5O7e3ZW07+bt00MsDJtuy9g0/XqfIyjW2rI34QptHok24AW0eiTZrhyENAAA4RNGWVEVM699HfnKKT2svb2z5unZbM6iR+qZY/0xmxIwqvMX6l4IjftHmoWgTbkGbh6LN2mFIAwAADpH9XL72m8W2rN3ngkXypaTYsrYdfKmp6nf+AlvW3m8Wq9Pz8XsJUViPNn9Dm3AT2vwNbdYeQxoAAHAIY9k6XbfmQlvWfrTlh9p1hT2XK7XDzit66KEWH9uy9rWrL5KxfL0tayM+0eZvaBNuQpu/oc3aY0gDAAAOEd23T5sndFTIjFi+dn1/qs4e9Y38R3WyfG2r+Y/O1vkjv1J9v/UvrQ6ZEW2d0EHRffH/jCCsQ5slaBNuQ5slaNMaDGkAAMAR6i3YpY/2p9my9t+bLNLS2xu4+4oVPr+W3l5ff2282Jbl/1uQoXrzd9qyNuIbbdIm3Ik2adMqDGkAAMARIktW6M53rrNt/Xm/G6PcK463bf3ayr3yeM0bOMa29Ue9c60iy1batj7iF23SJtyJNmnTKgxpAABAmdq+E1JB1J4TIWb66ujS+z+W0aurLevXhtG7qwb96SNl+urYsn5etFDt3rHnzxWJgTZpE+5Em7RpBYY0AACgTMFvf9aVqy62bf3RDVbp7Odny+jtngecxnHH6NznvtXdDVbbdowrV/5OgVn2vBwciYE27UGbqC3atEeitcmQBgAAlMksKtKesW2UE91v2zHubrBa5z73rYzju9l2jCo7oZsuePZrjay/1rZD5ET3K3dMK5lFRbYdA/GPNq1Hm7ACbVovEdtkSAMAAMqV9vYcHTtjlK3HGFl/rS6Y9pV0goMPOE/opounfaER9dfZepjer4xS6rtzbT0GEgNtWos2YRXatFYitsmQBgAAlMsMh9V58g69nlfX1uOMqL9OF079SsXnHCcjmGTrsQ5mBJNUfM5xunjaFxpeb4Otx5qRl6nsydtlhsO2HgeJgTatQ5uwEm1aJ1HbZEgDAAAqFFm+Sn9+7hrtjOTbepwR9dfp1afHauU/eyvQro2tx5KkQLs2WvmvY/XG04/b/kBzZyRf//vs1YqssO89+0g8tFl7tAk70GbtJXKbDGkAAEClWv/7B920+lLbj9PIn6ZlV03QiTOXqej84yWf3/JjGIGAis4/XifPXKplQyaqvj/V8mMc7qbVl6rVv763/ThIPLRZO7QJu9Bm7SRymwxpAABApcxwWDsmtNN2m58VlCS/4dMDjZbqzSfGav9/Wyv/8j4KtMqq9bqBNq2Uf3kfFb6fpTefGKs/NVomv2H/Q6HtkXztmNBOikZsPxYSD23WHG3CTrRZc4neZsDpDQCAGwWaNZUkhbdtl0yz4hsbhgLNmsqMRhXZtj0GuwOckf7q9zqj/Wh9MfxhNfKn2X68+v5UfdXtTelx6cmcFhrz0kDVWxFV/S/WVKvNPae21Z5sn0YNeUvDMt8p/aL9zwJKJQ80zxg/Wi1fnR2T4yEx0Wb10SZigTarjzYlw6zgL2qAb1Alf4tA/Po4+qrh9B7KQ5v28zdsoGX3Z+vS077Xe6u7Ku29jDJvV3Bhrs5v94ve/LyPsv++TJE9e2K808RDm87ypaQo89NUTW/3mWN7mLy3pdYUNdY7q46psM0L2y9Wu+QdurXephjv8DeXrzpL+QPyFC0sdGwPsUKbzqLN6qFNd6DN2KBNdyqvTYY0QDm4Q4O/YQNtm9ZIPxw7vdyXdkbMqI776So1v24bA5oYoU3n+Tu2U6uXtuqJrMR9lqsqblzfT1uuaazIyjVObyUmaNN5tFk1tOketImD0WYJzkkDAOWI7Nqtptfv0ri97cu9zdg9HdX8hu0MaJBQIivXaP1NbTS/qMjprbjWnKJibbmxZcI80IQ70GblaBNOoM3K0eZvGNIAQAUiO3fpmWnnK2QeeeKykBnR1GnnKrJrtwM7A5wV/XmFrh0/ShvDeU5vxXU2hvN0w+MjFVmy0umtIAHRZvloE06izfLR5qEY0gBAJVpNXabX8xod8fkZeU3UaupSB3YEuEA0ouaPfa/zx97HA86DbAzn6YLH7lOzsd8n7FUp4DDaLBNtwnG0WSbaPBJDGgCoRGT3Xv1l/kVHfP6vcy9UZE+OAzsCXOLAA84xPOCUSh9oPsoDTbgAbR6CNuEatHkI2iwbQxoAqEw0oqQ56Ud8OnlOGncoQDSi5mO+1wWPJfYDzt+eCZzN/y/AHWhTEm3ChWhTEm1WJOD0BgAAgMdFI2o2ZrYGb7lXXUct0lOtvnV6RzF14/p+WvLYMWo2Y7ZUwVUzgZijTdqEO9EmbVaAV9IAAIDaM01lTP9Om69spBvX93N6NzFz/fr+2jqkoTJe+Y4HmnAn2qRNuBNt0mY5GNIAQGUMQ/ubRo/49P6mpmQYDmwIcK/wmnXaemUDdZ56m7ZH8p3ejm22R/LVecpt2n5FPYXXrHN6O0ClaBNwJ9rE4RjSAEAljKQk/fH8t474/H0XzpSRlBT7DQEuF167Xm0f+E5nPj5a03KbOL0dyz2T00xnPj5abR+YrfC6DU5vB6gy2gTciTZxMIY0AFCJ3IG9dFH6qiM+PzB9hfZd0suBHQEeYJpq8fAsvXreicp+9jbtiRQ4vaNa2xnJV+ept+mN805Qi4dnOb0doGZoE3An2kQpThwMABUwAgE1G75KTfxpR3ytiT9NjYevUeEbAZnhsAO7A9wvvGad2v95k3731V2Kjtyp97u+rHRfitPbqpa8aKHO/fkqBcc0VNuPflCYq1AgDtAm4E60CV5JAwDl8fm17k8n6Ml2b5V7k6fbv6H1fzyBc9MAFTDDYSX/90elXrhJxz91t57JaaaQ6f4HbCEzoidzWuj4J+9W+kUblfTBj1wmFHGFNgF3os3EZpgVnFF5gG8Qp1tGwvo4+qprf+qmzRjw+bX+//XRrBsfUX1/aoU33RnJV/+nRqv137/njigGaNP7Am1ba9X1WWrSd4tmHv1ipY3F2p5IgS5afI12ft9MHaZs4P3zVUSb3keb8Yk2vY8241N5bfJ2JwA4jC8jQ2vu7abZN1Q+oJGkRv40zbr5EZ1k3Ku2jy5SdN++GOwS8K7w2vVq85f18qWk6Hdn3KV1l5v618mv67L0nQoafkf2FDIjmpHXRA98+zu1edVQxueLlFa4WryREYmENgF3os3EwitpgHLwrEOC8fkVaNpYWy9up5Nv/kl/a/aVMn11qrVETnS/7t9ymmY/fayavb1G4W07eGWNDWgzPgWyWmrVzW3UqM9Wje/8spr6Q2oeSLf1mFvCedoWCeqOZUNKnv17ap3CGzfZesx4RpvxiTa9jzbjE216X3ltMqQBysEdWmLJuaavLrzvC52Qukpnp4ZqtdZHBUH9UNBB7/37NNV96TuLdogDaDO++VJT5cusq5yT22j7cT51OXGN7s76SKm+Ip2QHKzV2j8UhVQQTdYjG87R8u/aqsmPUWXOWqdoTq6iBd6/iobTaDO+0aZ30WZ8o03vYkgDVBN3aInFl5oqo06K1LSR1l7WSGbp3/45l/yg/hnLK/zer/dl68OZJ0iSjKjU9vUd0vZdMvcXcgdmA9pMLLTpHbSZWGjTO2gzsdCmdzCkAaqJOzRIJXd08lfyXt9IhDuuGKJNSLTpRrQJiTbdiDYh0aYbceJgAKgB7qgAd6JNwJ1oE3An2vQOn9MbAAAAAAAAAEMaAAAAAAAAV2BIAwAAAAAA4AIMaQAAAAAAAFyAIQ0AAAAAAIALMKQBAAAAAABwAYY0AAAAAAAALsCQBgAAAAAAwAUY0gAAAAAAALgAQxoAAAAAAAAXYEgDAAAAAADgAgxpAAAAAAAAXIAhDQAAAAAAgAswpAEAAAAAAHABhjQAAAAAAAAuwJAGAAAAAADABRjSAAAAAAAAuABDGgAAAAAAABdgSAMAAAAAAOACDGkAAAAAAABcgCENAAAAAACACzCkAQAAAAAAcAGGNAAAAAAAAC7AkAYAAAAAAMAFGNIAAAAAAAC4AEMaAAAAAAAAF2BIAwAAAAAA4AIMaQAAAAAAAFyAIQ0AAAAAAIALMKQBAAAAAABwAYY0AAAAAAAALsCQBgAAAAAAwAUY0gAAAAAAALgAQxoAAAAAAAAXYEgDAAAAAADgAgxpAAAAAAAAXIAhDQAAAAAAgAswpAEAAAAAAHABhjQAAAAAAAAuwJAGAAAAAADABRjSAAAAAAAAuABDGgAAAAAAABdgSAMAAAAAAOACDGkAAAAAAABcgCENAAAAAACACzCkAQAAAAAAcAGGNAAAAAAAAC7AkAYAAAAAAMAFGNIAAAAAAAC4AEMaAAAAAAAAF2BIAwAAAAAA4AIMaQAAAAAAAFyAIQ0AAAAAAIALMKQBAAAAAABwAYY0AAAAAAAALsCQBgAAAAAAwAUM0zSd3gMAAAAAAEDC45U0AAAAAAAALsCQBgAAAAAAwAUY0gAAAAAAALgAQxoAAAAAAAAXYEgDAAAAAADgAgxpAAAAAAAAXIAhDQAAAAAAgAswpAEAAAAAAHABhjQAAAAAAAAuwJAGAAAAAADABRjSAAAAAAAAuABDGgAAAAAAABdgSAMAAAAAAOACDGkAAAAAAABcgCENAAAAAACACzCkAQAAAAAAcAGGNAAAAAAAAC7AkAYAAAAAAMAFGNIAAAAAAAC4AEMaAAAAAAAAF2BIAwAAAAAA4AIMaQAAAAAAAFyAIQ0AAAAAAIALMKQBAAAAAABwAYY0AAAAAAAALsCQBgAAAAAAwAUY0gAAAAAAALgAQxoAAAAAAAAXYEgDAAAAAADgAgxpAAAAAAAAXIAhDQAAAAAAgAswpAEAAAAAAHABhjQAAAAAAAAuwJAGAAAAAADABRjSAAAAAAAAuABDGgAAAAAAABdgSAMAAAAAAOACgYq+OMA3yIzVRgC3+Tj6quH0HspDm0hktAm4E20C7kSbgDuV1yavpAEAAAAAAHABhjQAAAAAAAAuwJAGAAAAAADABRjSAAAAAAAAuABDGgAAAAAAABdgSAMAAAAAAOACDGkAAAAAAABcgCENAAAAAACACzCkAQAAAAAAcAGGNAAAAAAAAC7AkAYAAAAAAMAFGNIAAAAAAAC4AEMaAAAAAAAAF2BIAwAAAAAA4AIMaQAAAAAAAFyAIQ0AAAAAAIALMKQBAAAAAABwAYY0AAAAAAAALsCQBgAAAAAAwAUY0gAAAAAAALgAQxoAAAAAAAAXYEgDAAAAAADgAgxpAAAAAAAAXCDg9AYSjREIyN8669dfmz5Da4c01/7m4Sp9f53NAbWdvkVG1CxdwFRkwyaZ4ap9P4Cy0SbgTrQJuBNtAu5Em97HkMZG/nqZUstmiqYEtPyGdJmpYaWkF+uN459QihH99XYtAslKNoJVWrPIDGnzzUW//rrA9OuyH4apKD9JRkFA2VPy5CsMS5u2KrI3x/LfExAPaBNwJ9oE3Ik2AXeizfhkmKZZ7hcH+AaV/0VUzDC08tE+euiCl3RqnS1q5E+LyWF3RvL12f4W+uO7Q9Txnu+lCv5+UbGPo68aTu+hPLRZPb60NJlHtVNux3Tt+l2BemVt1OOt35FPimmbUUl3rr9I8zZmqeGbqaq7Mk/GkjWK5ufHZA/xgjbjB23GF9qMH7QZX2gzftBmfCmvTYY0NjKCSVL3Tlo2vI4Wnz1Rqb4kW49XEC1W1w9vV+eJ+6WFK2SGim09XrzjDs3b/B3baV/3Jsq9Nlft6u/WCx1myief7R1WVUG0WFFFdc2qS7R6TwNlPltXGYu2K7JyjdNbcz3a9DbajF+06W20Gb9o09toM36V1yZvd7KRGSqW5ixW59uSdcyjI7Rk4Pgqv8ysugqixTrmzRHqfO98mUVFlX8DEIcC7doot2czFd64RyM7farB6dsVNPylX01xdG+HO3DH+lanDyVJoeMjmpHXRGNWnKk6T9dTxvytCq9d7+QWAcvQJuBOtAm4E20mNl5JEyNGcrKWjemhpRdPsHxQU2SGdNRbdyj7bgY0VuJZB+8In9Fbm/sna9SVb2lY5mant2OJyXtbauz0S9TimyIFPpvj9HZchTa9gzYTC216B20mFtr0DtpMLLzdyQUCzZvpok8X6dZ6myxdd8LeVnr/jKMV3rrN0nUTHXdo7ld8znHKvzNHb3SbqqxAutPbscXGcJ4uXXS90sdmKvjRT05vxxVo0/1oMzHRpvvRZmKiTfejzcTE251cILxlqx787jzdeu7Tlq77yKxzlL2Vf+hIED6/is8+Vvkj9uq1bmPUOpAuKT7vzCQpK5CuH3q9qjVP5WnwohuUPj5TSR/NlaIRp7cGHIo2aRPuRJu0CXeiTdosB0OaGGv/oqk9AwpU359qyXo7I/lq/xIDaMQ/IxBQ4YBeyh+eo+ndHlOHYHzfkR2uXTBdPx47Q6ueyNPghTeo7oRMJX8yT2Y47PTWkOBokzbhTrRJm3An2qTNyjCkibHkrXkKybqhSlRS8tZ9Yv6IeGUEk1Q4oIfyb0/MO7LDdQima07vGVr+RL6GLLxeGRMzlfLJAq7mhpijzUPRJtyCNg9Fm3AL2jwUbZaPIQ0A1wo0b6aVY5ro/b7ckR0uO5imOb1naNXkPJ03+3Z1GrmN81IhZmizfLQJJ9Fm+WgTTqLN8tHmkXxObyDRbOvXQOkWXt0p1fBrW7+Glq0HuIEvI0Pr/3KSrvj8J/3cb2rpnRnK0iGYrsX9p2rQF/O0/i8nyZeR4fSWEMdos+poE7FEm1VHm4gl2qw62vwNQ5pY8vm17/T8X68lb4V0X4pyT9sv+fyWrQk4KXT2cdo7o4kWDhuna+vuVNDg33ZlgoZf19XdroXDxmnvjCYKndXb6S0hDtFm9dEmYoE2q482EQu0WX20WYK3O8WQ0auLZvadLOnIkwZ/sd+nXZGKJ6sN/Xk6rU70iM+/ddIk3dPjJpnzFlu1VSDmfGlpWvVAdz02aKouSC2U5I47stq0GWtBw6/ZPV7X25NSde+rQ9Xh7wsULShwelvwONqsPdqEHWiz9mgTdqDN2kv0NhnSxIi/U3u1nbxKOdFkPZnTQnP2tdGsV3vpwDmEW83cKnPrjgrXMJo30YiLm5b+Qjpp0Dz1zlin7skb1OaJ1dpwdXtFVqy2+XcCWM/fqb2W3l9fywaMd+xZhu8KI1pY1MryNvumxP73c3Fagc4bOl7ZzYfpqH/sVmTlmpjvAfHBzW02XBJSMK/iK0GE0gPadVTpW4xpE3GENq1Fm7AKbVorUds0TLP8Kw0N8A3i2s4W8KWkaOtNx8qImGo8J0/GguVS1Kz1mauNYJLkM2T26qwdvdJk+g01e3quooWFFu08sX0cfdVweg/liac2w2f21u2TXtXAtL3yG7F7B+bC4kL9d183PbWwnzK+raMmP+2zpc3tx6ZrX78C3dztW52XsUjdk1Is+h1ULmJG9Xp+fT1x6+UKfDYnZse1G23GhlvaTN0RUcrusAqaBlV4xV4ZhinDMPV41+nqkVRxqwuKk3Tn4itlmoZM01DK9HpK3R5SYYOAChr7adNitBkbtGkf2ow92qw92vSu8tpkSBMrhiFV8GftmWMkEO7Q7OVLSVHOwJ66728vaGBaXsyO++ju9pr67Llq9sN++b5eKJnR2LRp+BQ5pYe2HZ+i64d+oLsbxO5Vb2/lp+uhB65R5sz5cTHEpU17Od1mxvqoknIj2nJSQFknbtINrb7V4PTtklTrZyVDZkSSNCOviaZsOFmbZrVUs9lhFdf1a19rH23WEm3aizZps6Zo0160SZs1xZAGqCbu0OzjS0nR0jHdtfSiCUq28Gpn5VkTytMl825WxkuZyvx8lSI7Kn77kt38jRsr5/QO2ndVjmb2ekrtYnCm/yIzpC7vDFeXkQs9f6dGm/Zxsk0jYmrf73N1U6dZGlF/ne3HPti4PW309IqTlPF8XZl+Q3lX5egt2qw22rQPbdJmbdCmfWiTNmuDIQ1QTdyh2cNITtaysT1icmf26O72eubFc9Vi1n75vpxn67FqKnpqL20+qY5uvuZ9jay/1tZjFZkhdXl7uDqPXCCzqMjWY9mJNu3hRJsNlka0t5NfJ10+T/c3+1itA85emnRNKE//3HqOvnuth+qtjGh3Fz9tVgNt2oM2abO2aNMetEmbtcWQBqgm7tCs5+t5tJaOSNXScyfZeme2JZynM5+6T+2mrlN44ybbjmOlQKssrb6htT678SE1t/EOtyBarK4f3K4u4/IVXbDEtuPYiTatF8s2z3jmPtVfFlXOoH26/aivNLzeBtuOVxvj9rTRpCX9Ve/VdO0+2qfPr6fNytCm9WjzSLRZfbRpPdo8Em1WH0MaoJq4Q7OWeWIPXfrMJ7q1nn1Dkz2RAp0250Y1HlNH/q8WSNGIbceyhc+vyKk9tGtkgb7oPVWZvjq2HWrC3lZ6+4bTpe8W2nYMu9CmtWLV5hlzb1DG1LraNqRQb/R5Ql2T7Pv3baWFxYW6/LthavpKHeVfv1efHzuNNstBm9aizYrRZtXRprVos2K0WXXltRm7004DSFh235kVmSE9uKuTThl3r5pfvkL+L+Z6b0AjSdGI/J/PVdPLVurkcffo4d0dVGSGbDnU8HobdPGUz6W+3W1ZH94QqzZPeupeFX/XQIP+8aF+6TfNMw80Jal7UooW95+qy/7+oYpmN1Tfp2gT9qPNytEmnECblaPN2uOVNEA5eNbBGr6eR+uSl7607c4sL1qoXi+MUvbYNQpv2WrLMZwSaNlCy+9so3lXP6Z0nz2XOZy8t6VmDjnFUy8TpU1rxKLNnq+MVJMfpbwrc/Tj8c/F5KSKdioyQzruh6HKeKWutp0gLRg8hjYPQpvWoM3qo82K0aY1aLP6aLNivJIGQMwZyclaOiLVtjuzMXva6qTH7laHP8+JuwGNJIU3bVaHB+boxDF3a9yeNrYc49Z6m7T0jnQZycm2rA93ikWbfSberWijYj3/4CNaeMLLnn+gKUnJRlCL+rykaQ/+R2aDkPpMpE1YizZrhjZhN9qsGdqsGYY0AGzhS0kpOeP9uZNsWf/h3R30wTUnq/l/ZskMFdtyDDcwQ8Vq8cgsvXdtPz26u70tx1h6/kQtG9NDvhR7ntmAu8SizefGn6eUE3dqyVlPqEMMLscZa9nBNC0ZMFnJfXdp6rjzaROWoM3ao03YgTZrjzarh7c7AeXgpaE150tJ0dIx3W25JGFetFDdPh6uLmP3Kzr/F0vXdjujV1ctvytFC8+aYPlLRYvMkLq8M1xdRi5UtLDQ0rWtRps1F4s263+fpPvvflGXpedaur5bzcjL1L8fvUp7+xbTJm3WGG1ajzZ/Q5s1R5vWo83f8HYnADGTM7CnLXdmOdH96vnyKHW+eUHCDWgkyZy3WNk3LVDP6SOVF7X2TifZCGrpRROUc0lPS9eFu9jZZvc37lJgR5L+3z3PJ8wDTUkanJ6j++9+Uf7tSer+5l20iRqhTevRJqxAm9ajzcoxpAFgqfCZvXXf316w5dmG3i/frY5//FFmOGzp2l5ihsPq+D8/qecr9gxq7vnbSwqf0dvSdeEOdrbZ642RMlMj+uXq8RqYlmfp+l5wWXqufrl6vMw6EXV/y54HnLQZv2jTPrSJ2qBN+9BmxRjSALCMv1N73T7pVcvvbPKiher58qiEH9AcUDKomWvLoOay9FzdMvk1+Tu2s3RdOMvONru/cZfMtIiWn/eEgobf0vW9JGj4tfy8J2QmR215ZpA24xNt2o82URO0aT/aLB9DGgCW8KWlaen99TUwba/WhPJ04/p+v37cvOFkbY/k12jdgmixek4fyYDmMGaoWB3/Z656zBipgmjNTpy8PZKvmzecfMjf1ZpQni5L26Ml9zeQLzXV4l3DCQe3aaWCaHHJA83UiJafm9gPNA8IGn4tPX+izJSour91V43bLA9txhfajB3aRHXQZuzQZtkY0gCwxKr7u+uW3l+p+/g7NOzaEdrYN+/Xj/V9CzTkujvV+ZnbNC23SZXXLIgWq9uMO9Xxj3MZ0JTBDBWr0x/mqttrd6rIDFX5+57JaaYuT9+mIUPv1Pq+BYf8XQ27doS6j79Dtx//hVb/qYeNu0esrHqgu5YNeFJ+w7q7/IJosY55c4TM1IiWnjeJB5oHSTaCJQ84k6I6ZuaIarVZGb/h0/Kzn9Tq+2kzHtBmbNEmqoo2Y4s2j8SQBkCtmSf3VOYK6avzspX1r1nyfTnvsBuYCnw6R23/PFuvnn+SOr50a5Ve0jhuT1d1fnB1XF9iu7bMULG6/HuNHt/TpdLb5kUL1fHF2/TGBX3V5v/NVuCzOdJhV/jzfTlPWf+apS/OO0p1V0nmSd66U8OhQmcfp8cGTbX8weC4PV3V7BtDX549xvL36seDZCOoz855TM2/NKrUZnUEDb8eHvysQmd58332KEGbzqBNVIY2nUGbh2JIA6DWgmu3q8GzPyi8cVOltw2vXquOf5yrXi+OqnBQM2ZPW31+Q19Ftm23cqtxKbx1mz654SSN29Om3NvkRQt17Auj1PFPcxRevbbyNTdsVINnf1Bw3Q4Ld4pY8mVkaP+oPbog1dr3eI/b00bTJw3Q8P97Va0D6ZauHU/aBdN1y/+9ppcmnqMJe1tZuvbFaQXKG5UrX1qapesiNmjTWbSJ8tCms2jzNwxpANRaeNNmKRqp8u3NULE6PDBHvV4oe1CzM5Kvt+86U+aPi6zcZnz7YZHeuHuAdpZx7p8DA5r2f55TvVclRSMlf7fwpLV3d9NX3WdYuubOSL5m/PlcXXnbx7o6Y5ela8eja+vu1KBbP9XLfz6/zDZr49ue07Xubl7p5kW06TzaRFlo03m0WYIhDQBHmKFidfjzHJ218JpDPp8XLdRJL96rpC8Z0FRX8mcLdeKL9x4x+Dpjwe+rP6CBpwWaN9Mfh8yw9OXaedFC9XntHm0aGNLIBr9Ytm68u6fhz9p8UVh9XrvH0itXBA2/7rv6NQWaNbVsTdiPNt2DNnEw2nQP2mRIA8BBZqhYqWPqHTIpP/fnqxgo1NCBwdeFv1z56+d2RvKV/lhd/jwTiBFM0soxTTQkY5ul657781VKX+fTkjOf4P301ZBsBLVkwGSlr/Ud0qYVrs7YohVjmsoIJlm6LuxBm+5CmziANt2FNhnSAHBY0mfzdd2qyyWVDBSCYxoyUKgFM1QsjWmsPZECSdK1Kwcp6YsFDu8KsVQ4oIfe7zvR0mcDd0bypacb69Lrv+CBZg0kG0ENvOFLhZ5q+mubVggafr174iQVnemNl28nOtp0H9qERJtulOhtMqQB4CgzHNbqj9tJkk5+7l4lfTTX4R15X/IHc9XnhXskSes+asvlyxOIEQgo//YcdQhae2LCk56/V5svDulPjXgbYk090GihtlwYUp8X77F03exgmnJuz5URCFi6LqxFm+5Fm4mNNt0rkdtkSAPAcc1+LNaTOS3U8alN1ToBMcoRjajTk5v1TE4zNf2xyOndIIYKB/TS9G5TLF3zmZxmajI3qlf7T7b8kqSJJGj4Nf2UJ9Tkp6im5TaxdO3pPaao6Kxelq4Ja9Gme9FmYqNN90rkNhnSAHBcIC+kcc8MVHjteqe3EjfCa9ZpzJRLFcjnVTQJw+dX/nBrnw3cHsnXI9MvVc7V+9Q72d3v3/aCE5KD2ntVnh6cfrm2W3jViuxgmnKH50iGYdmasBBtuh5tJijadL1EbZMhDQDHGbMWqMUjs5zeRtxp8fAsGbM5H02iKD77WMufDRy85Gql7JQW9XnJ0nUT2c99X1SdbaauWHqVpevO6D5FxWf3tnRNWIM2vYE2Ew9tekMitsmQBgCAOJA/Yq+lzwZuDOepaFoznX0TA1SrnXnzd9r/bHNtDOdZtmaHYLpy78i1bD1Yhza9gzYTC216R6K16d6z5QAAgCopPuc4vdZtjCTrHmw+t7e3kvdG9GDT+ZataaWIGdXXhQGN2TigzK+PzPpY/VPC8hvuez7q303n6Mxdx+nFnF76Q8MVlq37WvcpuvGsuxT8ZI5la6J2aPNItAk3oM0j0aZ7MKQBAMDj8u/MUeuAtVemeO7NMxW5xrrLXtZWyIxo9NY+mr8rS3mvNFfddcVK3p6v6MKlZd7+we6D9X9N0pTbNknpg7eoZ8ONerjZ9644iaPf8GnjNWFNffMs/eEm6x5stguma9/IfWrwiWVLopZo80i0CTdIuDZfba6MDWGF6/hUWK/sIcyf996swP6oclsHlHE5bTqJIQ0AAB4WPqO33ug2VlY+G/h6Xl01+z6kSUMnSkq1bN2aWFJcoGt/vk6Rdxuq2WvLlbxzrZK1VpIUreD7oguXKiipoSQ9LS1v1FB9Bt2hwIU79cIx05QdTLN/8xV45+QJuu3Fu/TWkHQNTLPu5dtvdp+i606/U/7P51q2JmqGNstGm7TptERpM/xBIwX3mQqlG2p+1Vqd3niZjk7ZpAtSC8v8vvcKUvRLYUt9ur2Ltr3eRrPymuuEjBMUPG8HbcYYQxoAADxsc/9kZVn8bODDK89WQZegsoMplq5bHRvDeTr1yxHqNDakBnMWS+ZyRWqxXmTnLjWeNFuabOjO3rdoxcigvjxlnOV/dlWVHUzRns5BPbjyHA3s8bpl62YF0rWpf4paf27Zkqgh2qwa2kSsxXWbX41Q1vSgCrsE1GTgRj2b/VKVf68XpBbqgtRVGt1glXR/yXpDl1+l7R9k6eZJo7RpSEhf9KfNWHDfG84AAECVBNq10agr37J0zVWhPJnTG+vC33/j2PvS79lyrC7+52h1HLpQ5k8/S6Zp3eKmKfOnn9Xx2oW6+F+jNXprL+vWrga/4dO5185SZHoTrQlZ94ygJN115UwF2ra2dE1UD23WAG0iBuK5zfPG3yf/+hQNf/QVzR81Xp8e/XatBipZgXR9evTbmj9qvIY/+op861J07oT7aDMGGNIAAOBRuT2baVjmZkvX/CD/KKVuD+tPjX+wdN2q2B7JV7sPbtKSK9uq8eTZUrQ2z89XIhpR40mztfiKdmr3wU3aHsm371jl+HPj75S2NaSPC7ItXffmzA3a16OZpWuiemizFmgTNorXNj97pq8aDdikJUMnaHB6jqXDIr/h0+D0HC0ZOkGNztysT54+Ue0+vJE2bcSQBgAAjyq8cY/la45960KtuyqidF9sX7K9PZKvMyaMVvZN8xRZsTpmx42sWK3sm+bp9ImjY/6AM92XonVDTD0y8xJL1/UbPuXdmGPpmqge2qw92oQd4q3N/tPulX93QJPuHafPu8609ZU8fsOnL455S+PvHS//ziT1f/Ze2rQJQxoAADzI37GdRnb61NI1i8yQkvcaql/f2pcRV+bAD4EtH/re3mfoyxONKOvB7x35YbBegzwl7TVUZIYsXXdk9qfyd2xn6ZqoGtq0EG3CQvHW5ilT71XSMTlaNmSi+qbE7gpMJ6f4tOSq8Qoenav+02I/qEmENhnSAADgQfu6N9Hg9O2Wrjm7MFnNvt+vN3tMsXTdimyP5OuM8aPV8kGb30JRmWhEWf+erTMmxPaHwdd7PKPm3+7XT0XWPsAekrFN+7o1sXRNVA1tWow2YZF4avOUKaMV7Jaj+Se84Mh5cIKGXwv6PK9g11ydMjW2g5pEaJMhDQAAHpR7ba6ChrUPUH7c306FDZKUEaMHfNsj+Tpz3Gi1fGi2tScgrSnTVMsHZ+uM8bH7YTDDZ6ioYVDfF3S0dN2g4VfO0FxL10TV0KYNaBMWiJc2T5kyWsHuex0b0BzgN3xa0Od5BY6J7aAmEdpkSAMAgMf40tLUrv5uy9d98r2ztfGiiOr7Uy1fuyz9n71XLR6a5Y4fAg8wTbV8aLb6PX9vTA7XyJ+mDRdGNfG/51i+dtv6e+RLS7N8XZSPNm1Em6iFeGqzuF2hFvV5ydEBzQF+w6ef+76o4jZFtGkh5/9mAQBAtZhHtdMLHWZavq5hHvgf+12/vr86PrUxJseqNtNUpyc36cb1/WJzPMOeP/bnO7wpM7ut9QujXLRpM9pEDcVLm3W2GXqj/6SYHK863jhlklK3GLRpEYY0AAB4TG7HdPksvgtfFcpTs9kR/fVE6x/EHm5jOE8rHzpa4XUbbD9WTYXXrteyh7tqY9j+k0H+5eS31XxWRKtC1h4rKL9yszMsXRMVo0370SZqIh7aXDz5GJ0y9Ef1TE62/XjV1TM5Wf2unaOFT3SjTQswpAEAwGN2/a5Aqb4kS9fcFw0qZUeR+tdZa+m6ZTn95dFKffMH249TW2lv/KDTXhlt+3H611mtlO1FyjcDlq6b6kvSzoH7LV0TFaPN2KBNVJfn25w+Wjv6h/R4ix9tP1ZNjW/5vXb2C+m0Gfa/7Sne22RIAwCAh/jrZapXlkvfilAF7xWkKPuJLe4610V5TFPZT2zVBwXue9ayqrpnbZK/bl2nt5EQaDOGaBPVEA9ttvgqotfOmOj0Vir12hkTlfV5hDZriSENAABe0rKZHm/9juXLTtpxmvZ0TlWGz7B87YPdNfM6hdess/UYVoqsWqvh71xv6zEyfYb2Zqdq8o7TLF97YtuZUlYzy9dFGWgzpmgTVRYHba6/2FTvZGtfCWSH3slJWneRQZu1xJAGAAAPiaYEbLnz/vj77tp5fESN/PZd1WBjOE/NZpveeKb+ANNUs9nSFhvfY9/In6advaP674/dbVk/mhy0ZV0cijZjjDZRRV5vs/5iQ+f1WmTbMax2Vq/Fqv+zQZu1wJAGAAAPWX5Duq0PCO00dPlVynh3gdPbqLa67y7UdSuudHobNdLEn6blN6Q7vY2EQJuxR5uoCq+3GUo39Ejzr5zeSpU91vJThVMN2qwFhjQAAHiImRp2egs1tuGnlooWFjq9jWqLFhRo9ZxWTm+jxszUiNNbSAi0GXu0iarweps5vYosP+mxndJ9KcrpWUybtcCQBgAAjzACAaWkFzu9jRopeTuFd38gaTY7autLt+2UlF4sI2DtFTBwKNp0Dm2iIl5vs/4v0uU95jq9lWq7pOd81V9s79sR7eR0mwxpAADwCH/rLL1x/BNOb6NGdkaCyvhhvdPbqLG6P2zQjqg3f5h6o88T8me1cHobcY02nUObqIjX28xcWaDbG37t9FaqbUSjL1RvRQFt1hBDGgAAPCTFiDq9hRqZU9hGZti7z9ab4bDmFrZ2ehs1kmJEJMPeq4+ANp1Cm6iMl9ssapCsFA/+E0k2pKIGybRZQwxpAACA7f7x6SWK7Njh9DZqLLJtu/76+UCntwFYjjYBd/rHp5dow3mGmge8d4LprEC6Npxt0GYNMaQBAMAjTJ8Hn047wENX9i1XPPweYAvadFg8/B5gC6+3aRoe/sdtiDZriCENAAAesXZIc7UIJNuzuCEZpocfzKJcWYFkrbmqpdPbiGu0iZqgTfvRJmrC6TYZ0gAA4BH7m4eVbARtWfueM95X1semZ6/E4GUbw3nK+sTUH09/15b1k42gCpt595wjXkCb8Yk2vY8241O8t8mQBgAA6OQ6K5WyvUiFvDQ55opMKWVHkfrWWe30VuBCtOkc2kRFaNM58d4mQxoAAAAAAAAXYEgDAADU1B9STsdUjd95ii3rdzh6s3xpabasHQu+tDRld95sy9pjd5yuvZ1S1dgXtmV9eBttVow24ZRYtFl3eUB50UJb1rdTTnS/Mlb6abOGGNIAAAA1D6Rrz9HSGwt72bL+w+1fk69uhi1rx4KvXqYe7vCaLWu/s6CH9nSVJy+zCvvRZsVoE06JRZtNf8jXjoj3BhE7IxE1/TGfNmuIIQ0AAJAkhVOj0n6/LWsHjajMDO8+W2/WTVNQUcvXjZhRGfv9iqRZvzbiB22WjzbhJLvbjNQJaHMk1Zb17bQpkq5InQBt1hBDGgAAIEl69LwX1f61iHZG8i1fu0swWat+38TydWNl1TWNdFSS9Q+Ud0X3q/3rIY05+3nL10b8oM3y0SacZHebG09P0tDZN1q+tt2u++YGbTgziTZriCENAACQJDXz5ygaNLQsVMfytf2GT8WNI5LPnmccbeXzq7iRPS83XxGqo0iSTy0De21ZH/GBNstBm3CY7W02iii6M1kR0zuvGomYURm7khRqSJs1xZAGAABIkvqm+LXt+CTdNGeoLeu/cPZk+Tu3t2VtO/m7dNDLAybbsvYNP16nrX2S1Ds5yZb1ER9os2y0CafFos3WH0X0dWHAlvXt8EVhUK0+idBmLTCkAQAAvypsHlHRtlRbnrU7OcWntZc3tnxdu60Z1Eh9U6x/lUHEjCq0rY4Km3vvpJCIPdo8Em3CDexuc/uxQd0652rL17bLbT9erW3HBWmzFhjSAADgEXU2B1Rkhmw9xsMDXlaHV4u13yy2Zf0+FyySLyXFlrXt4EtNVb/zF9iy9n6zWB1eL9ZjZ71ky/oHFJkh1dniwbeyeAhtxh5toiripc3Md9NVELVnfSsVRItV/7002qwlhjQAAHhE2+lbtDlcZOsxzqizVbuOStF1ay60Zf1HW36oXVfYc7lSO+y8ooceavGxLWtfu/oi7exaR6embLdl/QM2hovU9uVNth4j0dFm7NEmqiJe2gylSteuOd+W9a10zeoLVJxh0GYtMaQBAMAjjKhp+zHq+1PV47qfteHJTgqZEVvWP3vUN/If1cnyta3mPzpb54/8SvX91l+dImRGtPnJDjr22oW2rI/Yos3Yok1UVby0ef6t32j1i530xX73/vj+6X6/1r7UURff8iVt1pJ7/5YBAIAjhjb+Vkn5UX20P82W9f/eZJGW3t7A3VeT8fm19Pb6+mvjxbYs/9+CDAULTA1t8o0t6yM+0aZoE64Uizb3do3q+g9vcuWVnkJmRDd/cJP2HhOlTQswpAEAwCtMUwWm/T88nVYnqo0DTN357nW2HWPe78Yo94rjbVu/tnKvPF7zBo6xbf1R716rjWebOiUGpwDJNwOSaf+zyQmNNmOGNlEtcdZmox/9un79abYdo6auX3emGs7x0aZFGNIAAOARkQ2bdNkPw2JyrLtO+UitPorYdqLCTF8dXXr/xzJ6dbVl/dowenfVoD99pExfHVvWz4sWqtVHEd3V/yNb1j/c5d8NU2Tj5pgcK1HRZmzQJqor3tocfM9H+vm5rpqRl2nLMWpi+r76+uX5ozTk7g9p0yIMaQAA8AgzHFZRflJMjjUsc7n2ZQV05aqLbTvG6AardPbzs2X0ds8Pg8Zxx+jc577V3Q1W23aMK1f+TrltAhqWudy2YxwslJ8kMxzflyt1Gm3ajzZRE/HY5jXDP9S/H7tK0/fVt+04VfXivoZ6aMyVuvaO/9KmhRjSAADgIUZBICbHSfUl6cSb52rHE22VE91v23HubrBa5z73rYzju9l2jCo7oZsuePZrjay/1rZD5ET3a9cTbXTKzT8q1Wf/Dw4RMyqjwMXnF4kjtGkj2kQtxGOb197xXz005ko9l9vItuNU5rncRvrPmMG6/o73adNiDGkAAPCQ7Cl52hnJr/U6W8J5ej2v7iEf7xWkHHJCwsdazNLWUyM6dsaoWh+vIiPrr9UF076STnDwh8ETuuniaV9oRP11th6m9yujtPWMiB5u9v2vn4uYUb1XkHLE38d2C/6ed0X3K3tKXq3XQeWsarMqaNN6ZbVpJ9qMnXht8/o73tdjjw/WP3d2VpEZsvV4ByuIFuvvO7tozNhBunHEu7Rpg9iMFQEAgCV8hWHV9LoOHxUE9fTWU7Tkrc7K2BhV5nuHXoHBl56mPw1ur8Impu783bu6KH2Jnh3wlO6/9xa9fmFdXZaeW/vfQDlG1F8nTf1Kb9w9QMmfLZQZsuc9/YczgkkqOqO7Ln/sQw2vt8HWY83Iy1SzWaYefPgJbYns18x9XTX+zfOVssNQ1iurFM0vOOT2/7ngKu3L8qnr75bq5mZf6sw6Nbu0q68oJOsvCovD1abN6goaftq00MFtBo3YPYNOm7ERz2367nhHL//5fD11QX+9dvpE9U6295Umc4qKdflnt6vl+37d+Ld3adMmhlnBWYsH+AZxunEkrI+jrxpO76E8tIlEluht+utlqu57fk1v91mVv2dPpEC93xqlLpP2KLpibZV+yDKSk1VwXg+1GL1Sc9e3ktakatbvH1Ejvz2XFz1gZyRffaffq84TNyu8xt5n5wLt2mjZ8Ob68YpHVd+fauuxdkbydfJz90od89Wj5SZtfbiDUj9YILOoqNLvNYJJ8nVqq6W31de8342p1okZL191lgouKFYk174fFA6gzeq3WVvZXw6lzVo6uM1l/Z+z9VgHo80StFl7OyP56jvjHjVYZOi8UV/pgUYLLR9ohMyI/rqjpz56rJ929TT10+W0aYXy2uTtTgAAeEhkb47mbcyq8u0f3NVJF4y+W53u+kmRX5ZX+Vlws6hIdd76QfuuqCP/0jQ1WmDqptWX1nTbVdbIn6ZlV03QiTOXqej84yWf9c+cGYGAis4/XifPXKplQyba/kBTkm5afakaLjLlW5yu/CtTVGfmD1Ua0EiSGSpW5Jfl6nTXTzp39Cg9vLtDlY+7cGPLmDzQRPXbtMKSU6aq7irRZi3ctPpSZayRfuk3zfZjHYw2Yych2rxyoi6++3N98vd+Ov7BEbp9U1/Nr+J9TEXmFxXp9k19dfy/R+jzf5ykgfd8puWDadNuvN0JAACPafhmqgpOLq7wBHoF0WId8+YIdZm4WxlLvqvxscIbN6n1XzfJ37Wzdkxop+3/yVcTm58V9Bs+PdBoqYY/MVeX/HK1ok81Ueb3mxTesLFW6wbatFLO8S0UGLZNbx41tvRBpv3PV22P5GvHhHbK/GWvMqYvVY2vFxGNqO7L3+nz+cdq0vCz9PPAcZX+G2j8pj2XQ0XZqtKmlfyGT72GLdT8J7pr+19ps7q2R/K1aVp79b5tvvxG7J67ps3YS5g2Hy1pc8FDPXSH2UPbL9+v/m1X6w/NP1R2sGp7WB7K14NbztHXazqoyespMg2p3s2b9eZRL9FmjDCkAYAyBJo1lSSFt22XKnhbqCTJMBRo1lRmNKrItu0x2B0SXd2VeYpW8A77gmixus24U9l/mKuIReePiCxepvRfDJ3RfrS+GP6w7S/flqT6/lR91e1N6XHpyZwWGvPSQNVbEVX9L9ZUq809p7bVnmyfRg15S8My3yn9ov3PAkolDzTPGD9aLV+drWhl+62iyJIVyh6VpG7hO/XLoHFKNoJl3i6kiDJW7BPvj42dytq0w1OtvlW3i9rolKn36pvr7X9rhRQ/bZ4yZbSCF+/VE1mzY3LMA2gz9hKuzbG/tbnkrWN0Y1FXGVFTu44OqNO5q8r83hUfdFDDX8IyfYYiyYb82T5d+7e3NCxzc+ktaDNWOCcNUI5Ef/9uovM3bKBl92fr0tO+13uruyrtvYwyb1dwYa7Ob/eL3vy8j7L/vkyRPXtivNPEQ5uSLy1Nye+n661OH5b59Qd3ddKXZ7WzZWjoS0lR5qepMX1v/+Em722pNUWN9c6qYyps88L2i9UueYdurbcpxjv8zeWrzlL+gDxFCwstXzvQrKlO+2SlRjco+wH3xSvOVei8XEULCsr8utVos/I27VIQLdYpf7lLHW9YRptVNHj1mVo9LVvf/vXxcgeddqHN39BmbNBm1bilTV5JAwBliOzarc7/WK7POnXSohOfk/+ksl9qGTGjOu6nqxjQIKai+flavad1mV/bEs7Tx3f2l3/bXHuOXVio3KHNdctLJ8b8Ga4DSh48btKDTedLJzmyhSq5cX0/FVyfoWjhTlvWD2/dpg/uPE1Dn11Y5kvp1+xuoBYFW205NspWUZt2SvUlafz943XL2BG65f+3d+/RUdZ3Hsc/c0sgZBKokAQEQXBD6oWLKFgRlSKtVSm6Koq1q5DipcgKHOCcttquq93t1hZBQbESLnVRhAWFthYpausFEIiGgFgQCJcoyEVIMhMymXnm2T+AACYhAZL5PTPzfp3DOfqYzHwP+GHy+zyX34+OkM0GjNrdX5sXdteLP6//SrTmRDZjj2ySzcZwSjZ5cDAA1MM6+LWyRxzUc4e71vs1Uw9dpPYj91HQIOYy52YobJ+6QWTYtnTtKxPl/WBjs763tbVEu37SuUkeSpioCkPV2pN/vqytJc36Pr73N6j/qxPq/H+hzdz0Zn1v1K2ubMbCVS08+p8xBdr8xKVk8zQKQ9X6/D8v1tNjXtJVLWK3pe9xZNMcsulsZPMEShoAOA3rwEEVzLmpzg/1sG1p9pwbZR382sBkSHb+Dfu0IJB1yrEZh7sqd/ruRu/gdC6iGz/Xv00bp9JIoNnfK96URgIa+exYWZ9tbfb3ssPVyp1eqhnfKJPnVbSXv5hnZJlQVzZjZXDLIwo+XKbhc8lmXUojAd07Z6yqRh/SoJZmFstk0xyy6Vxk81SUNADQgE6zN2tRoG2t4wsCWeo0+58GJgKOXs0y5fNBpxybtvG6c95lpdGilto/85FumjqJHzhPUhoJ6OZnJiln6kdSNDZnbCM7d2v6p9eecuzZLQMV2b4jJu+PU9WVzVjxuNxa3Xu+0voc0OBZZPNkpZGABhdMkr/vfn3Yc0FMd4w5Gdk0h2w6E9msjZIGABpgfX1YvyoaUuv4Ex/fIutQmYGJgKNazmxd889h29L5BbHZWrTG8aJmCj9wSscKmsmxLWiOa1+QWnPFn2VHlV6QGdP3x6lOzmaseVxurbl8vtKvOKDBBWRTOrYInDlJmf32aVWv14wtAsmmeWTTWchm3ShpAKAhUUsphbXvUU0tbBXzhRhwMn/RXs04fL4kaY91RCmHDFwiHLXUfspHuvmZ5P6B88QVNKuM/L2Q+nVIe6wjkqQZZZ3lL9oT8xlwwsnZNOH4Wfv0Kw9o8EyyOXjmJPn7mT1LL5FNJyCbzkE260dJAwBAnIrs2KWp84dKkvI/Hy57XfM+MLheUUs5U1Zp2KQJGrW7v5kZDMrfdY2GTZygnCmrJDsmu8nWYq/bqAe23iVJmv7qEEV27jYyB446OZum1CwG+x7QrU9OTNps3vrkRPn77Td6lv44smke2XQGsnl6lDQAAMSxDh+EVBoJKGx5jBUEkiTbln/+an15d1vl77rG3BwxNmLXAO0dfp78r602/vsfjnpUGgmowwdV5uZAjePZNOn4YvCy/I1a+789ky6bhfN6qGf+Bq3pvdD4IpBsOgfZNItsNoySBgAa4nLpSHa01uEj2bbkchkYCDjB+06h/nXDCNNj1IiU7NTeu7+l7rMf1j4raHqcZrPPCqr7rIe1767WipTsND1OjaHrR8rz7semx4Cck02Py63ZF7yvgvFTVDivR9Jk85N5l6lg/BQVXPCB6ZEkkU0nIZtmkM3Go6QBgAa4UlL0s5veqHV80i1L5EqJ8YNagTqkT83UwWCa6TFqRHbsUpfHVmvQsxM1p9zMdqfNqaAsR4Oenaguj61y1OXR+wOtlDnVb3oMnCR9aqZKws545kSf1BTNGf+Mwh1Duq4gcbN53cyJCl8Q0pzxz6hPqjM+o0vCAbLpMGQztsjmmaGkAYAGlN/aW0PSt9U6fmv656oY2tvARMCpfMvXybfcObsSSJJsWx2eXqmFP/iOcuc+rENWpemJztkBK6jusx/W4h/0VYenV5oepxbvW63lW1FoegycxLd8nYZtGGl6jBq9UlO1ffAseXse1szHbkuobObOeVizHx8qb6/D2n7DLPVKTTU9Vo3b1+eTTYchm7FBNs+O1/QAAOBkLq9XOaO3KcvTqtZ/y/K0UrvRJapa7JUdiRiYDjghe1WZ3J06KrK71PQop4iU7FTXx7/Qbe89qujYA3rzkleV7m5heqwzEohW6caN98g35Tx1Wb5GEQfu6ubt3EnZq8pU+8ZMmJY+LVPbXgyom6/2LoGmbOj3itb0Cuvu9x7UkHHj5B61L66zqZntFPlhSFOHz3DMGfrjtoUDaj3NeWfqQTabE9k8N1xJAwD1cXu08+d99YcL36j3S2Z2XaxdP+vLs2lgXLRok+MKmuPsSESpf12rtFu+0JUvjVdBWY7CtvOKjm8K25b+UNZBV/5hvNKHlCpl2Voj22s3RmTnbkWLNpkeA3VIWf6xhhU754z9cX1Tfdp8w0sa9PgHKvtre13+x3Fxl80+c8epYlmOBj/+vjYPeslxi0BJGlY8Ur6/Oe9MPchmcyCbTYMraQCgLm6Pdv2yn1bm/05t6riK5ri2nlZ674GnNcA1URc89ZFjF3CAE9jhal3wxEotnttXT4/oqKyr9mjJxfPUxuOc5+lI0iGrUkM+vVcHPspRt1m7dcHOlTK4bxPiXdRSxvRMbXkxqFxf/Z8nJvhcHj3R7lP9fGKRLv3HKM365VD9tpdb2VfsdXQ296/LVttiW/ZtlVpz/0ylunySPKbHq2VLOKiM6Zlmd35D/chmkyGbTctln2awwe47nTk1EAN/iy507KURZLN5uf1+lUy4TKtG/q7RH4KHrEpdPXOCukzeoGhFRTNPmNzIZuJwt2ihI9+9TDvvsPXf/Rfp9vQD8rnM/DAXti0tCGTpsQ9vU+eFLrV8d4OiVc7aktPpyGb9XF6v9r/eVYV9Fpgco0FFoZDuWPmQ0gpbyl8a1Zc3RhyVzQ7LvKro5Fbl5Ue0uP8L6pHi7FtAeq+9W9m3bzV+SzTZrB/ZPHtk89zVl02upAEASXJ75M1up70/vFD9R63T/JzfK9Pd+LMUbTxpWj3q9/rFLddr1czvKGdpiSJf7efKGuA0olVVSn1zrXLflF7ueLX+Y1Rnte23V9O6v6psT1jtvc37nIA9kYC+snx6ZPPwo1fNvLRTuaXrjs7WrO+MZGNHIvI/n6ltM5z1/Itv6pWaqq0DZytwXZV+c+BKvfbWNXphwp361VUetevzlZFs7l+Xrey1lrxXe3TDL97TxPMKjz2fw9mLwC3hoFq/4De+CMTpkc0zQzZjgytpgHpw1iG5lN17lW6Z9Hf1Tdum76WFz+m1llf6tKaym/7ym+uV8crqJpoQx5HNxOZOS5M7M0Nl/Ttr3xVu5X2nROM7LleaO6S+qb5zeu01obAqo6n63e7va8vqLspaG1Xmyp2KlpUrWhn/u2iYRjZPz+VL0faX8/TpgNnGznyfjS3hoG7+cLRafJym9iuDOpSXprJcNWs2MzdLbTZXas/VrVR1eaX+0n+6425HOZ2wbenif+Sr232bZIerTY9DNhtANutHNptXfdmkpAHqwQdacnGnpcnVsoWU3VY7bm8r+9if/veHrtEA/5bTfu/7Fbl6a0lfSZIrKnVZtF/ad1D2kSoWfs2AbCYXshk/yGbDvDnZuvPvn+j+jH2mRzljgWiV9lsRPb3vBv114yVqsyZFbYuPqDrDp31X+M4+m7aUtS6slPKw9vdM0+ErQ/rBpZ9qYtYKtfN4425XG0kqKMvRout7yPrKGX/OZLNhZPMoshlblDTAGeIDDdLRBaI8DZxVsSwWfDFENiGRTScim42z61dXq/iB5+LqjH1dAtEqVdqWNlX79VDhj2QfWwmetzhNrfaGTvu9wfapOnjb0Wy6XLZm9Jmni1MqlObyxOXC72QhO6zeMx5VpydXmh6lBtlsHLJJNmONZ9IAwFlggQc4E9lEvOoyeYOuvWqYVvVcZHqUc5LubqF0SVkto/rnNS/XHK/sX61oA091csutNPc3t+SNn1smTmdA0T3qPHk9z7WKQ2STbDqF2/QAAAAAQLKIVlSo5e9ba2nQWVvoNpU0d8rRReJpftVeBCaGpcE0+SdnKBoMmh4FZ4Fskk2noKQBAAAAYsi3olATFt6nsM0OgIkibFua+Np98r5daHoUnAOymXjiMZuUNAAAAECMdXtqvXKXPyDLjoeL73E6lh1V7rIH1fW/1pseBU2AbCaOeM0mJQ0AAAAQY9HKSn37119rUbCN6VFwjhYF2+jiXx/gWVkJgmwmjnjNJiUNAAAAYIC1tUQvPnSH3gimmx4FZ2lRIEMvPnSHItt3mB4FTYhsxr94ziYlDQAAAGCI951C/faxexWyw6ZHwRkK2WFNfuweed+Jn2ddoPHIZvyK92xS0gAAAAAGZS4pUt6fRrMYjCMhO6y8JaOVsbTI9ChoRmQz/iRCNilpAAAAAIOiVVXKG1usvKWjVRmtNj0OGlAZrda333hE3cetV7SqyvQ4aEZkM74kSjYpaQAAAADDolVV6j52vS5Z9lPTo6ABl7w5Wrnji2SHQqZHQQyQzfiRKNmkpAEAAAAcwA6FlPdcUNMPdzI9Cuox/XAn5U2riPtFIM4M2XS+RMomJQ0AAADgENH1n2npyIEsBh3ouUOdtfT+6xUt/qfpUWAA2XSuRMsmJQ0AAADgJKuLtXTkQM04fL7pSXDM9MOd9OcR10prNpgeBSaRTcdJxGxS0gAAAABOs7pYS4Zfqwv/MoqdZQyqjFbrwj+P0p/v7p9Qi0CcA7LpCImcTUoaAAAAwIGi6z9T90eO7izDYjD2QnZYly4Zo+5jihPmNgo0DbJpVqJnk5IGAAAAcCg7FFLeuGLl/YnFYCyF7LDyliTGTjFoHmTTjGTIJiUNAAAA4GDRqirljS3WwPFjtCiQYXqchLcokKHvjhujvPHFCbsIRNMgm7GVLNmkpAEAAAAcLlpVJf9rq/X8Q3dqQSBTlh01PVLCseyoFgQy9fxDdyp9wWpFq6pMj4Q4QDabX7Jlk5IGAAAAiBPedwo156bv6qLloxS2LdPjJIywbemiZQ9o7o0D5X2n0PQ4iENks3kkYzYpaQAAAIA4Ym0tUd7oz3TpnEe0NJhmepy4tzSYpktnP6K8MZsU2b7D9DiIY2SzaSVrNr2mBwAAAABwZqKVleryi1Wa8u5wPTWuXB/2mi+fy2N6rLgSssMaUHSP/JMz1OXtVeImFTQFsnnukj2bXEkDAAAAxCnfikKdN+xL9ZwxRnPKs7jNohHCtqWCshz1nvGozhv2pbxvJ8ctFIgtsnnmyOZRlDQAAABAHIsGg+r05EotvL63Lnl/hLaEg6ZHcqwt4aAu/ke+Fl3fQ52eXKlokN8rNB+y2Xhk8wRudwIAAAASQGTvV+r640N6cNBYlf20XPN7zlKur5XpsRxhSziou4ry1foFv7q9vV5WuNr0SEgiZLN+ZLM2ShoAAAAgQdjhaqUsW6usFV49eMNYlY8u04Ies9TNl256NCO2hQMaVjxSGdMzlb3iE9mRiGzTQyEpkc1Tkc36UdIAAAAACcaORJSybK3avuXST743VuWPlOv/eszShUmyICwJB3T7+ny1nuZX278VSrbNAhCOQDbJZkMoaQAAAIBEZdtKeWud2r4l5d/wqCrGVuj1HrPU0ZuYC8LSSEBD149U5lS/2q1IzoeOIk6QTdSDkgYAAABIAr4VhfrWCun+gf+uLwa00KN3L9GozN3yuOJ7LxHLjmpGWWdNf3WIOnxQpbbvfmx6JOCMkE2cjJIGAAAASCKedz/WBe9Kf/pjH73S82YF8ss0NvdtDfd/JZ/LY3q8RgnbluZVtNezWwYqvSBT/qI96rRzpemxgHNCNiFR0gAAAABJKbJjl1ru2KWWS6T5Fw3QS5dlqey+cnVpc0gvd3tdPnmU5k4xPaYkqTJarbAs/XjbbSr5+ltqMzdd/uJ9ard9syQpYng+oCmRzeRGSQMAAAAkOWtridK2lijtdSncqpXuyv2JynP9OnDrEfXo+IWe77JEkpTlaf5tgy07qoPRI5Kkn+4YquLS89Xu9Zbyf14h1+YSdajcK4nFH5ID2Uw+lDQAAAAAakSDQemTT+X/RPK/JlVmZOj+jiMUTfVpy8h02WmWUtKrtbjfi2rhsmq+r6M3VakuX6PeI2SHVRoJ1fx70PbqjtUPKBxMkavSo9xZAblDYal0ry4sXy9Jso/9ApIV2UwOlDQAAAAA6mWVl0ubyiVJ/zLm6DGX16tJHe+SXK6aryu553xV5Vh1vUQtLfd41OXVL04csG11Ld0kO3L0HLwtqXGvBCQvspmYKGkAAAAAnBE7ElFkx65TjnX69c4zeg1uiQCaHtmMf/G9pxcAAAAAAECCoKQBAAAAAABwAEoaAAAAAAAAB6CkAQAAAAAAcABKGgAAAAAAAAegpAEAAAAAAHAAShoAAAAAAAAHoKQBAAAAAABwAEoaAAAAAAAAB6CkAQAAAAAAcABKGgAAAAAAAAegpAEAAAAAAHAAShoAAAAAAAAHoKQBAAAAAABwAEoaAAAAAAAAB6CkAQAAAAAAcABKGgAAAAAAAAegpAEAAAAAAHAAShoAAAAAAAAHoKQBAAAAAABwAEoaAAAAAAAAB6CkAQAAAAAAcABKGgAAAAAAAAdw2bZtegYAAAAAAICkx5U0AAAAAAAADkBJAwAAAAAA4ACUNAAAAAAAAA5ASQMAAAAAAOAAlDQAAAAAAAAOQEkDAAAAAADgAP8PFhpmDQBg9N8AAAAASUVORK5CYII=\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "diameters = [31,41,61,71,101]\n", - "nd = len(diameters)\n", - "plt.figure(figsize=(20,12))\n", - "\n", - "for idx in range(nd):\n", - "\n", - " plt.subplot(3,nd,idx+1)\n", - " ax = plt.gca()\n", - " ax.set_axis_off()\n", - " image_violation_solid = imageruler.length_violation_solid(image,diameter=diameters[idx])\n", - " plt.imshow(image_violation_solid)\n", - " plt.title(\"probe diameter = \"+str(diameters[idx]))\n", - "\n", - " plt.subplot(3,nd,nd+idx+1)\n", - " ax = plt.gca()\n", - " ax.set_axis_off()\n", - " image_violation_void = imageruler.length_violation_void(image,diameter=diameters[idx])\n", - " plt.imshow(image_violation_void)\n", - "\n", - " plt.subplot(3,nd,2*nd+idx+1)\n", - " ax = plt.gca()\n", - " ax.set_axis_off()\n", - " image_violation = imageruler.length_violation(image,diameter=diameters[idx])\n", - " plt.imshow(image_violation);" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Declared minimum length scale of the solid region: 0.8\n", - "Estimated minimum length scale of the solid region: 0.8090039062499998\n" - ] - } - ], - "source": [ - "resolution = 50\n", - "width, height = 6, 4 # size of the binary image\n", - "phys_size = (width, height)\n", - "\n", - "stripe_width = 0.8\n", - "image = stripe(resolution, phys_size, stripe_width)\n", - "\n", - "plt.figure()\n", - "plt.imshow(image,extent=[-phys_size[1]/2,phys_size[1]/2,-phys_size[0]/2,phys_size[0]/2])\n", - "plt.show()\n", - "\n", - "solid_mls = imageruler.minimum_length_solid(image, phys_size)\n", - "\n", - "print(\"Declared minimum length scale of the solid region: \", stripe_width)\n", - "print(\"Estimated minimum length scale of the solid region: \", solid_mls)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Declared minimum length scale of the solid region: 0.8\n", - "Estimated minimum length scale of the solid region: 0.811298828125\n" - ] - } - ], - "source": [ - "image = stripe(resolution, phys_size, stripe_width, center = (0, -2)) | stripe(\n", - " resolution, phys_size, stripe_width, center = (0, 2))\n", - "\n", - "plt.figure()\n", - "plt.imshow(image,extent=[-phys_size[1]/2,phys_size[1]/2,-phys_size[0]/2,phys_size[0]/2])\n", - "plt.show()\n", - "\n", - "# Assume this image is periodic along the horizontal direction, which corresponds to the axis 1.\n", - "solid_mls = imageruler.minimum_length(image, phys_size, periodic_axes=1)\n", - "\n", - "print(\"Declared minimum length scale of the solid region: \", stripe_width)\n", - "print(\"Estimated minimum length scale of the solid region: \", solid_mls)" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Declared minimum length scale of the solid region: 1\n", - "Estimated minimum length scale of the solid region: 0.9877929687499998\n" - ] - } - ], - "source": [ - "stripe_width,intercept,angle = 1,1/np.sqrt(2),0.25*np.pi\n", - "image = stripe(resolution, phys_size, stripe_width, center=(intercept,0), angle=135)\n", - "\n", - "plt.figure()\n", - "plt.imshow(image,extent=[-phys_size[1]/2,phys_size[1]/2,-phys_size[0]/2,phys_size[0]/2])\n", - "plt.show()\n", - "\n", - "solid_mls = imageruler.minimum_length_solid(image, phys_size)\n", - "\n", - "print(\"Declared minimum length scale of the solid region: \", stripe_width)\n", - "print(\"Estimated minimum length scale of the solid region: \", solid_mls)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Padding schemes can affect estimated minimum length scales. The default padding schemes are padding solid/void materials when estimating minimum length scales of solid/void regions and padding solid/void materials for morphological opening/closing in the dual approach that involves both openning and closing. In the preceding example, if we use void padding or edge-mode padding, the boundary stuctures will influence the estimated minimum length scale, and consequently, the results will be away from the width of the strip. " - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Estimated minimum length scale of the solid region: 0.08607421875 (void padding), 0.7079492187499998 (edge-mode padding)\n" - ] - } - ], - "source": [ - "solid_mls_void = imageruler.minimum_length_solid(image, phys_size, pad_mode=imageruler.PaddingMode.VOID)\n", - "solid_mls_edge = imageruler.minimum_length_solid(image, phys_size, pad_mode=imageruler.PaddingMode.EDGE)\n", - "print(\"Estimated minimum length scale of the solid region: \", solid_mls_void, \"(void padding), \", solid_mls_edge, \"(edge-mode padding)\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Some tests based on 1d images are as follows." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Estimated minimum length scales: 0.39999999999999997 (solid), 0.3 (void)\n", - "Estimated minimum length scales with some end regions disregarded: 0.9999999999999999 (solid), 2.0999999999999996 (void)\n" - ] - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "phys_size = 10.1\n", - "image = np.sin(np.linspace(0,100,101)/5) > 0.5\n", - "plt.plot(np.linspace(-phys_size/2,phys_size/2,len(image)),image);\n", - "\n", - "solid_mls, void_mls = imageruler.minimum_length_solid_void(image, phys_size)\n", - "print(\"Estimated minimum length scales: \", solid_mls, \"(solid), \", void_mls, \"(void)\")\n", - "\n", - "# disregard the short void and solid regions at both ends\n", - "solid_mls, void_mls = imageruler.minimum_length_solid_void(image, phys_size, margin_size=(void_mls,solid_mls))\n", - "print(\"Estimated minimum length scales with some end regions disregarded: \", solid_mls, \"(solid), \", void_mls, \"(void)\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This package can also be used via the command line, which allows you to invoke the function \"minimum_length_solid_void()\" being invoked. The syntax is \"imageruler file\", where \"file\" is a string of the path of the text file that contains the array of the input image. All other arguments of the function take default options." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python [conda env:root] *", - "language": "python", - "name": "conda-root-py" - }, - "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.13" - }, - "latex_envs": { - "LaTeX_envs_menu_present": true, - "autoclose": false, - "autocomplete": true, - "bibliofile": "biblio.bib", - "cite_by": "apalike", - "current_citInitial": 1, - "eqLabelWithNumbers": true, - "eqNumInitial": 1, - "hotkeys": { - "equation": "Ctrl-E", - "itemize": "Ctrl-I" - }, - "labels_anchors": false, - "latex_user_defs": false, - "report_style_numbering": false, - "user_envs_cfg": false - }, - "toc": { - "base_numbering": 1, - "nav_menu": {}, - "number_sections": true, - "sideBar": true, - "skip_h1_title": false, - "title_cell": "Table of Contents", - "title_sidebar": "Contents", - "toc_cell": false, - "toc_position": {}, - "toc_section_display": true, - "toc_window_display": false - }, - "varInspector": { - "cols": { - "lenName": 16, - "lenType": 16, - "lenVar": 40 - }, - "kernels_config": { - "python": { - "delete_cmd_postfix": "", - "delete_cmd_prefix": "del ", - "library": "var_list.py", - "varRefreshCmd": "print(var_dic_list())" - }, - "r": { - "delete_cmd_postfix": ") ", - "delete_cmd_prefix": "rm(", - "library": "var_list.r", - "varRefreshCmd": "cat(var_dic_list()) " - } - }, - "types_to_exclude": [ - "module", - "function", - "builtin_function_or_method", - "instance", - "_Feature" - ], - "window_display": false - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..ced56ea --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,81 @@ +[project] + +name = "imageruler" +version = "v0.2.0" +description = "Measure minimum sollid/void lengthscales in binary images." +keywords = ["topology", "optimization", "length scale"] +readme = "README.md" +requires-python = ">=3.7" +license = {file = "LICENSE"} + +authors = [ + {name = "Wenchao Ma", email = "mawc@mit.edu"}, + {name = "Ian A. D. Williamson"}, + {name = "Martin Schubert", email = "mfschubert@gmail.com"}, + {name = "Ardavan Oskooi"}, + {name = "Steven G. Johnson", email = "stevenj@mit.edu"}, +] +maintainers = [ + {name = "Wenchao Ma", email = "mawc@mit.edu"}, + {name = "Ian A. D. Williamson"}, + {name = "Martin Schubert", email = "mfschubert@gmail.com"}, + {name = "Ardavan Oskooi"}, + {name = "Steven G. Johnson", email = "stevenj@mit.edu"}, +] + +dependencies = [ + "numpy", + "opencv-python", +] + +[project.optional-dependencies] +tests = [ + "parameterized", + "pytest", + "pytest-cov", + "pytest-xdist", + "scipy", +] +docs = [ + "matplotlib", + "jupyter-book", + "scipy", + "scikit-image", + "sphinx-autodoc-typehints", + "sphinx-click", +] +dev = [ + "bump-my-version", + "darglint", + "imageruler[tests]", + "mypy", + "pre-commit", +] + +[build-system] +requires = ["setuptools>=45", "wheel"] +build-backend = "setuptools.build_meta" + +[tool.setuptools.package-data] +"imageruler" = ["py.typed"] + +[tool.pytest.ini_options] +addopts = ["--import-mode=importlib"] # Allow tests with same name in different dirs. +pythonpath = ["src"] + +[tool.black] +line-length = 88 +target-version = ['py310'] + +[tool.mypy] +python_version = "3.10" +strict = true + +[tool.isort] +multi_line_output = 3 +line_length = 88 +include_trailing_comma = true + +[tool.pydocstyle] +inherit = false +convention = "google" diff --git a/reference_designs/README.md b/reference_designs/README.md new file mode 100644 index 0000000..48d34c5 --- /dev/null +++ b/reference_designs/README.md @@ -0,0 +1,3 @@ +# Reference designs +This directory contains several designs which can be used to demonstrate the calculation of length scales. +- Rasmus70nm.csv: from the [RGB metalens](https://github.com/NanoComp/photonics-opt-testbed/tree/main/RGB_metalens) problem of the photonics-opt-testbed repo. diff --git a/reference_designs/Rasmus70nm.csv b/reference_designs/Rasmus70nm.csv new file mode 100644 index 0000000..7a9de5a --- /dev/null +++ b/reference_designs/Rasmus70nm.csv @@ -0,0 +1,1022 @@ +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 diff --git a/setup.py b/setup.py deleted file mode 100644 index 960cb12..0000000 --- a/setup.py +++ /dev/null @@ -1,39 +0,0 @@ -"""Setup imageruler.""" -import codecs -import os.path -import setuptools - - -def read(rel_path): - here = os.path.abspath(os.path.dirname(__file__)) - with codecs.open(os.path.join(here, rel_path), 'r') as fp: - return fp.read() - - -def get_version(rel_path): - for line in read(rel_path).splitlines(): - if line.startswith('__version__'): - delim = '"' if '"' in line else "'" - return line.split(delim)[1] - else: - raise RuntimeError('Unable to find version string.') - - -setuptools.setup( - name='imageruler', - version=get_version('imageruler/__init__.py'), - license='MIT', - author='Wenchao Ma, Ian A. D. Williamson, Martin F. Schubert, Ardavan Oskooi, and Steven G. Johnson', - author_email='mawc@mit.edu, stevenj@mit.edu', - install_requires=[ - 'numpy', - 'opencv-python', - 'pytest', - 'pytest-xdist', - ], - url='https://github.com/NanoComp/imageruler', - packages=setuptools.find_packages(), - python_requires='>=3', - entry_points={"console_scripts": [ - "imageruler = imageruler.cli:main", - ]}) \ No newline at end of file diff --git a/src/imageruler/__init__.py b/src/imageruler/__init__.py new file mode 100644 index 0000000..21b10b1 --- /dev/null +++ b/src/imageruler/__init__.py @@ -0,0 +1,16 @@ +"""Imageruler for measuring minimum lengthscales in binary images.""" + +__version__ = "v0.2.0" +__all__ = [ + "IgnoreScheme", + "minimum_length_scale", + "minimum_length_scale_solid", + "length_scale_violations_solid", +] + +from imageruler.imageruler import ( + IgnoreScheme, + length_scale_violations_solid, + minimum_length_scale, + minimum_length_scale_solid, +) diff --git a/src/imageruler/imageruler.py b/src/imageruler/imageruler.py new file mode 100644 index 0000000..aac6348 --- /dev/null +++ b/src/imageruler/imageruler.py @@ -0,0 +1,627 @@ +"""Imageruler for measuring minimum lengthscales in binary images.""" + +import dataclasses +import enum +import functools +from typing import Any, Callable, Tuple + +import cv2 +import numpy as onp + +NDArray = onp.ndarray[Any, Any] + + +DEFAULT_FEASIBILITY_GAP_ALLOWANCE = 10 + +PLUS_3_KERNEL = onp.array([[0, 1, 0], [1, 1, 1], [0, 1, 0]], dtype=bool) +PLUS_5_KERNEL = onp.array( + [ + [0, 1, 1, 1, 0], + [1, 1, 1, 1, 1], + [1, 1, 1, 1, 1], + [1, 1, 1, 1, 1], + [0, 1, 1, 1, 0], + ], + dtype=bool, +) +SQUARE_3_KERNEL = onp.ones((3, 3), dtype=bool) + + +@enum.unique +class IgnoreScheme(enum.Enum): + """Enumerates schemes for ignoring length scale violations.""" + + NONE = "none" + EDGES = "edges" + LARGE_FEATURE_EDGES = "large_feature_edges" + + +@enum.unique +class PaddingMode(enum.Enum): + """Enumerates padding modes for arrays.""" + + EDGE = "edge" + SOLID = "solid" + VOID = "void" + + +# ------------------------------------------------------------------------------ +# Exported functions related to the length scale metric. +# ------------------------------------------------------------------------------ + + +def minimum_length_scale( + x: NDArray, + periodic: Tuple[bool, bool] = (False, False), + ignore_scheme: IgnoreScheme = IgnoreScheme.LARGE_FEATURE_EDGES, + feasibility_gap_allowance: int = DEFAULT_FEASIBILITY_GAP_ALLOWANCE, +) -> Tuple[int, int]: + """Identifies the minimum length scale of solid and void features in `x`. + + The minimum length scale for solid (void) features defines the largest brush + which can be used to recreate the solid (void) features in `x`, by convolving + an array of "touches" with the brush kernel. In general if an array can be + created with a given brush, then its solid and void features are unchanged by + binary opening operations with that brush. + + In some cases, an array that can be created with a brush of size `n` cannot + be created with the smaller brush if size `n - 1`. Further, small pixel-scale + violations at edges of features may be unimportant. Some allowance for these + is provided via optional arguments to this function. + + Args: + x: Bool-typed rank-2 array containing the features. + periodic: Specifies which of the two axes are to be regarded as periodic. + ignore_scheme: Specifies what pixels are ignored when detecting violations. + feasibility_gap_allowance: In checking whether `x` is feasible with a brush + of size `n`, we also check for feasibility with larger brushes, since + e.g. some features realizable with a brush `n + k` may not be realizable + with the brush of size `n`. The `feasibility_gap_allowance is the + maximum value of `k` checked. For arrays with very large features, + particularly when ignoring no violations, larger values may be needed. + + Returns: + The detected minimum length scales `(length_scale_solid, length_scale_void)`. + """ + # Note that when the minimum of solid and void length scale is desired, + # a faster implementation involving comparison between binary opening and + # closing of designs is possible. This could improve performance by a factor + # of two or greater. + if x.ndim != 2: + raise ValueError(f"`x` must be 2-dimensional, but got shape {x.shape}.") + if not isinstance(x, onp.ndarray): + raise ValueError(f"`x` must be a numpy array but got {type(x)}.") + if x.dtype != bool: + raise ValueError(f"`x` must be of type `bool` but got {x.dtype}.") + if not isinstance(periodic[0], bool) or not isinstance(periodic[1], bool): + raise ValueError( + f"`periodic` must be a length-2 tuple of `bool` but got {periodic}." + ) + + # Use a dedicated codepath for arrays with a singleton axis. + if 1 in x.shape: + idx, squeeze_idx = (1, 0) if x.shape[0] == 1 else (0, 1) + return minimum_length_scale_1d( + onp.squeeze(x, axis=squeeze_idx), periodic=periodic[idx] + ) + + return ( + minimum_length_scale_solid( + x, periodic, ignore_scheme, feasibility_gap_allowance + ), + minimum_length_scale_solid( + ~x, periodic, ignore_scheme, feasibility_gap_allowance + ), + ) + + +def minimum_length_scale_solid( + x: NDArray, + periodic: Tuple[bool, bool] = (False, False), + ignore_scheme: IgnoreScheme = IgnoreScheme.LARGE_FEATURE_EDGES, + feasibility_gap_allowance: int = DEFAULT_FEASIBILITY_GAP_ALLOWANCE, +) -> int: + """Identifies the minimum length scale of solid features in `x`. + + Args: + x: Bool-typed rank-2 array containing the features. + periodic: Specifies which of the two axes are to be regarded as periodic. + ignore_scheme: Specifies what pixels are ignored when detecting violations. + feasibility_gap_allowance: In checking whether `x` is feasible with a brush + of size `n`, we also check for feasibility with larger brushes, since + e.g. some features realizable with a brush `n + k` may not be realizable + with the brush of size `n`. The `feasibility_gap_allowance is the + maximum value of `k` checked. For arrays with very large features, + particularly when ignoring no violations, larger values may be needed. + + Returns: + The detected minimum length scale of solid features. + """ + assert x.dtype == bool + + def test_fn(length_scale: int) -> bool: + return ~onp.any( # type: ignore + length_scale_violations_solid( + x=x, + length_scale=length_scale, + periodic=periodic, + ignore_scheme=ignore_scheme, + feasibility_gap_allowance=feasibility_gap_allowance, + ) + ) + + return maximum_true_arg( + nearly_monotonic_fn=test_fn, + min_arg=1, + max_arg=max(x.shape), + non_monotonic_allowance=feasibility_gap_allowance, + ) + + +def length_scale_violations_solid( + x: NDArray, + length_scale: int, + periodic: Tuple[bool, bool] = (False, False), + ignore_scheme: IgnoreScheme = IgnoreScheme.LARGE_FEATURE_EDGES, + feasibility_gap_allowance: int = DEFAULT_FEASIBILITY_GAP_ALLOWANCE, +) -> NDArray: + """Computes the length scale violations, allowing for the feasibility gap. + + Args: + x: Bool-typed rank-2 array containing the features. + length_scale: The length scale for which violations are sought. + periodic: Specifies which of the two axes are to be regarded as periodic. + ignore_scheme: Specifies what pixels are ignored when detecting violations. + feasibility_gap_allowance: In checking whether `x` is feasible with a brush + of size `n`, we also check for feasibility with larger brushes, since + e.g. some features realizable with a brush `n + k` may not be realizable + with the brush of size `n`. The `feasibility_gap_allowance is the + maximum value of `k` checked. For arrays with very large features, + particularly when ignoring no violations, larger values may be needed. + + Returns: + The array containing violations. + """ + violations = [] + for scale in range(length_scale, length_scale + feasibility_gap_allowance): + violations.append( + length_scale_violations_solid_strict(x, scale, periodic, ignore_scheme) + ) + length_scale_violations: NDArray = onp.all(violations, axis=0) + return length_scale_violations + + +# ------------------------------------------------------------------------------ +# Non-exported functions related to the length scale metric. +# ------------------------------------------------------------------------------ + + +def length_scale_violations_solid_strict( + x: NDArray, + length_scale: int, + periodic: Tuple[bool, bool], + ignore_scheme: IgnoreScheme, +) -> NDArray: + """Identifies length scale violations of solid features in `x`. + + Args: + x: Bool-typed rank-2 array containing the features. + length_scale: The length scale for which violations are sought. + periodic: Specifies which of the two axes are to be regarded as periodic. + ignore_scheme: Specifies what pixels are ignored when detecting violations. + + Returns: + The array containing violations. + """ + violations = _length_scale_violations_solid_strict( + wrapped_x=_HashableArray(x), + length_scale=length_scale, + periodic=periodic, + ignore_scheme=ignore_scheme, + ) + assert violations.shape == x.shape + return violations + + +@dataclasses.dataclass +class _HashableArray: + """Hashable wrapper for numpy arrays.""" + + array: NDArray + + def __hash__(self) -> int: + return hash((self.array.dtype, self.array.shape, self.array.tobytes())) + + def __eq__(self, other: Any) -> bool: + if not isinstance(other, _HashableArray): + return False + return onp.all(self.array == other.array) and ( # type: ignore + self.array.dtype == other.array.dtype + ) + + +@functools.lru_cache(maxsize=128) +def _length_scale_violations_solid_strict( + wrapped_x: _HashableArray, + length_scale: int, + periodic: Tuple[bool, bool], + ignore_scheme: IgnoreScheme, +) -> NDArray: + """Identifies length scale violations of solid features in `x`. + + This function is strict, in the sense that no violations are ignored. + + Args: + wrapped_x: The wrapped bool-typed rank-2 array containing the features. + length_scale: The length scale for which violations are sought. + periodic: Specifies which of the two axes are to be regarded as periodic. + ignore_scheme: Specifies what pixels are ignored when detecting violations. + + Returns: + The array containing violations. + """ + x = wrapped_x.array + kernel = kernel_for_length_scale(length_scale) + violations_solid = x & ~binary_opening(x, kernel, periodic, PaddingMode.SOLID) + + ignored = ignored_pixels(x, periodic, ignore_scheme) + violations_solid = violations_solid & ~ignored + return violations_solid + + +def kernel_for_length_scale(length_scale: int) -> NDArray: + """Returns an approximately circular kernel for the given `length_scale`. + + The kernel has shape `(length_scale, length_scale)`, and is `True` for pixels + whose centers lie within the circle of radius `length_scale / 2` centered on + the kernel. This yields a pixelated circle, which for length scales less than + `3` will actually be square. + + Args: + length_scale: The length scale for which the kernel is sought. + + Returns: + The approximately circular kernel. + """ + assert length_scale > 0 + centers = onp.arange(-length_scale / 2 + 0.5, length_scale / 2) + squared_distance = centers[:, onp.newaxis] ** 2 + centers[onp.newaxis, :] ** 2 + kernel = squared_distance < (length_scale / 2) ** 2 + # Ensure that kernels larger than `2` can be realized with a width-3 brush. + if length_scale > 2: + kernel = binary_opening( + kernel, + kernel=PLUS_3_KERNEL, + periodic=(False, False), + padding_mode=PaddingMode.VOID, + ) + return kernel + + +def ignored_pixels( + x: NDArray, + periodic: Tuple[bool, bool], + ignore_scheme: IgnoreScheme, +) -> NDArray: + """Returns an array indicating locations at which violations are to be ignored. + + Args: + x: The array for which ignored locations are to be identified. + periodic: Specifies which of the two axes are to be regarded as periodic. + ignore_scheme: Specifies the manner in which ignored locations are identified. + + Returns: + The array indicating locations to be ignored. + """ + assert x.dtype == bool + if ignore_scheme == IgnoreScheme.NONE: + return onp.zeros_like(x) + elif ignore_scheme == IgnoreScheme.EDGES: + return x & ~binary_erosion(x, PLUS_3_KERNEL, periodic, PaddingMode.SOLID) + elif ignore_scheme == IgnoreScheme.LARGE_FEATURE_EDGES: + return x & ~erode_large_features(x, periodic) + else: + raise ValueError(f"Unknown `ignore_scheme`, got {ignore_scheme}.") + + +# ------------------------------------------------------------------------------ +# Array-manipulating functions backed by `cv2`. +# ------------------------------------------------------------------------------ + + +def binary_opening( + x: NDArray, kernel: NDArray, periodic: Tuple[bool, bool], padding_mode: PaddingMode +) -> NDArray: + """Performs binary opening with the given `kernel` and padding mode.""" + assert x.ndim == 2 + assert x.dtype == bool + assert kernel.ndim == 2 + assert kernel.dtype == bool + # The `cv2` convention for binary opening yields a shifted output with + # even-shape kernels, requiring padding and unpadding to differ. + pad_width, unpad_width = _pad_width_for_kernel_shape(kernel.shape) + opened = cv2.morphologyEx( + src=pad_2d(x, pad_width, periodic, padding_mode).view(onp.uint8), + kernel=kernel.view(onp.uint8), + op=cv2.MORPH_OPEN, + ) + return unpad(opened.view(bool), unpad_width) + + +def binary_erosion( + x: NDArray, kernel: NDArray, periodic: Tuple[bool, bool], padding_mode: PaddingMode +) -> NDArray: + """Performs binary erosion with structuring element `kernel`.""" + assert x.dtype == bool + assert kernel.dtype == bool + pad_width = ((kernel.shape[0],) * 2, (kernel.shape[1],) * 2) + eroded = cv2.erode( + src=pad_2d(x, pad_width, periodic, padding_mode).view(onp.uint8), + kernel=kernel.view(onp.uint8), + ) + return unpad(eroded.view(bool), pad_width) + + +def binary_dilation( + x: NDArray, kernel: NDArray, periodic: Tuple[bool, bool], padding_mode: PaddingMode +) -> NDArray: + """Performs binary dilation with structuring element `kernel`.""" + assert x.dtype == bool + assert kernel.dtype == bool + # The `cv2` convention for binary dilation yields a shifted output with + # even-shape kernels, requiring padding and unpadding to differ. + pad_width, unpad_width = _pad_width_for_kernel_shape(kernel.shape) + dilated = cv2.dilate( + src=pad_2d(x, pad_width, periodic, padding_mode).view(onp.uint8), + kernel=kernel.view(onp.uint8), + ) + return unpad(dilated.view(bool), unpad_width) + + +_Padding = Tuple[Tuple[int, int], Tuple[int, int]] + + +def _pad_width_for_kernel_shape(shape: Tuple[int, ...]) -> Tuple[_Padding, _Padding]: + """Prepares `pad_width` and `unpad_width` for the given kernel shape.""" + assert len(shape) == 2 + pad_width = ((shape[0],) * 2, (shape[1],) * 2) + unpad_width = ( + ( + pad_width[0][0] + (shape[0] + 1) % 2, + pad_width[0][1] - (shape[0] + 1) % 2, + ), + ( + pad_width[1][0] + (shape[1] + 1) % 2, + pad_width[1][1] - (shape[1] + 1) % 2, + ), + ) + return pad_width, unpad_width + + +def erode_large_features(x: NDArray, periodic: Tuple[bool, bool]) -> NDArray: + """Erodes large features while leaving small features untouched. + + Note that this operation can change the topology of `x`, i.e. it + may create two disconnected solid features where originally there + was a single contiguous feature. + + Args: + x: Bool-typed rank-2 array to be eroded. + periodic: Specifies which of the two axes are to be regarded as periodic. + + Returns: + The array with eroded features. + """ + assert x.dtype == bool + + # Identify interior solid pixels, which should not be removed. Pixels for + # which the neighborhood sum equals `9` are interior pixels. + neighborhood_sum = _filter_2d(x, SQUARE_3_KERNEL, periodic, PaddingMode.EDGE) + interior_pixels = neighborhood_sum == 9 + + # Identify solid pixels that are adjacent to interior pixels. + adjacent_to_interior = ( + x + & ~interior_pixels + & binary_dilation( + x=interior_pixels, + kernel=PLUS_5_KERNEL, + periodic=periodic, + padding_mode=PaddingMode.EDGE, + ) + ) + + removed_by_erosion = x & ~binary_erosion( + x, PLUS_3_KERNEL, periodic, PaddingMode.EDGE + ) + should_remove = adjacent_to_interior & removed_by_erosion + return onp.asarray(x & ~should_remove) + + +def _filter_2d( + x: NDArray, kernel: NDArray, periodic: Tuple[bool, bool], padding_mode: PaddingMode +) -> NDArray: + """Convolves `x` with `kernel`.""" + assert x.dtype == bool + assert kernel.dtype == bool + pad_width, unpad_width = _pad_width_for_kernel_shape(kernel.shape) + filtered = cv2.filter2D( + src=pad_2d(x, pad_width, periodic, padding_mode).view(onp.uint8), + kernel=kernel.view(onp.uint8), + ddepth=cv2.CV_32F, + borderType=cv2.BORDER_REPLICATE, + ) + filtered = onp.around(onp.asarray(filtered)).astype(int) + return unpad(filtered, unpad_width) + + +def pad_2d( + x: NDArray, + pad_width: Tuple[Tuple[int, int], Tuple[int, int]], + periodic: Tuple[bool, bool], + padding_mode: PaddingMode, +) -> NDArray: + """Pads rank-2 boolean array `x` with the specified mode. + + Padding may take values from the edge pixels, or be entirely solid or + void, determined by the `mode` parameter. + + Args: + x: The array to be padded. + pad_width: The extent of the padding, `((i_lo, i_hi), (j_lo, j_hi))`. + periodic: Specifies which of the two axes are to be regarded as periodic. + padding_mode: Specifies the padding mode to be used. + + Returns: + The padded array. + """ + assert x.dtype == bool + ((top, bottom), (left, right)) = pad_width + + pad_value = 1 if padding_mode == PaddingMode.SOLID else 0 + + if periodic[0]: + border_type_i = cv2.BORDER_WRAP + elif padding_mode == PaddingMode.EDGE: + border_type_i = cv2.BORDER_REPLICATE + else: + border_type_i = cv2.BORDER_CONSTANT + x = cv2.copyMakeBorder( # type: ignore[call-overload] + src=x.view(onp.uint8), + top=top, + bottom=bottom, + left=0, + right=0, + borderType=border_type_i, + value=pad_value, + ) + + if periodic[1]: + border_type_j = cv2.BORDER_WRAP + elif padding_mode == PaddingMode.EDGE: + border_type_j = cv2.BORDER_REPLICATE + else: + border_type_j = cv2.BORDER_CONSTANT + x = cv2.copyMakeBorder( # type: ignore[call-overload] + src=x, + top=0, + bottom=0, + left=left, + right=right, + borderType=border_type_j, + value=pad_value, + ).view(bool) + return onp.asarray(x) + + +def unpad( + x: NDArray, + pad_width: Tuple[Tuple[int, int], ...], +) -> NDArray: + """Undoes a pad operation.""" + slices = tuple( + slice(pad_lo, dim - pad_hi) for (pad_lo, pad_hi), dim in zip(pad_width, x.shape) + ) + return x[slices] + + +# ------------------------------------------------------------------------------ +# Functions that find thresholds of nearly-monotonic functions. +# ------------------------------------------------------------------------------ + + +def maximum_true_arg( + nearly_monotonic_fn: Callable[[int], bool], + min_arg: int, + max_arg: int, + non_monotonic_allowance: int, +) -> int: + """Searches for the maximum integer for which `nearly_monotonic_fn` is `True`. + + This requires `nearly_monotonic_fn` to be approximately monotonically + decreasing, i.e. it should be `True` for small arguments and then `False` for + large arguments. Some allowance for "noisy" behavior at the transition is + controlled by `non_monotonic_allowance`. + + The input argument is checked in the range `[min_arg, max_arg]`, where both + values are positive. If `test_fn` is never `True`, `min_arg` is returned. + + Note that the algorithm here assumes that `nearly_monotonic_fn` is expensive + to evaluate with large arguments, and so a "small first" search strategy is + employed. For this reason, `min_arg` must be positive. + + Args: + nearly_monotonic_fn: The function for which the maximum `True` argument is + sought. + min_arg: The minimum argument. Must be positive. + max_arg: The maximum argument. Must be greater than `min_arg.` + non_monotonic_allowance: The number of candidate arguments where the + function evaluates to `False` to be considered before concluding that the + maximum `True` argument is smaller than the candidates. Must be positive. + + Returns: + The maximum `True` argument, or `min_arg`. + """ + assert min_arg > 0 + assert min_arg < max_arg + assert non_monotonic_allowance > 0 + + max_true_arg = min_arg - 1 + + while min_arg <= max_arg: + # We double `min_arg` rather than bisecting, as this requires fewer + # evaluations when the minimum `True` value is close to `min_arg`. + test_arg_start = min(min_arg * 2, max_arg) + test_arg_stop = min(test_arg_start + non_monotonic_allowance, max_arg + 1) + for test_arg in range(test_arg_start, test_arg_stop): + result = nearly_monotonic_fn(test_arg) + if result: + break + if result: + min_arg = test_arg + 1 + max_true_arg = max(max_true_arg, test_arg) + else: + max_arg = test_arg_start - 1 + return max_true_arg + + +# ------------------------------------------------------------------------------ +# Functions that handle the special case of 1D patterns. +# ------------------------------------------------------------------------------ + + +def minimum_length_scale_1d(x: NDArray, periodic: bool) -> Tuple[int, int]: + """Return the minimum solid and void length scale for a 1D array.""" + assert x.dtype == bool + x = x.astype(int) + + # Find interior locations within `x` where the pattern transistions from + # solid to void, or vice versa. + xpad = onp.pad(x, (1, 1), mode="edge") + delta = onp.roll(xpad, 1) - xpad + delta = delta[1:-1] + (idxs,) = onp.where(onp.abs(delta) > 0) + + # Determine the dimensions of each region. + idxs = onp.concatenate([[0], idxs, [x.size]]) + dims = idxs[1:] - idxs[:-1] + + if periodic: + # Wrap the starting region in the case of a periodic pattern. + if x[0] == x[-1]: + dims = onp.concatenate([[dims[0] + dims[-1]], dims[1:-1]]) + dims = onp.minimum(dims, x.size) + else: + # If not periodic, discount the first and last regions. + dims = dims[1:-1] + + # Find the minimum length scale. + min_dim_first_region = int(onp.amin(dims[::2]) if len(dims) > 0 else x.size) + min_dim_second_region = int(onp.amin(dims[1::2]) if len(dims) > 1 else x.size) + + starts_with_solid = bool(x[0]) + starts_with_void = not starts_with_solid + if starts_with_solid and periodic or (starts_with_void and not periodic): + return min_dim_first_region, min_dim_second_region + else: + return min_dim_second_region, min_dim_first_region diff --git a/src/imageruler/py.typed b/src/imageruler/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/src/imageruler/regular_shapes.py b/src/imageruler/regular_shapes.py new file mode 100644 index 0000000..bf57b43 --- /dev/null +++ b/src/imageruler/regular_shapes.py @@ -0,0 +1,175 @@ +"""Regular shapes.""" + +from typing import Any, Tuple + +import numpy as onp + +NDArray = onp.ndarray[Any, Any] + + +def rounded_square( + resolution: float, + phys_size: Tuple[float, float], + declared_mls: float, + center: Tuple[float, float] = (0, 0), + angle: float = 0, +) -> NDArray: + """Return a bool array where all True elements form a square with rounded corners. + + Args: + resolution: A float that represents the number of points per unit length. + phys_size: A tuple with two elements that describe the physical size of + the entire pattern. + declared_mls: A float that represents the declared minimum length scale, + which is equal to the diameter of round corners. + center: A tuple with two elements that describe the coordinates of the + center of the square. + angle: A float that represents the angle of rotation in degree. + + Returns: + An array with Boolean elements. + """ + + angle = onp.radians(angle) + + # number of pixels along each dimension + n = onp.round(onp.asarray(phys_size) * resolution).astype(int) + # size of the entire pattern formed by centers of pixels + grid_size = (n - 1) / resolution + + x_coord = onp.linspace(-grid_size[0] / 2, grid_size[0] / 2, n[0]) + y_coord = onp.linspace(-grid_size[1] / 2, grid_size[1] / 2, n[1]) + xv, yv = onp.meshgrid(x_coord, y_coord, sparse=True, indexing="ij") + + side, diameter = 2 * declared_mls, declared_mls + rect_vert = ( + abs(onp.sin(angle) * (xv - center[0]) - onp.cos(angle) * (yv - center[1])) + <= (side - diameter) / 2 + ) & ( + abs(onp.cos(angle) * (xv - center[0]) + onp.sin(angle) * (yv - center[1])) + <= side / 2 + ) + rect_hori = ( + abs(onp.sin(angle) * (xv - center[0]) - onp.cos(angle) * (yv - center[1])) + <= side / 2 + ) & ( + abs(onp.cos(angle) * (xv - center[0]) + onp.sin(angle) * (yv - center[1])) + <= (side - diameter) / 2 + ) + + disc_centers = ( + onp.array( + [ + [ + side - diameter, + diameter - side, + diameter - side, + side - diameter, + ], + [ + side - diameter, + side - diameter, + diameter - side, + diameter - side, + ], + ] + ) + / 2 + ) + disc_centers_x = ( + disc_centers[0, :] * onp.cos(angle) + - disc_centers[1, :] * onp.sin(angle) + + center[0] + ) + disc_centers_y = ( + disc_centers[0, :] * onp.sin(angle) + + disc_centers[1, :] * onp.cos(angle) + + center[1] + ) + disc_centers = onp.vstack((disc_centers_x, disc_centers_y)) + + disc0 = (xv - disc_centers[0, 0]) ** 2 + ( + yv - disc_centers[1, 0] + ) ** 2 <= diameter**2 / 4 + disc1 = (xv - disc_centers[0, 1]) ** 2 + ( + yv - disc_centers[1, 1] + ) ** 2 <= diameter**2 / 4 + disc2 = (xv - disc_centers[0, 2]) ** 2 + ( + yv - disc_centers[1, 2] + ) ** 2 <= diameter**2 / 4 + disc3 = (xv - disc_centers[0, 3]) ** 2 + ( + yv - disc_centers[1, 3] + ) ** 2 <= diameter**2 / 4 + + return onp.asarray(rect_vert | rect_hori | disc0 | disc1 | disc2 | disc3) + + +def disc( + resolution: float, + phys_size: Tuple[float, float], + diameter: float, + center: Tuple[float, float] = (0, 0), +) -> NDArray: + """Return a Boolean array where all True elements form a disc. + + Args: + resolution: A float that represents the number of points per unit length. + phys_size: A tuple with two elements that describe the physical size of + the entire pattern. + diameter: A float that represents the diameter of the disc. + center: A tuple with two elements that describe the coordinates of the + center of the square. + + Returns: + An array with Boolean elements. + """ + + # number of pixels along each dimension + n = onp.round(onp.asarray(phys_size) * resolution).astype(int) + # size of the entire pattern formed by centers of pixels + grid_size = (n - 1) / resolution + + x_coord = onp.linspace(-grid_size[0] / 2, grid_size[0] / 2, n[0]) + y_coord = onp.linspace(-grid_size[1] / 2, grid_size[1] / 2, n[1]) + xv, yv = onp.meshgrid(x_coord, y_coord, sparse=True, indexing="ij") + + return (xv - center[0]) ** 2 + (yv - center[1]) ** 2 <= diameter**2 / 4 + + +def stripe( + resolution: float, + phys_size: Tuple[float, float], + width: float, + center: Tuple[float, float] = (0, 0), + angle: float = 0, +) -> NDArray: + """Return a Boolean array where all True elements form a disc. + + Args: + resolution: A float that represents the number of points per unit length. + phys_size: A tuple with two elements that describe the physical size of + the entire pattern. + width: A float that represents the width of the stripe. + center: A tuple with two elements that describe the coordinates of the + center of the stripe. + angle: A float that represents the angle of rotation in degree. + + Returns: + An array with Boolean elements. + """ + + angle = onp.radians(angle) + + # number of pixels along each dimension + n = onp.round(onp.asarray(phys_size) * resolution).astype(int) + # size of the entire pattern formed by centers of pixels + grid_size = (n - 1) / resolution + + x_coord = onp.linspace(-grid_size[0] / 2, grid_size[0] / 2, n[0]) + y_coord = onp.linspace(-grid_size[1] / 2, grid_size[1] / 2, n[1]) + xv, yv = onp.meshgrid(x_coord, y_coord, sparse=True, indexing="ij") + + return onp.asarray( + abs(onp.sin(angle) * (xv - center[0]) - onp.cos(angle) * (yv - center[1])) + <= width / 2 + ) diff --git a/tests/test_imageruler.py b/tests/test_imageruler.py new file mode 100644 index 0000000..5980011 --- /dev/null +++ b/tests/test_imageruler.py @@ -0,0 +1,611 @@ +"""Tests for `imageruler`.""" + +import itertools +import unittest + +import numpy as onp +from parameterized import parameterized +from scipy import ndimage + +from imageruler import imageruler + +TEST_ARRAY_4_5 = onp.array( + [ # Solid features feasible with circle-4, void with circle-5. + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1], + [0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1], + [0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1], + ], + dtype=bool, +) +TEST_ARRAY_5_5 = onp.array( + [ # Solid features feasible with circle-5, void with circle-5. + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0], + [0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1], + [0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1], + [0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1], + ], + dtype=bool, +) +TEST_ARRAY_5_3 = onp.array( + [ # Solid features feasible with circle-5, void with circle-3. + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0], + [0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0], + [0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1], + [0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1], + [0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1], + [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1], + ], + dtype=bool, +) +TEST_ARRAY_5_WITH_DEFECT = onp.array( + [ # Mostly feasible with diameter-4 brush. + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0], + [0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1], # One pixel here is defective. + [0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1], + [0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1], + ], + dtype=bool, +) +TEST_ARRAYS = [TEST_ARRAY_4_5, TEST_ARRAY_5_5, TEST_ARRAY_5_3, TEST_ARRAY_5_WITH_DEFECT] + + +TEST_KERNEL_4 = onp.array( + [[0, 1, 1, 0], [1, 1, 1, 1], [1, 1, 1, 1], [0, 1, 1, 0]], dtype="bool" +) +TEST_KERNEL_5 = onp.array( + [ + [0, 1, 1, 1, 0], + [1, 1, 1, 1, 1], + [1, 1, 1, 1, 1], + [1, 1, 1, 1, 1], + [0, 1, 1, 1, 0], + ], + dtype="bool", +) +TEST_KERNEL_4_3_ASYMMETRIC = onp.array( + [[0, 1, 0], [1, 1, 1], [1, 1, 1], [0, 1, 0]], dtype="bool" +) +TEST_KERNELS = [TEST_KERNEL_4, TEST_KERNEL_5, TEST_KERNEL_4_3_ASYMMETRIC] + + +class LengthScaleTest(unittest.TestCase): + @parameterized.expand( + [ + (TEST_ARRAY_4_5, 4, 5), + (TEST_ARRAY_5_5, 5, 5), + (TEST_ARRAY_5_3, 5, 3), + ] + ) + def test_length_scale_matches_expected(self, x, expected_solid, expected_void): + length_scale_solid, length_scale_void = imageruler.minimum_length_scale( + x, ignore_scheme=imageruler.IgnoreScheme.NONE + ) + self.assertEqual(length_scale_solid, expected_solid) + self.assertEqual(length_scale_void, expected_void) + + @parameterized.expand( + list( + itertools.product( + [i for i in range(1, 20)], + [ + imageruler.IgnoreScheme.NONE, + imageruler.IgnoreScheme.LARGE_FEATURE_EDGES, + ], + ) + ) + ) + def test_circle_has_expected_length_scale(self, length_scale, ignore_scheme): + # With `NONE` and `LARGE_FEATURE_EDGES` ignore schemes, even small length + # scales will correctly be identified. + x = imageruler.kernel_for_length_scale(length_scale) + x = onp.pad(x, ((1, 1), (1, 1)), mode="constant") + with self.subTest("solid_circle"): + length_scale_solid, length_scale_void = imageruler.minimum_length_scale( + x, ignore_scheme=ignore_scheme + ) + self.assertEqual(length_scale_solid, length_scale) + self.assertEqual(length_scale_void, min(x.shape)) + with self.subTest("void_circle"): + length_scale_solid, length_scale_void = imageruler.minimum_length_scale( + ~x, ignore_scheme=ignore_scheme + ) + self.assertEqual(length_scale_void, length_scale) + self.assertEqual(length_scale_solid, min(x.shape)) + + @parameterized.expand([[i] for i in range(5, 20)]) + def test_circle_has_expected_length_scale_ignore_edges(self, length_scale): + # With the `EDGES` ignore scheme, we will be blind to small features. + # Check only for features larger than 5 pixels in size. + x = imageruler.kernel_for_length_scale(length_scale) + x = onp.pad(x, ((1, 1), (1, 1)), mode="constant") + with self.subTest("solid_circle"): + length_scale_solid, length_scale_void = imageruler.minimum_length_scale( + x, ignore_scheme=imageruler.IgnoreScheme.EDGES + ) + self.assertEqual(length_scale_solid, length_scale) + self.assertEqual(length_scale_void, min(x.shape)) + with self.subTest("void_circle"): + length_scale_solid, length_scale_void = imageruler.minimum_length_scale( + ~x, ignore_scheme=imageruler.IgnoreScheme.EDGES + ) + self.assertEqual(length_scale_void, length_scale) + self.assertEqual(length_scale_solid, min(x.shape)) + + @parameterized.expand( + list( + itertools.product( + list(range(1, 20)), + [ + imageruler.IgnoreScheme.NONE, + imageruler.IgnoreScheme.LARGE_FEATURE_EDGES, + ], + ) + ) + ) + def test_line_has_expected_length_scale(self, length_scale, ignore_scheme): + # Make an array that has a single void circular feature with diameter equal + # to the length scale. Pad to make sure the feature is isolated. + x = onp.zeros((40, 40), dtype=bool) + x[:, 10 : (10 + length_scale)] = True + length_scale_solid, length_scale_void = imageruler.minimum_length_scale( + x, ignore_scheme=ignore_scheme + ) + self.assertEqual(length_scale_solid, length_scale) + self.assertEqual(length_scale_void, min(x.shape)) + + @parameterized.expand( + [[imageruler.IgnoreScheme.EDGES], [imageruler.IgnoreScheme.LARGE_FEATURE_EDGES]] + ) + def test_brush_violations_with_interface_defects(self, ignore_scheme): + # Assert that there are violations in the defective array. + assert onp.any( + imageruler.length_scale_violations_solid_strict( + TEST_ARRAY_5_WITH_DEFECT, + length_scale=4, + periodic=(False, False), + ignore_scheme=imageruler.IgnoreScheme.NONE, + ) + ) + # Assert that there are no violations if we ignore interfaces. + assert not onp.any( + imageruler.length_scale_violations_solid_strict( + TEST_ARRAY_5_WITH_DEFECT, + length_scale=4, + periodic=(False, False), + ignore_scheme=ignore_scheme, + ) + ) + + @parameterized.expand([[s] for s in imageruler.IgnoreScheme]) + def test_solid_feature_shallow_incidence(self, ignore_scheme): + # Checks that the length scale for a design having a solid feature that + # is incident on the design edge with a very shallow angle has a length + # scale equal to the size of the design. + x = onp.ones((70, 70), dtype=bool) + x[-1, 10:] = 0 + x[-2, 20:] = 0 + length_scale_solid, length_scale_void = imageruler.minimum_length_scale( + x, ignore_scheme=ignore_scheme + ) + self.assertEqual(length_scale_solid, 70) + self.assertEqual(length_scale_void, 70) + + def test_feasibility_gap(self): + # Tests that if we have features feasible with size 6 kernel and size 7 + # kernel, but not both, that a minimum feature size of 6 is reported. + circle6 = onp.pad(imageruler.kernel_for_length_scale(6), ((2, 1), (2, 1))) + circle7 = onp.pad(imageruler.kernel_for_length_scale(7), ((1, 1), (1, 1))) + # Check that the `circle6` is feasible with `6` but infeasible with `7`. + self.assertFalse( + onp.any( + imageruler.length_scale_violations_solid_strict( + circle6, 6, (False, False), imageruler.IgnoreScheme.NONE + ) + ) + ) + self.assertTrue( + onp.any( + imageruler.length_scale_violations_solid_strict( + circle6, 7, (False, False), imageruler.IgnoreScheme.NONE + ) + ) + ) + # Check that the `circle7` is infeasible with `6` but feasible with `7`. + self.assertTrue( + onp.any( + imageruler.length_scale_violations_solid_strict( + circle7, 6, (False, False), imageruler.IgnoreScheme.NONE + ) + ) + ) + self.assertFalse( + onp.any( + imageruler.length_scale_violations_solid_strict( + circle7, 7, (False, False), imageruler.IgnoreScheme.NONE + ) + ) + ) + # Check that putting both features in the same design makes it infeasible + # for `6` and `7`. + merged = onp.concatenate([circle6, circle7]) + self.assertTrue( + onp.any( + imageruler.length_scale_violations_solid_strict( + merged, 6, (False, False), imageruler.IgnoreScheme.NONE + ) + ) + ) + self.assertTrue( + onp.any( + imageruler.length_scale_violations_solid_strict( + merged, 7, (False, False), imageruler.IgnoreScheme.NONE + ) + ) + ) + # Check that when allowing for the feasibility gap, the merged design is + # considered feasible with `6` but infeasible with `7`. + self.assertFalse( + onp.any( + imageruler.length_scale_violations_solid( + merged, + 6, + (False, False), + imageruler.IgnoreScheme.NONE, + feasibility_gap_allowance=2, + ) + ) + ) + self.assertTrue( + onp.any( + imageruler.length_scale_violations_solid( + merged, + 7, + (False, False), + imageruler.IgnoreScheme.NONE, + feasibility_gap_allowance=2, + ) + ) + ) + + +class PeriodicLengthScale(unittest.TestCase): + @parameterized.expand(range(1, 10)) + def test_circle_array_length_scale(self, pad_amount): + x = imageruler.kernel_for_length_scale(20) + x = onp.pad(x, ((pad_amount, 0), (pad_amount, 0))) + length_scale_not_periodic = imageruler.minimum_length_scale( + x, periodic=(False, False), ignore_scheme=imageruler.IgnoreScheme.NONE + ) + onp.testing.assert_array_equal(length_scale_not_periodic, (20, x.shape[0])) + + length_scale_periodic_both = imageruler.minimum_length_scale( + x, periodic=(True, True), ignore_scheme=imageruler.IgnoreScheme.NONE + ) + onp.testing.assert_array_equal(length_scale_periodic_both, (20, pad_amount)) + + @parameterized.expand(range(1, 10)) + def test_line_array_length_scale(self, pad_amount): + x = onp.ones((20, 20)) + x = onp.pad(x, ((pad_amount, 0), (0, 0))).astype(bool) + length_scale_not_periodic = imageruler.minimum_length_scale( + x, periodic=(False, False), ignore_scheme=imageruler.IgnoreScheme.NONE + ) + onp.testing.assert_array_equal( + length_scale_not_periodic, (x.shape[0], x.shape[0]) + ) + + length_scale_periodic_x = imageruler.minimum_length_scale( + x, periodic=(True, False), ignore_scheme=imageruler.IgnoreScheme.NONE + ) + onp.testing.assert_array_equal(length_scale_periodic_x, (20, pad_amount)) + + length_scale_periodic_y = imageruler.minimum_length_scale( + x, periodic=(False, True), ignore_scheme=imageruler.IgnoreScheme.NONE + ) + onp.testing.assert_array_equal( + length_scale_periodic_y, (x.shape[0], x.shape[0]) + ) + + length_scale_periodic_both = imageruler.minimum_length_scale( + x, periodic=(True, True), ignore_scheme=imageruler.IgnoreScheme.NONE + ) + onp.testing.assert_array_equal(length_scale_periodic_both, (20, pad_amount)) + + +class OneDimensionalLengthScaleTest(unittest.TestCase): + @parameterized.expand( + [ + [[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], (False, False), (10, 10)], + [[[0, 0, 1, 1, 0, 0, 0, 0, 0, 0]], (False, False), (2, 10)], + [[[0, 0, 1, 1, 0, 1, 1, 0, 0, 0]], (False, False), (2, 1)], + [[[0, 0, 1, 1, 0, 0, 0, 0, 0, 0]], (False, True), (2, 8)], + [[[0, 0, 1, 1, 0, 0, 0, 0, 0, 0]], (True, False), (2, 10)], + ] + ) + def test_length_scale_matches_expected(self, x, periodic, expected): + mls = imageruler.minimum_length_scale( + x=onp.asarray(x, dtype=bool), + periodic=periodic, + ) + onp.testing.assert_array_equal(mls, expected) + + +class KernelTest(unittest.TestCase): + @parameterized.expand([(4, TEST_KERNEL_4), (5, TEST_KERNEL_5)]) + def test_kernel_matches_expected(self, length_scale, expected): + onp.testing.assert_array_equal( + imageruler.kernel_for_length_scale(length_scale), expected + ) + + def test_length_scale_1(self): + onp.testing.assert_array_equal( + imageruler.kernel_for_length_scale(1), onp.ones((1, 1)) + ) + + def test_length_scale_2(self): + onp.testing.assert_array_equal( + imageruler.kernel_for_length_scale(2), onp.ones((2, 2)) + ) + + def test_length_scale_3(self): + onp.testing.assert_array_equal( + imageruler.kernel_for_length_scale(3), imageruler.PLUS_3_KERNEL + ) + + +# ------------------------------------------------------------------------------ +# Tests for array-manipulating functions. +# ------------------------------------------------------------------------------ + + +class MorphologyOperationsTest(unittest.TestCase): + @parameterized.expand( + list(itertools.product(TEST_ARRAYS, TEST_KERNELS, imageruler.PaddingMode)) + ) + def test_erosion_matches_scipy(self, x, kernel, padding_mode): + pad_width = ((kernel.shape[0],) * 2, (kernel.shape[1],) * 2) + if padding_mode == imageruler.PaddingMode.EDGE: + x_padded = onp.pad(x, pad_width, mode="edge") + elif padding_mode == imageruler.PaddingMode.SOLID: + x_padded = onp.pad(x, pad_width, mode="constant", constant_values=True) + elif padding_mode == imageruler.PaddingMode.VOID: + x_padded = onp.pad(x, pad_width, mode="constant", constant_values=False) + expected = ndimage.binary_erosion(x_padded, kernel) + expected = expected[ + pad_width[0][0] : expected.shape[0] - pad_width[0][1], + pad_width[1][0] : expected.shape[1] - pad_width[1][1], + ] + actual = imageruler.binary_erosion( + x, kernel, periodic=(False, False), padding_mode=padding_mode + ) + onp.testing.assert_array_equal(expected, actual) + + @parameterized.expand( + list(itertools.product(TEST_ARRAYS, TEST_KERNELS, imageruler.PaddingMode)) + ) + def test_dilation_matches_scipy(self, x, kernel, padding_mode): + pad_width = ((kernel.shape[0],) * 2, (kernel.shape[1],) * 2) + if padding_mode == imageruler.PaddingMode.EDGE: + x_padded = onp.pad(x, pad_width, mode="edge") + elif padding_mode == imageruler.PaddingMode.SOLID: + x_padded = onp.pad(x, pad_width, mode="constant", constant_values=True) + elif padding_mode == imageruler.PaddingMode.VOID: + x_padded = onp.pad(x, pad_width, mode="constant", constant_values=False) + expected = ndimage.binary_dilation(x_padded, kernel) + expected = expected[ + pad_width[0][0] : expected.shape[0] - pad_width[0][1], + pad_width[1][0] : expected.shape[1] - pad_width[1][1], + ] + actual = imageruler.binary_dilation( + x, kernel, periodic=(False, False), padding_mode=padding_mode + ) + onp.testing.assert_array_equal(expected, actual) + + @parameterized.expand( + list(itertools.product(TEST_ARRAYS, TEST_KERNELS, imageruler.PaddingMode)) + ) + def test_opening_matches_scipy(self, x, kernel, padding_mode): + pad_width = ((kernel.shape[0],) * 2, (kernel.shape[1],) * 2) + if padding_mode == imageruler.PaddingMode.EDGE: + x_padded = onp.pad(x, pad_width, mode="edge") + elif padding_mode == imageruler.PaddingMode.SOLID: + x_padded = onp.pad(x, pad_width, mode="constant", constant_values=True) + elif padding_mode == imageruler.PaddingMode.VOID: + x_padded = onp.pad(x, pad_width, mode="constant", constant_values=False) + expected = ndimage.binary_opening(x_padded, kernel) + expected = expected[ + pad_width[0][0] : expected.shape[0] - pad_width[0][1], + pad_width[1][0] : expected.shape[1] - pad_width[1][1], + ] + actual = imageruler.binary_opening( + x, kernel, periodic=(False, False), padding_mode=padding_mode + ) + onp.testing.assert_array_equal(expected, actual) + + def test_opening_removes_small_features(self): + # Test that a feature that is feasible with a size-4 brush is eliminated + # by opening with the size-5 brush. + actual = imageruler.binary_opening( + TEST_ARRAY_4_5, + TEST_KERNEL_5, + periodic=(False, False), + padding_mode=imageruler.PaddingMode.EDGE, + ) + expected = onp.array( + [ + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1], + ], + dtype=bool, + ) + onp.testing.assert_array_equal(expected, actual) + + @parameterized.expand( + [ + [[(0, 0, 1, 0, 0)], [(0, 0, 1, 0, 0)]], + [[(0, 0, 1, 1, 0)], [(0, 0, 1, 1, 0)]], + [[(0, 0, 1, 1, 1, 0, 0, 0)], [(0, 0, 0, 1, 0, 0, 0, 0)]], + [[(0, 0, 0, 0, 0, 0, 0, 1)], [(0, 0, 0, 0, 0, 0, 0, 1)]], + ] + ) + def test_erode_large_features_1d(self, x, expected): + result = imageruler.erode_large_features( + onp.asarray(x, dtype=bool), periodic=(False, False) + ) + onp.testing.assert_array_equal(result, onp.asarray(expected, dtype=bool)) + + @parameterized.expand( + [ + ( + [ + [0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 1, 0, 0, 0, 0], + [1, 1, 1, 1, 1, 1, 1, 1], + [1, 1, 1, 1, 1, 1, 1, 1], + ], + [ + [0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 1, 0, 0, 0, 0], + [1, 1, 1, 1, 1, 1, 1, 1], + ], + ), + ( + [ + [1, 1, 1, 1, 1, 1, 1, 1], + [1, 1, 1, 1, 0, 0, 0, 0], + [1, 1, 1, 1, 0, 0, 0, 0], + [1, 1, 1, 1, 0, 0, 0, 0], + [1, 1, 0, 0, 1, 0, 0, 0], + [1, 1, 0, 0, 0, 0, 0, 0], + ], + [ + [1, 1, 1, 1, 0, 1, 1, 1], + [1, 1, 1, 0, 0, 0, 0, 0], + [1, 1, 1, 0, 0, 0, 0, 0], + [1, 1, 0, 0, 0, 0, 0, 0], + [1, 0, 0, 0, 1, 0, 0, 0], + [1, 0, 0, 0, 0, 0, 0, 0], + ], + ), + ] + ) + def test_erode_large_features_2d(self, x, expected): + result = imageruler.erode_large_features( + onp.asarray(x, dtype=bool), periodic=(False, False) + ) + onp.testing.assert_array_equal(result, onp.asarray(expected, dtype=bool)) + + +class PaddingOperationsTest(unittest.TestCase): + @parameterized.expand( + [ + [((0, 0), (0, 0))], + [((1, 5), (2, 4))], + [((4, 2), (5, 1))], + ], + ) + def test_pad_2d_matches_numpy(self, pad_width): + onp.random.seed(0) + x = onp.random.rand(20, 30) > 0.5 # Random binary array. + with self.subTest("edge"): + expected = onp.pad(x, pad_width, mode="edge") + actual = imageruler.pad_2d( + x, pad_width, (False, False), imageruler.PaddingMode.EDGE + ) + onp.testing.assert_array_equal(expected, actual) + with self.subTest("solid"): + expected = onp.pad(x, pad_width, constant_values=True) + actual = imageruler.pad_2d( + x, pad_width, (False, False), imageruler.PaddingMode.SOLID + ) + onp.testing.assert_array_equal(expected, actual) + with self.subTest("void"): + expected = onp.pad(x, pad_width, constant_values=False) + actual = imageruler.pad_2d( + x, pad_width, (False, False), imageruler.PaddingMode.VOID + ) + onp.testing.assert_array_equal(expected, actual) + + @parameterized.expand( + [ + [((0, 0), (0, 0))], + [((1, 5), (2, 4))], + [((4, 2), (5, 1))], + ], + ) + def test_unpad(self, pad_width): + x = onp.arange(200).reshape(10, 20) + expected = x[ + pad_width[0][0] : x.shape[0] - pad_width[0][1], + pad_width[1][0] : x.shape[1] - pad_width[1][1], + ] + actual = imageruler.unpad(x, pad_width) + onp.testing.assert_equal(expected.shape, actual.shape) + onp.testing.assert_array_equal(expected, actual) + + +# ------------------------------------------------------------------------------ +# Tests for `maximum_true_arg`. +# ------------------------------------------------------------------------------ + + +class MaximumTrueArgTest(unittest.TestCase): + @parameterized.expand( + [ + # 1 2 3 4 5 6 7 8 9 10 11 + ([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0], 1, 11, 1, 10), + ([1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0], 1, 11, 1, 3), + ([1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0], 1, 11, 11, 10), + ([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1], 1, 8, 1, 0), # No `True` values. + ([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 1, 8, 1, 8), # All `True` values. + ] + ) + def test_finds_maximum_true_arg( + self, + sequence, + min_arg, + max_arg, + allowance, + expected, + ): + fn = lambda i: bool(sequence[i - 1]) + actual = imageruler.maximum_true_arg(fn, min_arg, max_arg, allowance) + assert expected == actual + + +class OneDimensionalPatternTest(unittest.TestCase): + @parameterized.expand( + [ + [[0, 0, 1, 1, 1, 0, 0, 0, 0, 0], False, (3, 10)], + [[0, 0, 1, 1, 1, 0, 0, 0, 0, 0], True, (3, 7)], + [[0, 0, 1, 1, 1, 0, 0, 0, 1, 1], True, (2, 2)], + [[0, 1, 1, 1, 0, 0, 0, 1, 1, 0], True, (2, 2)], + [[0, 1, 0, 1, 0, 0, 0, 1, 1, 0], True, (1, 1)], + [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], False, (10, 10)], + [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], True, (10, 10)], + [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1], False, (10, 10)], + [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1], True, (10, 10)], + ] + ) + def test_minimum_feature_size_matches_expected( + self, pattern, periodic, expected_minimum_length + ): + minimum_length = imageruler.minimum_length_scale_1d( + onp.asarray(pattern, dtype=bool), periodic + ) + onp.testing.assert_array_equal(minimum_length, expected_minimum_length) diff --git a/tests/test_regular_shapes.py b/tests/test_regular_shapes.py new file mode 100755 index 0000000..09fe4ba --- /dev/null +++ b/tests/test_regular_shapes.py @@ -0,0 +1,168 @@ +"""Tests for imageruler based on regular shapes.""" + +import unittest + +import numpy as np +from parameterized import parameterized + +import imageruler +from imageruler import imageruler +from imageruler import regular_shapes as shapes + +# properties of design weights array +RESOLUTION = 1 +PHYS_SIZE = (200, 200) + + +class TestDuality(unittest.TestCase): + def duality_dilation_erosion(self, weights: np.ndarray, diam: int) -> bool: + """Checks the duality of the dilation and erosion operators for solid + + and void features of the design weights. + + Args: + weights: the design weights as a 2d array. + diam: the diameter of the circular-ball kernel. + + Returns: + A Boolean indicating whether duality is satisfied or not. + """ + kernel = imageruler.kernel_for_length_scale(diam) + erosion_of_negation = imageruler.binary_erosion( + ~weights, + kernel, + periodic=(False, False), + padding_mode=imageruler.PaddingMode.SOLID, + ) + negation_of_dilation = ~imageruler.binary_dilation( + weights, + kernel, + periodic=(False, False), + padding_mode=imageruler.PaddingMode.VOID, + ) + dilation_of_negation = imageruler.binary_dilation( + ~weights, + kernel, + periodic=(False, False), + padding_mode=imageruler.PaddingMode.SOLID, + ) + negation_of_erosion = ~imageruler.binary_erosion( + weights, + kernel, + periodic=(False, False), + padding_mode=imageruler.PaddingMode.VOID, + ) + return (erosion_of_negation == negation_of_dilation).all() and ( + negation_of_erosion == dilation_of_negation + ).all() + + @parameterized.expand((3, 45, 51, 81, 101)) + def test_rounded_square(self, length_scale): + print("------ Testing duality property using rounded squares ------") + + declared_mls: float = 50.0 + for angle in [0, 10.5, 44.3, 73.9]: + print(f"Rotation angle of the rounded square: {angle}°") + pattern = shapes.rounded_square( + RESOLUTION, PHYS_SIZE, declared_mls, angle=angle + ) + print(f"Kernel diameter: {length_scale:.2f}") + self.assertTrue(self.duality_dilation_erosion(pattern, length_scale)) + + @parameterized.expand((3, 45, 51, 81, 101)) + def test_disc(self, length_scale): + print("------ Testing duality property using a shapes.disc ------") + + diam = 50.0 + pattern = shapes.disc(RESOLUTION, PHYS_SIZE, diam) + print(f"Kernel diameter: {length_scale:.2f}") + self.assertTrue(self.duality_dilation_erosion(pattern, length_scale)) + + @parameterized.expand((3, 45, 51, 81, 101)) + def test_ring(self, length_scale): + print("------ Testing duality property using concentric circles ------") + + outer_diameter, inner_diameter = 120, 50 + declared_solid_mls, declared_void_mls = ( + outer_diameter - inner_diameter + ) / 2, inner_diameter + print( + f"Declared minimum length scale: {declared_solid_mls:.2f} " + f"(solid), {declared_void_mls:.2f} (void)" + ) + + solid_disc = shapes.disc(RESOLUTION, PHYS_SIZE, diameter=outer_diameter) + void_disc = shapes.disc(RESOLUTION, PHYS_SIZE, diameter=inner_diameter) + pattern = solid_disc ^ void_disc # ring + + print(f"Kernel diameter: {length_scale:.2f}") + self.assertTrue(self.duality_dilation_erosion(pattern, length_scale)) + + +class TestMinimumLengthScale(unittest.TestCase): + def test_rounded_square(self): + print("------ Testing minimum length scale of rounded squares ------") + + declared_mls = 50 + print("Declared minimum length scale: ", declared_mls) + + for angle in [5.6, 25.2, 49.3, 69.5]: + pattern = shapes.rounded_square( + RESOLUTION, PHYS_SIZE, declared_mls, angle=angle + ) + solid_mls = imageruler.minimum_length_scale_solid(pattern) + print(f"Rotation angle of the rounded square: {angle}°") + print(f"Estimated minimum length scale: {solid_mls:.2f}") + self.assertAlmostEqual(solid_mls, declared_mls, delta=4) + + def test_disc(self): + print("------ Testing minimum length scale of a shapes.disc ------") + + diameter = 50 + print(f"Declared minimum length scale: {diameter}") + pattern = shapes.disc(RESOLUTION, PHYS_SIZE, diameter) + solid_mls = imageruler.minimum_length_scale_solid(pattern) + print(f"Estimated minimum length scale: {solid_mls:.2f}") + self.assertAlmostEqual(solid_mls, diameter, delta=1) + + def test_ring(self): + print("------ Testing minimum length scale of concentric circles ------") + + outer_diameter, inner_diameter = 120, 50 + declared_solid_mls, declared_void_mls = ( + outer_diameter - inner_diameter + ) / 2, inner_diameter + print( + f"Declared minimum length scale: {declared_solid_mls:.2f} " + f"(solid), {declared_void_mls:.2f} (void)" + ) + + solid_disc = shapes.disc(RESOLUTION, PHYS_SIZE, diameter=outer_diameter) + void_disc = shapes.disc(RESOLUTION, PHYS_SIZE, diameter=inner_diameter) + pattern = solid_disc ^ void_disc # ring + + solid_mls = imageruler.minimum_length_scale_solid(pattern) + void_mls = imageruler.minimum_length_scale_solid(~pattern) + print( + f"Estimated minimum length scale: {solid_mls:.2f} (solid), ", + f"{void_mls:.2f} (void)", + ) + + self.assertAlmostEqual(solid_mls, declared_solid_mls, delta=1) + self.assertAlmostEqual(void_mls, declared_void_mls, delta=1) + + def test_periodicity(self): + print("------ Testing minimum length scale on a periodic image ------") + + shapes.stripe_width = 50 + print(f"Declared minimum length scale: {shapes.stripe_width}") + pattern = shapes.stripe( + RESOLUTION, PHYS_SIZE, shapes.stripe_width, center=(0, -PHYS_SIZE[1] / 2) + ) | shapes.stripe( + RESOLUTION, PHYS_SIZE, shapes.stripe_width, center=(0, PHYS_SIZE[1] / 2) + ) + solid_mls = imageruler.minimum_length_scale_solid( + pattern, periodic=(False, True) + ) + print(f"Estimated minimum length scale: {solid_mls:.2f}") + self.assertAlmostEqual(solid_mls, shapes.stripe_width, delta=1)