From 98ea11e77e3cfb8df73873d49377c29782622df9 Mon Sep 17 00:00:00 2001 From: MartinuzziFrancesco Date: Fri, 25 Jul 2025 11:46:11 +0200 Subject: [PATCH 01/14] feat: initial split of reca models --- Project.toml | 2 - .../.github/dependabot.yml | 7 ++ .../.github/workflows/CI.yml | 79 +++++++++++++++++++ .../.github/workflows/CompatHelper.yml | 16 ++++ .../.github/workflows/TagBot.yml | 31 ++++++++ lib/ReservoirCellularAutomata/.gitignore | 5 ++ lib/ReservoirCellularAutomata/LICENSE | 21 +++++ lib/ReservoirCellularAutomata/Project.toml | 28 +++++++ lib/ReservoirCellularAutomata/README.md | 7 ++ .../docs/Project.toml | 3 + lib/ReservoirCellularAutomata/docs/make.jl | 24 ++++++ .../docs/src/index.md | 14 ++++ .../src/ReservoirCellularAutomata.jl | 22 ++++++ .../ReservoirCellularAutomata/src}/reca.jl | 0 .../src}/reca_input_encodings.jl | 0 lib/ReservoirCellularAutomata/test/qa.jl | 11 +++ .../test/runtests.jl | 10 +++ .../test/test_predictive.jl | 20 +++++ src/ReservoirComputing.jl | 29 +++---- src/generics/linear_regression.jl | 40 ++++++++++ src/{ => generics}/predict.jl | 0 src/{ => generics}/states.jl | 0 src/{esn => inits}/esn_inits.jl | 0 src/{esn => inits}/inits_components.jl | 0 src/{esn => layers}/esn_reservoir_drivers.jl | 0 src/{esn => models}/deepesn.jl | 0 src/{esn => models}/esn.jl | 0 src/{esn => models}/esn_predict.jl | 0 src/{esn => models}/hybridesn.jl | 0 test/runtests.jl | 4 - 30 files changed, 348 insertions(+), 25 deletions(-) create mode 100644 lib/ReservoirCellularAutomata/.github/dependabot.yml create mode 100644 lib/ReservoirCellularAutomata/.github/workflows/CI.yml create mode 100644 lib/ReservoirCellularAutomata/.github/workflows/CompatHelper.yml create mode 100644 lib/ReservoirCellularAutomata/.github/workflows/TagBot.yml create mode 100644 lib/ReservoirCellularAutomata/.gitignore create mode 100644 lib/ReservoirCellularAutomata/LICENSE create mode 100644 lib/ReservoirCellularAutomata/Project.toml create mode 100644 lib/ReservoirCellularAutomata/README.md create mode 100644 lib/ReservoirCellularAutomata/docs/Project.toml create mode 100644 lib/ReservoirCellularAutomata/docs/make.jl create mode 100644 lib/ReservoirCellularAutomata/docs/src/index.md create mode 100644 lib/ReservoirCellularAutomata/src/ReservoirCellularAutomata.jl rename {src/reca => lib/ReservoirCellularAutomata/src}/reca.jl (100%) rename {src/reca => lib/ReservoirCellularAutomata/src}/reca_input_encodings.jl (100%) create mode 100644 lib/ReservoirCellularAutomata/test/qa.jl create mode 100644 lib/ReservoirCellularAutomata/test/runtests.jl create mode 100644 lib/ReservoirCellularAutomata/test/test_predictive.jl create mode 100644 src/generics/linear_regression.jl rename src/{ => generics}/predict.jl (100%) rename src/{ => generics}/states.jl (100%) rename src/{esn => inits}/esn_inits.jl (100%) rename src/{esn => inits}/inits_components.jl (100%) rename src/{esn => layers}/esn_reservoir_drivers.jl (100%) rename src/{esn => models}/deepesn.jl (100%) rename src/{esn => models}/esn.jl (100%) rename src/{esn => models}/esn_predict.jl (100%) rename src/{esn => models}/hybridesn.jl (100%) diff --git a/Project.toml b/Project.toml index 7a0d3f84..8d534e38 100644 --- a/Project.toml +++ b/Project.toml @@ -5,7 +5,6 @@ version = "0.11.3" [deps] Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" -CellularAutomata = "878138dc-5b27-11ea-1a71-cb95d38d6b29" Compat = "34da2185-b29b-5c13-b0c7-acf172513d20" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" NNlib = "872c559c-99b0-510c-b3b7-b6c96a88d5cd" @@ -26,7 +25,6 @@ RCSparseArraysExt = "SparseArrays" [compat] Adapt = "4.1.1" Aqua = "0.8" -CellularAutomata = "0.0.2" Compat = "4.16.0" DifferentialEquations = "7.16.1" LIBSVM = "0.8" diff --git a/lib/ReservoirCellularAutomata/.github/dependabot.yml b/lib/ReservoirCellularAutomata/.github/dependabot.yml new file mode 100644 index 00000000..700707ce --- /dev/null +++ b/lib/ReservoirCellularAutomata/.github/dependabot.yml @@ -0,0 +1,7 @@ +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" # Location of package manifests + schedule: + interval: "weekly" diff --git a/lib/ReservoirCellularAutomata/.github/workflows/CI.yml b/lib/ReservoirCellularAutomata/.github/workflows/CI.yml new file mode 100644 index 00000000..f2afa455 --- /dev/null +++ b/lib/ReservoirCellularAutomata/.github/workflows/CI.yml @@ -0,0 +1,79 @@ +name: CI +on: + push: + branches: + - main + tags: ['*'] + pull_request: + workflow_dispatch: +concurrency: + # Skip intermediate builds: always. + # Cancel intermediate builds: only if it is a pull request build. + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} +jobs: + test: + name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} + runs-on: ${{ matrix.os }} + timeout-minutes: 60 + permissions: # needed to allow julia-actions/cache to proactively delete old caches that it has created + actions: write + contents: read + strategy: + fail-fast: false + matrix: + version: + - '1.10' + - '1.11' + - 'pre' + os: + - ubuntu-latest + arch: + - x64 + - x86 + steps: + - uses: actions/checkout@v4 + - uses: julia-actions/setup-julia@v2 + with: + version: ${{ matrix.version }} + arch: ${{ matrix.arch }} + - uses: julia-actions/cache@v2 + - uses: julia-actions/julia-buildpkg@v1 + - uses: julia-actions/julia-runtest@v1 + - uses: julia-actions/julia-processcoverage@v1 + - uses: codecov/codecov-action@v4 + with: + files: lcov.info + token: ${{ secrets.CODECOV_TOKEN }} + fail_ci_if_error: false + docs: + name: Documentation + runs-on: ubuntu-latest + permissions: + actions: write # needed to allow julia-actions/cache to proactively delete old caches that it has created + contents: write + statuses: write + steps: + - uses: actions/checkout@v4 + - uses: julia-actions/setup-julia@v2 + with: + version: '1' + - uses: julia-actions/cache@v2 + - name: Configure doc environment + shell: julia --project=docs --color=yes {0} + run: | + using Pkg + Pkg.develop(PackageSpec(path=pwd())) + Pkg.instantiate() + - uses: julia-actions/julia-buildpkg@v1 + - uses: julia-actions/julia-docdeploy@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} + - name: Run doctests + shell: julia --project=docs --color=yes {0} + run: | + using Documenter: DocMeta, doctest + using ReservoirCellularAutomata + DocMeta.setdocmeta!(ReservoirCellularAutomata, :DocTestSetup, :(using ReservoirCellularAutomata); recursive=true) + doctest(ReservoirCellularAutomata) diff --git a/lib/ReservoirCellularAutomata/.github/workflows/CompatHelper.yml b/lib/ReservoirCellularAutomata/.github/workflows/CompatHelper.yml new file mode 100644 index 00000000..cba9134c --- /dev/null +++ b/lib/ReservoirCellularAutomata/.github/workflows/CompatHelper.yml @@ -0,0 +1,16 @@ +name: CompatHelper +on: + schedule: + - cron: 0 0 * * * + workflow_dispatch: +jobs: + CompatHelper: + runs-on: ubuntu-latest + steps: + - name: Pkg.add("CompatHelper") + run: julia -e 'using Pkg; Pkg.add("CompatHelper")' + - name: CompatHelper.main() + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + COMPATHELPER_PRIV: ${{ secrets.DOCUMENTER_KEY }} + run: julia -e 'using CompatHelper; CompatHelper.main()' diff --git a/lib/ReservoirCellularAutomata/.github/workflows/TagBot.yml b/lib/ReservoirCellularAutomata/.github/workflows/TagBot.yml new file mode 100644 index 00000000..0cd3114e --- /dev/null +++ b/lib/ReservoirCellularAutomata/.github/workflows/TagBot.yml @@ -0,0 +1,31 @@ +name: TagBot +on: + issue_comment: + types: + - created + workflow_dispatch: + inputs: + lookback: + default: "3" +permissions: + actions: read + checks: read + contents: write + deployments: read + issues: read + discussions: read + packages: read + pages: read + pull-requests: read + repository-projects: read + security-events: read + statuses: read +jobs: + TagBot: + if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot' + runs-on: ubuntu-latest + steps: + - uses: JuliaRegistries/TagBot@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + ssh: ${{ secrets.DOCUMENTER_KEY }} diff --git a/lib/ReservoirCellularAutomata/.gitignore b/lib/ReservoirCellularAutomata/.gitignore new file mode 100644 index 00000000..4bd0c418 --- /dev/null +++ b/lib/ReservoirCellularAutomata/.gitignore @@ -0,0 +1,5 @@ +*.jl.*.cov +*.jl.cov +*.jl.mem +/docs/Manifest*.toml +/docs/build/ diff --git a/lib/ReservoirCellularAutomata/LICENSE b/lib/ReservoirCellularAutomata/LICENSE new file mode 100644 index 00000000..aa0738c7 --- /dev/null +++ b/lib/ReservoirCellularAutomata/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Francesco Martinuzzi + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/lib/ReservoirCellularAutomata/Project.toml b/lib/ReservoirCellularAutomata/Project.toml new file mode 100644 index 00000000..69fe21b0 --- /dev/null +++ b/lib/ReservoirCellularAutomata/Project.toml @@ -0,0 +1,28 @@ +name = "ReservoirCellularAutomata" +uuid = "676858ad-c2be-42d3-9530-1b713c015f0f" +authors = ["Francesco Martinuzzi"] +version = "0.1.0" + +[deps] +CellularAutomata = "878138dc-5b27-11ea-1a71-cb95d38d6b29" +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +Reexport = "189a3867-3050-52da-a836-e630ba90ab69" +ReservoirComputing = "7c2d2b1e-3dd4-11ea-355a-8f6a8116e294" + +[compat] +Aqua = "0.8" +CellularAutomata = "0.0.6" +Random = "1.11.0" +Reexport = "1.2.2" +ReservoirComputing = "0.11.3" +SafeTestsets = "0.1.0" +Test = "1" +julia = "1.10" + +[extras] +Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" +SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[targets] +test = ["Aqua", "Test", "SafeTestsets"] diff --git a/lib/ReservoirCellularAutomata/README.md b/lib/ReservoirCellularAutomata/README.md new file mode 100644 index 00000000..ab99db2f --- /dev/null +++ b/lib/ReservoirCellularAutomata/README.md @@ -0,0 +1,7 @@ +# ReservoirCellularAutomata + +[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://MartinuzziFrancesco.github.io/ReservoirCellularAutomata.jl/stable/) +[![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://MartinuzziFrancesco.github.io/ReservoirCellularAutomata.jl/dev/) +[![Build Status](https://github.com/MartinuzziFrancesco/ReservoirCellularAutomata.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/MartinuzziFrancesco/ReservoirCellularAutomata.jl/actions/workflows/CI.yml?query=branch%3Amain) +[![Coverage](https://codecov.io/gh/MartinuzziFrancesco/ReservoirCellularAutomata.jl/branch/main/graph/badge.svg)](https://codecov.io/gh/MartinuzziFrancesco/ReservoirCellularAutomata.jl) +[![Aqua](https://raw.githubusercontent.com/JuliaTesting/Aqua.jl/master/badge.svg)](https://github.com/JuliaTesting/Aqua.jl) diff --git a/lib/ReservoirCellularAutomata/docs/Project.toml b/lib/ReservoirCellularAutomata/docs/Project.toml new file mode 100644 index 00000000..84a604af --- /dev/null +++ b/lib/ReservoirCellularAutomata/docs/Project.toml @@ -0,0 +1,3 @@ +[deps] +Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +ReservoirCellularAutomata = "676858ad-c2be-42d3-9530-1b713c015f0f" diff --git a/lib/ReservoirCellularAutomata/docs/make.jl b/lib/ReservoirCellularAutomata/docs/make.jl new file mode 100644 index 00000000..7a943fd2 --- /dev/null +++ b/lib/ReservoirCellularAutomata/docs/make.jl @@ -0,0 +1,24 @@ +using ReservoirCellularAutomata +using Documenter + +DocMeta.setdocmeta!(ReservoirCellularAutomata, :DocTestSetup, + :(using ReservoirCellularAutomata); recursive = true) + +makedocs(; + modules = [ReservoirCellularAutomata], + authors = "Francesco Martinuzzi", + sitename = "ReservoirCellularAutomata.jl", + format = Documenter.HTML(; + canonical = "https://MartinuzziFrancesco.github.io/ReservoirCellularAutomata.jl", + edit_link = "main", + assets = String[] + ), + pages = [ + "Home" => "index.md" + ] +) + +deploydocs(; + repo = "github.com/MartinuzziFrancesco/ReservoirCellularAutomata.jl", + devbranch = "main" +) diff --git a/lib/ReservoirCellularAutomata/docs/src/index.md b/lib/ReservoirCellularAutomata/docs/src/index.md new file mode 100644 index 00000000..f47a304a --- /dev/null +++ b/lib/ReservoirCellularAutomata/docs/src/index.md @@ -0,0 +1,14 @@ +```@meta +CurrentModule = ReservoirCellularAutomata +``` + +# ReservoirCellularAutomata + +Documentation for [ReservoirCellularAutomata](https://github.com/MartinuzziFrancesco/ReservoirCellularAutomata.jl). + +```@index +``` + +```@autodocs +Modules = [ReservoirCellularAutomata] +``` diff --git a/lib/ReservoirCellularAutomata/src/ReservoirCellularAutomata.jl b/lib/ReservoirCellularAutomata/src/ReservoirCellularAutomata.jl new file mode 100644 index 00000000..71cf86bb --- /dev/null +++ b/lib/ReservoirCellularAutomata/src/ReservoirCellularAutomata.jl @@ -0,0 +1,22 @@ +module ReservoirCellularAutomata + +using CellularAutomata: CellularAutomaton +using Random: randperm +using Reexport: @reexport +using ReservoirComputing +@reexport import ReservoirComputing: NLADefault, NLAT1, NLAT2, NLAT3, PartialSquare, + ExtendedSquare, + StandardStates, ExtendedStates, PaddedStates, + PaddedExtendedStates, StandardRidge, Generative, + Predictive, OutputLayer +import ReservoirComputing: train, AbstractReservoirComputer, AbstractOutputLayer, + obtain_prediction, next_state_prediction! + +include("reca.jl") +include("reca_input_encodings.jl") + +export RECA +export RandomMapping, RandomMaps +export train + +end diff --git a/src/reca/reca.jl b/lib/ReservoirCellularAutomata/src/reca.jl similarity index 100% rename from src/reca/reca.jl rename to lib/ReservoirCellularAutomata/src/reca.jl diff --git a/src/reca/reca_input_encodings.jl b/lib/ReservoirCellularAutomata/src/reca_input_encodings.jl similarity index 100% rename from src/reca/reca_input_encodings.jl rename to lib/ReservoirCellularAutomata/src/reca_input_encodings.jl diff --git a/lib/ReservoirCellularAutomata/test/qa.jl b/lib/ReservoirCellularAutomata/test/qa.jl new file mode 100644 index 00000000..fa53c976 --- /dev/null +++ b/lib/ReservoirCellularAutomata/test/qa.jl @@ -0,0 +1,11 @@ +using ReservoirCellularAutomata, Aqua +@testset "Aqua" begin + Aqua.find_persistent_tasks_deps(ReservoirCellularAutomata) + Aqua.test_ambiguities(ReservoirCellularAutomata; recursive = false) + Aqua.test_deps_compat(ReservoirCellularAutomata) + Aqua.test_piracies(ReservoirCellularAutomata) + Aqua.test_project_extras(ReservoirCellularAutomata) + Aqua.test_stale_deps(ReservoirCellularAutomata) + Aqua.test_unbound_args(ReservoirCellularAutomata) + Aqua.test_undefined_exports(ReservoirCellularAutomata) +end diff --git a/lib/ReservoirCellularAutomata/test/runtests.jl b/lib/ReservoirCellularAutomata/test/runtests.jl new file mode 100644 index 00000000..8d78160f --- /dev/null +++ b/lib/ReservoirCellularAutomata/test/runtests.jl @@ -0,0 +1,10 @@ +using SafeTestsets +using Test + +@testset "Common Utilities" begin + @safetestset "Quality Assurance" include("qa.jl") +end + +@testset "CA based Reservoirs" begin + @safetestset "RECA" include("test_predictive.jl") +end diff --git a/lib/ReservoirCellularAutomata/test/test_predictive.jl b/lib/ReservoirCellularAutomata/test/test_predictive.jl new file mode 100644 index 00000000..6884b27b --- /dev/null +++ b/lib/ReservoirCellularAutomata/test/test_predictive.jl @@ -0,0 +1,20 @@ +using ReservoirCellularAutomata, CellularAutomata + +const input = ones(2, 10) +const output = zeros(2, 10) +const g = 6 +const rule = 90 + +reca = RECA(input, DCA(rule); + generations = g, + input_encoding = RandomMapping(6, 10)) + +output_layer = train(reca, output, StandardRidge(0.001)) +prediction = reca(Predictive(input), output_layer) +final_pred = convert(AbstractArray{Int}, prediction .> 0.5) +@test final_pred == output + +rm1 = RandomMapping(6, 10) +rm2 = RandomMapping(6; expansion_size = 10) +rm3 = RandomMapping(; permutations = 6, expansion_size = 10) +@test rm1 == rm2 == rm3 diff --git a/src/ReservoirComputing.jl b/src/ReservoirComputing.jl index 028aad50..4181742b 100644 --- a/src/ReservoirComputing.jl +++ b/src/ReservoirComputing.jl @@ -1,7 +1,6 @@ module ReservoirComputing using Adapt: adapt -using CellularAutomata: CellularAutomaton using Compat: @compat using LinearAlgebra: eigvals, mul!, I, qr, Diagonal using NNlib: fast_act, sigmoid @@ -15,24 +14,18 @@ abstract type AbstractReservoirComputer end @compat(public, (create_states)) #general -include("states.jl") -include("predict.jl") - -#general training -include("train/linear_regression.jl") +include("generics/states.jl") +include("generics/predict.jl") +include("generics/linear_regression.jl") #esn -include("esn/inits_components.jl") -include("esn/esn_inits.jl") -include("esn/esn_reservoir_drivers.jl") -include("esn/esn.jl") -include("esn/deepesn.jl") -include("esn/hybridesn.jl") -include("esn/esn_predict.jl") - -#reca -include("reca/reca.jl") -include("reca/reca_input_encodings.jl") +include("inits/inits_components.jl") +include("inits/esn_inits.jl") +include("layers/esn_reservoir_drivers.jl") +include("models/esn.jl") +include("models/deepesn.jl") +include("models/hybridesn.jl") +include("models/esn_predict.jl") export NLADefault, NLAT1, NLAT2, NLAT3, PartialSquare, ExtendedSquare export StandardStates, ExtendedStates, PaddedStates, PaddedExtendedStates @@ -48,8 +41,6 @@ export add_jumps!, backward_connection!, delay_line!, reverse_simple_cycle!, export RNN, MRNN, GRU, GRUParams, FullyGated, Minimal export train export ESN, HybridESN, KnowledgeModel, DeepESN -export RECA -export RandomMapping, RandomMaps export Generative, Predictive, OutputLayer end #module diff --git a/src/generics/linear_regression.jl b/src/generics/linear_regression.jl new file mode 100644 index 00000000..429b816f --- /dev/null +++ b/src/generics/linear_regression.jl @@ -0,0 +1,40 @@ +@doc raw""" + + StandardRidge([Type], [reg]) + +Returns a training method for `train` based on ridge regression. +The equations for ridge regression are as follows: + +```math +\mathbf{w} = (\mathbf{X}^\top \mathbf{X} + +\lambda \mathbf{I})^{-1} \mathbf{X}^\top \mathbf{y} +``` + +# Arguments + - `Type`: type of the regularization argument. Default is inferred internally, + there's usually no need to tweak this + - `reg`: regularization coefficient. Default is set to 0.0 (linear regression). + +``` +""" +struct StandardRidge + reg::Number +end + +function StandardRidge(::Type{T}, reg) where {T <: Number} + return StandardRidge(T.(reg)) +end + +function StandardRidge() + return StandardRidge(0.0) +end + +function train(sr::StandardRidge, states::AbstractArray, target_data::AbstractArray) + n_states = size(states, 1) + A = [states'; sqrt(sr.reg) * I(n_states)] + b = [target_data'; zeros(n_states, size(target_data, 1))] + F = qr(A) + Wt = F \ b + output_layer = Matrix(Wt') + return OutputLayer(sr, output_layer, size(target_data, 1), target_data[:, end]) +end diff --git a/src/predict.jl b/src/generics/predict.jl similarity index 100% rename from src/predict.jl rename to src/generics/predict.jl diff --git a/src/states.jl b/src/generics/states.jl similarity index 100% rename from src/states.jl rename to src/generics/states.jl diff --git a/src/esn/esn_inits.jl b/src/inits/esn_inits.jl similarity index 100% rename from src/esn/esn_inits.jl rename to src/inits/esn_inits.jl diff --git a/src/esn/inits_components.jl b/src/inits/inits_components.jl similarity index 100% rename from src/esn/inits_components.jl rename to src/inits/inits_components.jl diff --git a/src/esn/esn_reservoir_drivers.jl b/src/layers/esn_reservoir_drivers.jl similarity index 100% rename from src/esn/esn_reservoir_drivers.jl rename to src/layers/esn_reservoir_drivers.jl diff --git a/src/esn/deepesn.jl b/src/models/deepesn.jl similarity index 100% rename from src/esn/deepesn.jl rename to src/models/deepesn.jl diff --git a/src/esn/esn.jl b/src/models/esn.jl similarity index 100% rename from src/esn/esn.jl rename to src/models/esn.jl diff --git a/src/esn/esn_predict.jl b/src/models/esn_predict.jl similarity index 100% rename from src/esn/esn_predict.jl rename to src/models/esn_predict.jl diff --git a/src/esn/hybridesn.jl b/src/models/hybridesn.jl similarity index 100% rename from src/esn/hybridesn.jl rename to src/models/hybridesn.jl diff --git a/test/runtests.jl b/test/runtests.jl index 8f051129..3e631748 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -13,7 +13,3 @@ end @safetestset "Hybrid ESN" include("esn/test_hybrid.jl") @safetestset "Deep ESN" include("esn/deepesn.jl") end - -@testset "CA based Reservoirs" begin - @safetestset "RECA" include("reca/test_predictive.jl") -end From 8ac997192b7284ee05f940385b259bc678fb43a1 Mon Sep 17 00:00:00 2001 From: MartinuzziFrancesco Date: Sat, 26 Jul 2025 16:05:45 +0200 Subject: [PATCH 02/14] docs: start splitting reca from main docs --- Project.toml | 2 +- docs/make.jl | 1 + docs/pages.jl | 3 +- lib/ReservoirCellularAutomata/Project.toml | 2 +- lib/ReservoirCellularAutomata/docs/make.jl | 41 +++++++++++-------- lib/ReservoirCellularAutomata/docs/pages.jl | 4 ++ .../docs}/src/api/reca.md | 0 .../docs/src/refs.bib | 21 ++++++++++ lib/ReservoirCellularAutomata/src/reca.jl | 7 +--- .../src/reca_input_encodings.jl | 5 +-- 10 files changed, 55 insertions(+), 31 deletions(-) create mode 100644 lib/ReservoirCellularAutomata/docs/pages.jl rename {docs => lib/ReservoirCellularAutomata/docs}/src/api/reca.md (100%) create mode 100644 lib/ReservoirCellularAutomata/docs/src/refs.bib diff --git a/Project.toml b/Project.toml index 8d534e38..22030750 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "ReservoirComputing" uuid = "7c2d2b1e-3dd4-11ea-355a-8f6a8116e294" authors = ["Francesco Martinuzzi"] -version = "0.11.3" +version = "0.12.0" [deps] Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" diff --git a/docs/make.jl b/docs/make.jl index 3194943c..f1547757 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -15,6 +15,7 @@ bib = CitationBibliography( makedocs(; modules = [ReservoirComputing], sitename = "ReservoirComputing.jl", + authors = "Francesco Martinuzzi", clean = true, doctest = false, linkcheck = true, plugins = [bib], format = Documenter.HTML(; diff --git a/docs/pages.jl b/docs/pages.jl index 773ba0db..345f54fc 100644 --- a/docs/pages.jl +++ b/docs/pages.jl @@ -19,6 +19,5 @@ pages = [ "Echo State Networks" => "api/esn.md", "ESN Initializers" => "api/inits.md", "ESN Drivers" => "api/esn_drivers.md", - "ESN Variations" => "api/esn_variations.md", - "ReCA" => "api/reca.md"] #"References" => "references.md" + "ESN Variations" => "api/esn_variations.md"] ] diff --git a/lib/ReservoirCellularAutomata/Project.toml b/lib/ReservoirCellularAutomata/Project.toml index 69fe21b0..4717e610 100644 --- a/lib/ReservoirCellularAutomata/Project.toml +++ b/lib/ReservoirCellularAutomata/Project.toml @@ -14,7 +14,7 @@ Aqua = "0.8" CellularAutomata = "0.0.6" Random = "1.11.0" Reexport = "1.2.2" -ReservoirComputing = "0.11.3" +ReservoirComputing = "0.12.0" SafeTestsets = "0.1.0" Test = "1" julia = "1.10" diff --git a/lib/ReservoirCellularAutomata/docs/make.jl b/lib/ReservoirCellularAutomata/docs/make.jl index 7a943fd2..e4ba975c 100644 --- a/lib/ReservoirCellularAutomata/docs/make.jl +++ b/lib/ReservoirCellularAutomata/docs/make.jl @@ -1,24 +1,29 @@ -using ReservoirCellularAutomata -using Documenter +using Documenter, DocumenterCitations, ReservoirCellularAutomata -DocMeta.setdocmeta!(ReservoirCellularAutomata, :DocTestSetup, - :(using ReservoirCellularAutomata); recursive = true) +cp("./docs/Manifest.toml", "./docs/src/assets/Manifest.toml"; force = true) +cp("./docs/Project.toml", "./docs/src/assets/Project.toml"; force = true) -makedocs(; - modules = [ReservoirCellularAutomata], - authors = "Francesco Martinuzzi", +ENV["PLOTS_TEST"] = "true" +ENV["GKSwstype"] = "100" +include("pages.jl") +mathengine = Documenter.MathJax() + +bib = CitationBibliography( + joinpath(@__DIR__, "src", "refs.bib"); + style = :authoryear +) + +makedocs(; modules = [ReservoirCellularAutomata], sitename = "ReservoirCellularAutomata.jl", + authors = "Francesco Martinuzzi", + clean = true, doctest = false, linkcheck = true, + plugins = [bib], format = Documenter.HTML(; - canonical = "https://MartinuzziFrancesco.github.io/ReservoirCellularAutomata.jl", - edit_link = "main", - assets = String[] - ), - pages = [ - "Home" => "index.md" - ] + mathengine, + assets = ["assets/favicon.ico"], + canonical = "https://docs.sciml.ai/ReservoirComputing/stable/"), + pages = pages ) -deploydocs(; - repo = "github.com/MartinuzziFrancesco/ReservoirCellularAutomata.jl", - devbranch = "main" -) +deploydocs(; repo = "github.com/SciML/ReservoirComputing.jl.git", + push_preview = true) diff --git a/lib/ReservoirCellularAutomata/docs/pages.jl b/lib/ReservoirCellularAutomata/docs/pages.jl new file mode 100644 index 00000000..f57032f9 --- /dev/null +++ b/lib/ReservoirCellularAutomata/docs/pages.jl @@ -0,0 +1,4 @@ +pages = [ + "ReservoirCellularAutomata.jl" => "index.md", + "API Manual" => "api/reca.md" +] diff --git a/docs/src/api/reca.md b/lib/ReservoirCellularAutomata/docs/src/api/reca.md similarity index 100% rename from docs/src/api/reca.md rename to lib/ReservoirCellularAutomata/docs/src/api/reca.md diff --git a/lib/ReservoirCellularAutomata/docs/src/refs.bib b/lib/ReservoirCellularAutomata/docs/src/refs.bib new file mode 100644 index 00000000..18cff664 --- /dev/null +++ b/lib/ReservoirCellularAutomata/docs/src/refs.bib @@ -0,0 +1,21 @@ +@misc{Yilmaz2014, + doi = {10.48550/ARXIV.1410.0162}, + url = {https://arxiv.org/abs/1410.0162}, + author = {Yilmaz, Ozgur}, + keywords = {Neural and Evolutionary Computing (cs.NE), FOS: Computer and information sciences, FOS: Computer and information sciences}, + title = {Reservoir Computing using Cellular Automata}, + publisher = {arXiv}, + year = {2014}, + copyright = {arXiv.org perpetual, non-exclusive license} +} + +@misc{Nichele2017, + doi = {10.48550/ARXIV.1703.02806}, + url = {https://arxiv.org/abs/1703.02806}, + author = {Nichele, Stefano and Molund, Andreas}, + keywords = {Neural and Evolutionary Computing (cs.NE), Emerging Technologies (cs.ET), FOS: Computer and information sciences, FOS: Computer and information sciences}, + title = {Deep Reservoir Computing Using Cellular Automata}, + publisher = {arXiv}, + year = {2017}, + copyright = {arXiv.org perpetual, non-exclusive license} +} diff --git a/lib/ReservoirCellularAutomata/src/reca.jl b/lib/ReservoirCellularAutomata/src/reca.jl index 8af5b2d3..483dce30 100644 --- a/lib/ReservoirCellularAutomata/src/reca.jl +++ b/lib/ReservoirCellularAutomata/src/reca.jl @@ -18,11 +18,8 @@ end nla_type = NLADefault(), states_type = StandardStates()) -[1] Yilmaz, Ozgur. “_Reservoir computing using cellular automata._” -arXiv preprint arXiv:1410.0162 (2014). - -[2] Nichele, Stefano, and Andreas Molund. “_Deep reservoir computing using cellular -automata._” arXiv preprint arXiv:1703.02806 (2017). +Builds a Resercoir Computing model with cellular automata [Yilmaz2014](@cite) +[Nichele2017](@cite). """ function RECA(train_data, automata; diff --git a/lib/ReservoirCellularAutomata/src/reca_input_encodings.jl b/lib/ReservoirCellularAutomata/src/reca_input_encodings.jl index dd29d72e..33079900 100644 --- a/lib/ReservoirCellularAutomata/src/reca_input_encodings.jl +++ b/lib/ReservoirCellularAutomata/src/reca_input_encodings.jl @@ -14,10 +14,7 @@ end Random mapping of the input data directly in the reservoir. The `expansion_size` determines the dimension of the single reservoir, and `permutations` determines the number of total reservoirs that will be connected, each with a different mapping. -The detail of this implementation can be found in [1]. - -[1] Nichele, Stefano, and Andreas Molund. “Deep reservoir computing using cellular -automata.” arXiv preprint arXiv:1703.02806 (2017). +The detail of this implementation can be found in [Nichele2017](@cite). """ function RandomMapping(; permutations = 8, expansion_size = 40) RandomMapping(permutations, expansion_size) From 8e07b99246f89bcc3c9c8a82ccde27c7fb89c6d7 Mon Sep 17 00:00:00 2001 From: MartinuzziFrancesco Date: Sat, 26 Jul 2025 17:13:29 +0200 Subject: [PATCH 03/14] docs: move reca tutorials over to ReservoirCellularAutomata --- docs/pages.jl | 31 +++++----- docs/src/reca_tutorials/reca.md | 48 --------------- lib/ReservoirCellularAutomata/docs/pages.jl | 1 + .../docs}/src/reca_tutorials/5bitinput.txt | 0 .../docs}/src/reca_tutorials/5bitoutput.txt | 0 .../docs/src/reca_tutorials/fbmt.md | 61 +++++++++++++++++++ .../src/ReservoirCellularAutomata.jl | 11 ++-- 7 files changed, 83 insertions(+), 69 deletions(-) delete mode 100644 docs/src/reca_tutorials/reca.md rename {docs => lib/ReservoirCellularAutomata/docs}/src/reca_tutorials/5bitinput.txt (100%) rename {docs => lib/ReservoirCellularAutomata/docs}/src/reca_tutorials/5bitoutput.txt (100%) create mode 100644 lib/ReservoirCellularAutomata/docs/src/reca_tutorials/fbmt.md diff --git a/docs/pages.jl b/docs/pages.jl index 345f54fc..1c10ee29 100644 --- a/docs/pages.jl +++ b/docs/pages.jl @@ -1,23 +1,22 @@ pages = [ "ReservoirComputing.jl" => "index.md", "General Settings" => Any[ - "Changing Training Algorithms" => "general/different_training.md", - "Altering States" => "general/states_variation.md", - "Generative vs Predictive" => "general/predictive_generative.md"], + "Changing Training Algorithms"=>"general/different_training.md", + "Altering States"=>"general/states_variation.md", + "Generative vs Predictive"=>"general/predictive_generative.md"], "Echo State Network Tutorials" => Any[ - "Lorenz System Forecasting" => "esn_tutorials/lorenz_basic.md", + "Lorenz System Forecasting"=>"esn_tutorials/lorenz_basic.md", #"Mackey-Glass Forecasting on GPU" => "esn_tutorials/mackeyglass_basic.md", - "Using Different Layers" => "esn_tutorials/change_layers.md", - "Using Different Reservoir Drivers" => "esn_tutorials/different_drivers.md", + "Using Different Layers"=>"esn_tutorials/change_layers.md", + "Using Different Reservoir Drivers"=>"esn_tutorials/different_drivers.md", #"Using Different Training Methods" => "esn_tutorials/different_training.md", - "Deep Echo State Networks" => "esn_tutorials/deep_esn.md", - "Hybrid Echo State Networks" => "esn_tutorials/hybrid.md"], - "Reservoir Computing with Cellular Automata" => "reca_tutorials/reca.md", - "API Documentation" => Any["Training Algorithms" => "api/training.md", - "States Modifications" => "api/states.md", - "Prediction Types" => "api/predict.md", - "Echo State Networks" => "api/esn.md", - "ESN Initializers" => "api/inits.md", - "ESN Drivers" => "api/esn_drivers.md", - "ESN Variations" => "api/esn_variations.md"] + "Deep Echo State Networks"=>"esn_tutorials/deep_esn.md", + "Hybrid Echo State Networks"=>"esn_tutorials/hybrid.md"], + "API Documentation" => Any["Training Algorithms"=>"api/training.md", + "States Modifications"=>"api/states.md", + "Prediction Types"=>"api/predict.md", + "Echo State Networks"=>"api/esn.md", + "ESN Initializers"=>"api/inits.md", + "ESN Drivers"=>"api/esn_drivers.md", + "ESN Variations"=>"api/esn_variations.md"] ] diff --git a/docs/src/reca_tutorials/reca.md b/docs/src/reca_tutorials/reca.md deleted file mode 100644 index fe8cdf8d..00000000 --- a/docs/src/reca_tutorials/reca.md +++ /dev/null @@ -1,48 +0,0 @@ -# Reservoir Computing using Cellular Automata - -Reservoir Computing based on Elementary Cellular Automata (ECA) has been recently introduced. Dubbed as ReCA [Yilmaz2014](@cite) [Margem2017](@cite) it proposed the advantage of storing the reservoir states as binary data. Less parameter tuning represents another advantage of this model. The architecture implemented in ReservoirComputing.jl follows [Nichele2017](@cite) which builds on top of the original implementation, improving the results. It is strongly suggested to go through the paper to get a solid understanding of the model before delving into experimentation with the code. - -To showcase how to use these models, this page illustrates the performance of ReCA in the 5 bit memory task. - -## 5 bit memory task - -The data can be read as follows: - -```@example reca -using DelimitedFiles - -input = readdlm("./5bitinput.txt", ',', Float64) -output = readdlm("./5bitoutput.txt", ',', Float64) -``` - -To use a ReCA model, it is necessary to define the rule one intends to use. To do so, ReservoirComputing.jl leverages [CellularAutomata.jl](https://github.com/MartinuzziFrancesco/CellularAutomata.jl) that needs to be called as well to define the `RECA` struct: - -```@example reca -using ReservoirComputing, CellularAutomata - -ca = DCA(90) -``` - -To define the ReCA model, it suffices to call: - -```@example reca -reca = RECA(input, ca; - generations=16, - input_encoding=RandomMapping(16, 40)) -``` - -After this, the training can be performed with the chosen method. - -```@example reca -output_layer = train(reca, output, StandardRidge(0.00001)) -``` - -The prediction in this case will be a `Predictive()` with the input data equal to the training data. In addition, to test the 5 bit memory task, a conversion from Float to Bool is necessary (at the moment, we are aware of a bug that doesn't allow boolean input data to the RECA models): - -```@example reca -prediction = reca(Predictive(input), output_layer) -final_pred = convert(AbstractArray{Float32}, prediction .> 0.5) - -final_pred == output -``` - diff --git a/lib/ReservoirCellularAutomata/docs/pages.jl b/lib/ReservoirCellularAutomata/docs/pages.jl index f57032f9..26e79593 100644 --- a/lib/ReservoirCellularAutomata/docs/pages.jl +++ b/lib/ReservoirCellularAutomata/docs/pages.jl @@ -1,4 +1,5 @@ pages = [ "ReservoirCellularAutomata.jl" => "index.md", + "Solving the 5 bit memory task" => "reca_tutorials/fbmt.md", "API Manual" => "api/reca.md" ] diff --git a/docs/src/reca_tutorials/5bitinput.txt b/lib/ReservoirCellularAutomata/docs/src/reca_tutorials/5bitinput.txt similarity index 100% rename from docs/src/reca_tutorials/5bitinput.txt rename to lib/ReservoirCellularAutomata/docs/src/reca_tutorials/5bitinput.txt diff --git a/docs/src/reca_tutorials/5bitoutput.txt b/lib/ReservoirCellularAutomata/docs/src/reca_tutorials/5bitoutput.txt similarity index 100% rename from docs/src/reca_tutorials/5bitoutput.txt rename to lib/ReservoirCellularAutomata/docs/src/reca_tutorials/5bitoutput.txt diff --git a/lib/ReservoirCellularAutomata/docs/src/reca_tutorials/fbmt.md b/lib/ReservoirCellularAutomata/docs/src/reca_tutorials/fbmt.md new file mode 100644 index 00000000..9938d905 --- /dev/null +++ b/lib/ReservoirCellularAutomata/docs/src/reca_tutorials/fbmt.md @@ -0,0 +1,61 @@ +# Reservoir Computing using Cellular Automata + +Reservoir Computing based on Cellular Automata ReCA +[Yilmaz2014](@cite) [Margem2017](@cite) proposes the advantage of storing the reservoir +states as binary data. Less parameter tuning represents another advantage of this model. +The architecture implemented in ReservoirCellularAutomata.jl follows [Nichele2017](@cite) +which builds on top of the original implementation, improving the results. +It is strongly suggested to go through the paper to get a solid understanding of the model +before delving into experimentation with the code. + +To showcase how to use these models, this page illustrates the performance of +ReCA in the 5 bit memory task. + +## 5 bit memory task + +The data can be read as follows: + +```@example reca +using DelimitedFiles + +input = readdlm("./5bitinput.txt", ',', Float64) +output = readdlm("./5bitoutput.txt", ',', Float64) +``` + +To use a ReCA model, it is necessary to define the rule one intends to use. To do so, +ReservoirCellularAutomata.jl leverages +[CellularAutomata.jl](https://github.com/MartinuzziFrancesco/CellularAutomata.jl). +All the functionalities of CellularAutomata.jl are reexported in ReservoirCellularAutomata. + +```@example reca +using ReservoirCellularAutomata + +ca = DCA(90) +``` + +To define the ReCA model, it suffices to call: + +```@example reca +reca = RECA(input, ca; + generations=16, + input_encoding=RandomMapping(16, 40)) +``` + +After this, the training can be performed with the chosen method. + +```@example reca +output_layer = train(reca, output, StandardRidge(0.00001)) +``` + +The prediction in this case will be a `Predictive()` with the input data +equal to the training data. In addition, to test the 5 bit memory task, +a conversion from Float to Bool is necessary +(at the moment, we are aware of a bug that doesn't allow boolean +input data to the RECA models): + +```@example reca +prediction = reca(Predictive(input), output_layer) +final_pred = convert(AbstractArray{Float32}, prediction .> 0.5) + +final_pred == output +``` diff --git a/lib/ReservoirCellularAutomata/src/ReservoirCellularAutomata.jl b/lib/ReservoirCellularAutomata/src/ReservoirCellularAutomata.jl index 71cf86bb..967c9bab 100644 --- a/lib/ReservoirCellularAutomata/src/ReservoirCellularAutomata.jl +++ b/lib/ReservoirCellularAutomata/src/ReservoirCellularAutomata.jl @@ -4,13 +4,14 @@ using CellularAutomata: CellularAutomaton using Random: randperm using Reexport: @reexport using ReservoirComputing +@reexport using CellularAutomata @reexport import ReservoirComputing: NLADefault, NLAT1, NLAT2, NLAT3, PartialSquare, - ExtendedSquare, - StandardStates, ExtendedStates, PaddedStates, - PaddedExtendedStates, StandardRidge, Generative, - Predictive, OutputLayer + ExtendedSquare, + StandardStates, ExtendedStates, PaddedStates, + PaddedExtendedStates, StandardRidge, Generative, + Predictive, OutputLayer import ReservoirComputing: train, AbstractReservoirComputer, AbstractOutputLayer, - obtain_prediction, next_state_prediction! + obtain_prediction, next_state_prediction! include("reca.jl") include("reca_input_encodings.jl") From 36a033f9002c644ec92463577df318f7dc0437da Mon Sep 17 00:00:00 2001 From: MartinuzziFrancesco Date: Sat, 26 Jul 2025 17:13:50 +0200 Subject: [PATCH 04/14] docs: move reca tutorials over to ReservoirCellularAutomata --- docs/pages.jl | 30 +++++++++---------- .../src/ReservoirCellularAutomata.jl | 10 +++---- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/docs/pages.jl b/docs/pages.jl index 1c10ee29..a5d98610 100644 --- a/docs/pages.jl +++ b/docs/pages.jl @@ -1,22 +1,22 @@ pages = [ "ReservoirComputing.jl" => "index.md", "General Settings" => Any[ - "Changing Training Algorithms"=>"general/different_training.md", - "Altering States"=>"general/states_variation.md", - "Generative vs Predictive"=>"general/predictive_generative.md"], + "Changing Training Algorithms" => "general/different_training.md", + "Altering States" => "general/states_variation.md", + "Generative vs Predictive" => "general/predictive_generative.md"], "Echo State Network Tutorials" => Any[ - "Lorenz System Forecasting"=>"esn_tutorials/lorenz_basic.md", + "Lorenz System Forecasting" => "esn_tutorials/lorenz_basic.md", #"Mackey-Glass Forecasting on GPU" => "esn_tutorials/mackeyglass_basic.md", - "Using Different Layers"=>"esn_tutorials/change_layers.md", - "Using Different Reservoir Drivers"=>"esn_tutorials/different_drivers.md", + "Using Different Layers" => "esn_tutorials/change_layers.md", + "Using Different Reservoir Drivers" => "esn_tutorials/different_drivers.md", #"Using Different Training Methods" => "esn_tutorials/different_training.md", - "Deep Echo State Networks"=>"esn_tutorials/deep_esn.md", - "Hybrid Echo State Networks"=>"esn_tutorials/hybrid.md"], - "API Documentation" => Any["Training Algorithms"=>"api/training.md", - "States Modifications"=>"api/states.md", - "Prediction Types"=>"api/predict.md", - "Echo State Networks"=>"api/esn.md", - "ESN Initializers"=>"api/inits.md", - "ESN Drivers"=>"api/esn_drivers.md", - "ESN Variations"=>"api/esn_variations.md"] + "Deep Echo State Networks" => "esn_tutorials/deep_esn.md", + "Hybrid Echo State Networks" => "esn_tutorials/hybrid.md"], + "API Documentation" => Any["Training Algorithms" => "api/training.md", + "States Modifications" => "api/states.md", + "Prediction Types" => "api/predict.md", + "Echo State Networks" => "api/esn.md", + "ESN Initializers" => "api/inits.md", + "ESN Drivers" => "api/esn_drivers.md", + "ESN Variations" => "api/esn_variations.md"] ] diff --git a/lib/ReservoirCellularAutomata/src/ReservoirCellularAutomata.jl b/lib/ReservoirCellularAutomata/src/ReservoirCellularAutomata.jl index 967c9bab..41e80964 100644 --- a/lib/ReservoirCellularAutomata/src/ReservoirCellularAutomata.jl +++ b/lib/ReservoirCellularAutomata/src/ReservoirCellularAutomata.jl @@ -6,12 +6,12 @@ using Reexport: @reexport using ReservoirComputing @reexport using CellularAutomata @reexport import ReservoirComputing: NLADefault, NLAT1, NLAT2, NLAT3, PartialSquare, - ExtendedSquare, - StandardStates, ExtendedStates, PaddedStates, - PaddedExtendedStates, StandardRidge, Generative, - Predictive, OutputLayer + ExtendedSquare, + StandardStates, ExtendedStates, PaddedStates, + PaddedExtendedStates, StandardRidge, Generative, + Predictive, OutputLayer import ReservoirComputing: train, AbstractReservoirComputer, AbstractOutputLayer, - obtain_prediction, next_state_prediction! + obtain_prediction, next_state_prediction! include("reca.jl") include("reca_input_encodings.jl") From bd35461d70bc4bd4f7745f6c9c082e9d55635236 Mon Sep 17 00:00:00 2001 From: MartinuzziFrancesco Date: Sat, 26 Jul 2025 18:30:01 +0200 Subject: [PATCH 05/14] chore: split test and tag workflows --- .github/workflows/TagBot.yml | 19 ++++- .../TestsReservoirCellularAutomata.yml | 42 ++++++++++ ...{Tests.yml => TestsReservoirComputing.yml} | 2 +- .../.github/dependabot.yml | 7 -- .../.github/workflows/CI.yml | 79 ------------------- .../.github/workflows/CompatHelper.yml | 16 ---- .../.github/workflows/TagBot.yml | 31 -------- 7 files changed, 58 insertions(+), 138 deletions(-) create mode 100644 .github/workflows/TestsReservoirCellularAutomata.yml rename .github/workflows/{Tests.yml => TestsReservoirComputing.yml} (95%) delete mode 100644 lib/ReservoirCellularAutomata/.github/dependabot.yml delete mode 100644 lib/ReservoirCellularAutomata/.github/workflows/CI.yml delete mode 100644 lib/ReservoirCellularAutomata/.github/workflows/CompatHelper.yml delete mode 100644 lib/ReservoirCellularAutomata/.github/workflows/TagBot.yml diff --git a/.github/workflows/TagBot.yml b/.github/workflows/TagBot.yml index 336aa1d5..8c11b545 100644 --- a/.github/workflows/TagBot.yml +++ b/.github/workflows/TagBot.yml @@ -1,3 +1,5 @@ +# Inspiration from https://github.com/JuliaGraphs/GraphNeuralNetworks.jl/blob/master/.github/workflows/TagBot.yml +# and https://github.com/LuxDL/Lux.jl/blob/main/.github/workflows/TagBot.yml name: TagBot on: issue_comment: @@ -21,13 +23,22 @@ permissions: security-events: read statuses: read jobs: - TagBot: + TagBot-ReservoirComputing: if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot' runs-on: ubuntu-latest steps: - - uses: JuliaRegistries/TagBot@62dd7cd21dcde087eca10e70c3fc3f8cefbe44a2 + - name: Tag ReservoirComputing + uses: JuliaRegistries/TagBot@62dd7cd21dcde087eca10e70c3fc3f8cefbe44a2 with: token: ${{ secrets.GITHUB_TOKEN }} - # Edit the following line to reflect the actual name of the GitHub Secret containing your private key ssh: ${{ secrets.DOCUMENTER_KEY }} - # ssh: ${{ secrets.NAME_OF_MY_SSH_PRIVATE_KEY_SECRET }} + TagBot-ReservoirCellularAutomata: + if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot' + runs-on: ubuntu-latest + steps: + - name: Tag ReservoirCellularAutomata + uses: JuliaRegistries/TagBot@62dd7cd21dcde087eca10e70c3fc3f8cefbe44a2 + with: + token: ${{ secrets.GITHUB_TOKEN }} + ssh: ${{ secrets.DOCUMENTER_KEY }} + subdir: "lib/ReservoirCellularAutomata" diff --git a/.github/workflows/TestsReservoirCellularAutomata.yml b/.github/workflows/TestsReservoirCellularAutomata.yml new file mode 100644 index 00000000..79e765b5 --- /dev/null +++ b/.github/workflows/TestsReservoirCellularAutomata.yml @@ -0,0 +1,42 @@ +name: "Tests - ReservoirCellularAutomata" + +on: + pull_request: + branches: + - master + paths: + - "lib/ReservoirCellularAutomata/**" + - ".github/workflows/TestsReservoirCellularAutomata.yml" + paths-ignore: + - 'docs/**' + push: + branches: + - master + paths-ignore: + - 'docs/**' + schedule: + - cron: '33 1 * * 4' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref_name != github.event.repository.default_branch || github.ref != 'refs/tags/v*' }} + +jobs: + tests: + name: "Tests" + strategy: + fail-fast: false + matrix: + version: + - "1" + - "lts" + - "pre" + os: + - "ubuntu-latest" + - "macos-latest" + - "windows-latest" + uses: "SciML/.github/.github/workflows/tests.yml@v1" + with: + julia-version: "${{ matrix.version }}" + os: "${{ matrix.os }}" + secrets: "inherit" \ No newline at end of file diff --git a/.github/workflows/Tests.yml b/.github/workflows/TestsReservoirComputing.yml similarity index 95% rename from .github/workflows/Tests.yml rename to .github/workflows/TestsReservoirComputing.yml index a2b581ed..a53c34ed 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/TestsReservoirComputing.yml @@ -1,4 +1,4 @@ -name: "Tests" +name: "Tests - ReservoirComputing" on: pull_request: diff --git a/lib/ReservoirCellularAutomata/.github/dependabot.yml b/lib/ReservoirCellularAutomata/.github/dependabot.yml deleted file mode 100644 index 700707ce..00000000 --- a/lib/ReservoirCellularAutomata/.github/dependabot.yml +++ /dev/null @@ -1,7 +0,0 @@ -# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates -version: 2 -updates: - - package-ecosystem: "github-actions" - directory: "/" # Location of package manifests - schedule: - interval: "weekly" diff --git a/lib/ReservoirCellularAutomata/.github/workflows/CI.yml b/lib/ReservoirCellularAutomata/.github/workflows/CI.yml deleted file mode 100644 index f2afa455..00000000 --- a/lib/ReservoirCellularAutomata/.github/workflows/CI.yml +++ /dev/null @@ -1,79 +0,0 @@ -name: CI -on: - push: - branches: - - main - tags: ['*'] - pull_request: - workflow_dispatch: -concurrency: - # Skip intermediate builds: always. - # Cancel intermediate builds: only if it is a pull request build. - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} -jobs: - test: - name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - runs-on: ${{ matrix.os }} - timeout-minutes: 60 - permissions: # needed to allow julia-actions/cache to proactively delete old caches that it has created - actions: write - contents: read - strategy: - fail-fast: false - matrix: - version: - - '1.10' - - '1.11' - - 'pre' - os: - - ubuntu-latest - arch: - - x64 - - x86 - steps: - - uses: actions/checkout@v4 - - uses: julia-actions/setup-julia@v2 - with: - version: ${{ matrix.version }} - arch: ${{ matrix.arch }} - - uses: julia-actions/cache@v2 - - uses: julia-actions/julia-buildpkg@v1 - - uses: julia-actions/julia-runtest@v1 - - uses: julia-actions/julia-processcoverage@v1 - - uses: codecov/codecov-action@v4 - with: - files: lcov.info - token: ${{ secrets.CODECOV_TOKEN }} - fail_ci_if_error: false - docs: - name: Documentation - runs-on: ubuntu-latest - permissions: - actions: write # needed to allow julia-actions/cache to proactively delete old caches that it has created - contents: write - statuses: write - steps: - - uses: actions/checkout@v4 - - uses: julia-actions/setup-julia@v2 - with: - version: '1' - - uses: julia-actions/cache@v2 - - name: Configure doc environment - shell: julia --project=docs --color=yes {0} - run: | - using Pkg - Pkg.develop(PackageSpec(path=pwd())) - Pkg.instantiate() - - uses: julia-actions/julia-buildpkg@v1 - - uses: julia-actions/julia-docdeploy@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} - - name: Run doctests - shell: julia --project=docs --color=yes {0} - run: | - using Documenter: DocMeta, doctest - using ReservoirCellularAutomata - DocMeta.setdocmeta!(ReservoirCellularAutomata, :DocTestSetup, :(using ReservoirCellularAutomata); recursive=true) - doctest(ReservoirCellularAutomata) diff --git a/lib/ReservoirCellularAutomata/.github/workflows/CompatHelper.yml b/lib/ReservoirCellularAutomata/.github/workflows/CompatHelper.yml deleted file mode 100644 index cba9134c..00000000 --- a/lib/ReservoirCellularAutomata/.github/workflows/CompatHelper.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: CompatHelper -on: - schedule: - - cron: 0 0 * * * - workflow_dispatch: -jobs: - CompatHelper: - runs-on: ubuntu-latest - steps: - - name: Pkg.add("CompatHelper") - run: julia -e 'using Pkg; Pkg.add("CompatHelper")' - - name: CompatHelper.main() - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - COMPATHELPER_PRIV: ${{ secrets.DOCUMENTER_KEY }} - run: julia -e 'using CompatHelper; CompatHelper.main()' diff --git a/lib/ReservoirCellularAutomata/.github/workflows/TagBot.yml b/lib/ReservoirCellularAutomata/.github/workflows/TagBot.yml deleted file mode 100644 index 0cd3114e..00000000 --- a/lib/ReservoirCellularAutomata/.github/workflows/TagBot.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: TagBot -on: - issue_comment: - types: - - created - workflow_dispatch: - inputs: - lookback: - default: "3" -permissions: - actions: read - checks: read - contents: write - deployments: read - issues: read - discussions: read - packages: read - pages: read - pull-requests: read - repository-projects: read - security-events: read - statuses: read -jobs: - TagBot: - if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot' - runs-on: ubuntu-latest - steps: - - uses: JuliaRegistries/TagBot@v1 - with: - token: ${{ secrets.GITHUB_TOKEN }} - ssh: ${{ secrets.DOCUMENTER_KEY }} From 307969a8b5c81490333b354aa085a6d99720fefa Mon Sep 17 00:00:00 2001 From: MartinuzziFrancesco Date: Sat, 26 Jul 2025 18:36:55 +0200 Subject: [PATCH 06/14] fix(ci): remove path-ignore for reca tests --- .github/workflows/TestsReservoirCellularAutomata.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/TestsReservoirCellularAutomata.yml b/.github/workflows/TestsReservoirCellularAutomata.yml index 79e765b5..d622ea00 100644 --- a/.github/workflows/TestsReservoirCellularAutomata.yml +++ b/.github/workflows/TestsReservoirCellularAutomata.yml @@ -7,8 +7,6 @@ on: paths: - "lib/ReservoirCellularAutomata/**" - ".github/workflows/TestsReservoirCellularAutomata.yml" - paths-ignore: - - 'docs/**' push: branches: - master From 1392a2ea5f7ea853f913dbaef88e3c6cbd6e95cc Mon Sep 17 00:00:00 2001 From: MartinuzziFrancesco Date: Sat, 26 Jul 2025 19:44:46 +0200 Subject: [PATCH 07/14] fix(ci): make reca yml run reca tests --- .github/workflows/TestsReservoirCellularAutomata.yml | 2 +- lib/ReservoirCellularAutomata/test/test_predictive.jl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/TestsReservoirCellularAutomata.yml b/.github/workflows/TestsReservoirCellularAutomata.yml index d622ea00..d58acc14 100644 --- a/.github/workflows/TestsReservoirCellularAutomata.yml +++ b/.github/workflows/TestsReservoirCellularAutomata.yml @@ -21,7 +21,6 @@ concurrency: jobs: tests: - name: "Tests" strategy: fail-fast: false matrix: @@ -37,4 +36,5 @@ jobs: with: julia-version: "${{ matrix.version }}" os: "${{ matrix.os }}" + project: "lib/ReservoirCellularAutomata" secrets: "inherit" \ No newline at end of file diff --git a/lib/ReservoirCellularAutomata/test/test_predictive.jl b/lib/ReservoirCellularAutomata/test/test_predictive.jl index 6884b27b..ef00ea8b 100644 --- a/lib/ReservoirCellularAutomata/test/test_predictive.jl +++ b/lib/ReservoirCellularAutomata/test/test_predictive.jl @@ -1,4 +1,4 @@ -using ReservoirCellularAutomata, CellularAutomata +using ReservoirCellularAutomata const input = ones(2, 10) const output = zeros(2, 10) From c11d5d5204dcc908fa2dbbf1bd6156b00b3695d7 Mon Sep 17 00:00:00 2001 From: MartinuzziFrancesco Date: Sun, 27 Jul 2025 09:58:27 +0200 Subject: [PATCH 08/14] chore: generalize downgrade and compathelper workflows --- .github/workflows/CompatHelper.yml | 4 ++- .github/workflows/Downgrade.yml | 40 ++++++++++++++-------- lib/ReservoirCellularAutomata/Project.toml | 2 +- 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/.github/workflows/CompatHelper.yml b/.github/workflows/CompatHelper.yml index 96cd43f1..3cf1eb24 100644 --- a/.github/workflows/CompatHelper.yml +++ b/.github/workflows/CompatHelper.yml @@ -10,7 +10,9 @@ jobs: steps: - name: Pkg.add("CompatHelper") run: julia -e 'using Pkg; Pkg.add("CompatHelper")' + - name: CompatHelper.main() env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: julia -e 'using CompatHelper; CompatHelper.main(;subdirs=["", "docs"])' + run: julia -e 'using CompatHelper; CompatHelper.main(;subdirs=["", "docs", "lib/ReservoirCellularAutomata", "lib/ReservoirCellularAutomata/docs"])' + diff --git a/.github/workflows/Downgrade.yml b/.github/workflows/Downgrade.yml index 7da86654..0002b1f1 100644 --- a/.github/workflows/Downgrade.yml +++ b/.github/workflows/Downgrade.yml @@ -1,31 +1,36 @@ name: Downgrade + on: pull_request: - branches: - - master - paths-ignore: - - 'docs/**' + branches: [ master ] + paths: + - 'lib/ReservoirCellularAutomata/**' + - '.github/workflows/**' + paths-ignore: [ 'docs/**' ] push: - branches: - - master - paths-ignore: - - 'docs/**' + branches: [ master ] + paths-ignore: [ 'docs/**' ] schedule: - cron: '33 1 * * 4' + jobs: - test: - runs-on: ${{ matrix.os }} + downgrade: strategy: fail-fast: false matrix: - group: - - Core - version: - - '1' + project: + - name: ReservoirComputing + path: . + - name: ReservoirCellularAutomata + path: lib/ReservoirCellularAutomata + version: ['1'] os: - ubuntu-latest - macos-latest - windows-latest + + runs-on: ${{ matrix.os }} + name: Downgrade – ${{ matrix.project.name }} · Julia ${{ matrix.version }} · ${{ matrix.os }} steps: - uses: actions/checkout@v4 - uses: julia-actions/setup-julia@v2 @@ -34,8 +39,15 @@ jobs: - uses: julia-actions/julia-downgrade-compat@v1 with: skip: Pkg, TOML, Test, Random, LinearAlgebra, Statistics, SparseArrays + project: ${{ matrix.project.path }} - uses: julia-actions/cache@v2 with: token: ${{ secrets.GITHUB_TOKEN }} + project: ${{ matrix.project.path }} - uses: julia-actions/julia-buildpkg@v1 + with: + project: ${{ matrix.project.path }} - uses: julia-actions/julia-runtest@v1 + with: + project: ${{ matrix.project.path }} + diff --git a/lib/ReservoirCellularAutomata/Project.toml b/lib/ReservoirCellularAutomata/Project.toml index 4717e610..69fe21b0 100644 --- a/lib/ReservoirCellularAutomata/Project.toml +++ b/lib/ReservoirCellularAutomata/Project.toml @@ -14,7 +14,7 @@ Aqua = "0.8" CellularAutomata = "0.0.6" Random = "1.11.0" Reexport = "1.2.2" -ReservoirComputing = "0.12.0" +ReservoirComputing = "0.11.3" SafeTestsets = "0.1.0" Test = "1" julia = "1.10" From cefa81ba99be7af7fb6769a40528526c49be17ad Mon Sep 17 00:00:00 2001 From: MartinuzziFrancesco Date: Sun, 27 Jul 2025 10:03:38 +0200 Subject: [PATCH 09/14] fix: resolve versioning issues in ReservoirCellularAutomata --- lib/ReservoirCellularAutomata/Project.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ReservoirCellularAutomata/Project.toml b/lib/ReservoirCellularAutomata/Project.toml index 69fe21b0..a83a935f 100644 --- a/lib/ReservoirCellularAutomata/Project.toml +++ b/lib/ReservoirCellularAutomata/Project.toml @@ -12,10 +12,10 @@ ReservoirComputing = "7c2d2b1e-3dd4-11ea-355a-8f6a8116e294" [compat] Aqua = "0.8" CellularAutomata = "0.0.6" -Random = "1.11.0" +Random = "1.10" Reexport = "1.2.2" ReservoirComputing = "0.11.3" -SafeTestsets = "0.1.0" +SafeTestsets = "0.1" Test = "1" julia = "1.10" From c088f7f56afcb81cb34d0839e0eab9336dfb7f8e Mon Sep 17 00:00:00 2001 From: MartinuzziFrancesco Date: Sun, 27 Jul 2025 10:18:17 +0200 Subject: [PATCH 10/14] fix: resolve version issues take 2 --- lib/ReservoirCellularAutomata/Project.toml | 2 +- lib/ReservoirCellularAutomata/src/ReservoirCellularAutomata.jl | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/ReservoirCellularAutomata/Project.toml b/lib/ReservoirCellularAutomata/Project.toml index a83a935f..a3afb13b 100644 --- a/lib/ReservoirCellularAutomata/Project.toml +++ b/lib/ReservoirCellularAutomata/Project.toml @@ -11,7 +11,7 @@ ReservoirComputing = "7c2d2b1e-3dd4-11ea-355a-8f6a8116e294" [compat] Aqua = "0.8" -CellularAutomata = "0.0.6" +CellularAutomata = "0.0.2" Random = "1.10" Reexport = "1.2.2" ReservoirComputing = "0.11.3" diff --git a/lib/ReservoirCellularAutomata/src/ReservoirCellularAutomata.jl b/lib/ReservoirCellularAutomata/src/ReservoirCellularAutomata.jl index 41e80964..e9a1e328 100644 --- a/lib/ReservoirCellularAutomata/src/ReservoirCellularAutomata.jl +++ b/lib/ReservoirCellularAutomata/src/ReservoirCellularAutomata.jl @@ -1,10 +1,9 @@ module ReservoirCellularAutomata -using CellularAutomata: CellularAutomaton using Random: randperm using Reexport: @reexport using ReservoirComputing -@reexport using CellularAutomata +@reexport import CellularAutomata: CellularAutomaton, DCA, CCA, TCA, Life @reexport import ReservoirComputing: NLADefault, NLAT1, NLAT2, NLAT3, PartialSquare, ExtendedSquare, StandardStates, ExtendedStates, PaddedStates, From 9ee511ea9283623d4d61cbae715a0edd9f616b89 Mon Sep 17 00:00:00 2001 From: MartinuzziFrancesco Date: Sun, 27 Jul 2025 12:14:51 +0200 Subject: [PATCH 11/14] fix: remove paths-ignore from Downgrade --- .github/workflows/Downgrade.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/Downgrade.yml b/.github/workflows/Downgrade.yml index 911a82f7..d9d1b83a 100644 --- a/.github/workflows/Downgrade.yml +++ b/.github/workflows/Downgrade.yml @@ -6,7 +6,6 @@ on: paths: - 'lib/ReservoirCellularAutomata/**' - '.github/workflows/**' - paths-ignore: [ 'docs/**' ] push: branches: [ master ] paths-ignore: [ 'docs/**' ] From b65ccf07f8ce1e86ee8d0c360316a907f373703d Mon Sep 17 00:00:00 2001 From: MartinuzziFrancesco Date: Sun, 27 Jul 2025 12:22:34 +0200 Subject: [PATCH 12/14] fix: cleanup Downgrade --- .github/workflows/Downgrade.yml | 47 +++++++++++++++------------------ 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/.github/workflows/Downgrade.yml b/.github/workflows/Downgrade.yml index d9d1b83a..39b555c4 100644 --- a/.github/workflows/Downgrade.yml +++ b/.github/workflows/Downgrade.yml @@ -3,52 +3,49 @@ name: Downgrade on: pull_request: branches: [ master ] - paths: - - 'lib/ReservoirCellularAutomata/**' - - '.github/workflows/**' + paths-ignore: [ 'docs/**' ] push: branches: [ master ] paths-ignore: [ 'docs/**' ] - schedule: - - cron: '33 1 * * 4' jobs: - downgrade: + test: + runs-on: ubuntu-latest + strategy: + fail-fast: false matrix: - project: - name: ReservoirComputing path: . - name: ReservoirCellularAutomata path: lib/ReservoirCellularAutomata - version: ['1'] - os: - - ubuntu-latest - - macos-latest - - windows-latest - - runs-on: ${{ matrix.os }} - name: Downgrade – ${{ matrix.project.name }} · Julia ${{ matrix.version }} · ${{ matrix.os }} + group: ['Core'] + downgrade_mode: ['alldeps'] + julia-version: ['1.10'] + + name: Downgrade – ${{ matrix.project.name }} · Julia ${{ matrix.julia-version }} + steps: - uses: actions/checkout@v4 + - uses: julia-actions/setup-julia@v2 with: - version: ${{ matrix.julia-version }} - - uses: julia-actions/julia-downgrade-compat@v2 -# if: ${{ matrix.version == '1.6' }} - with: + julia-version: ${{ matrix.julia-version }} - skip: Pkg, TOML - project: ${{ matrix.project.path }} - - uses: julia-actions/cache@v2 + - uses: julia-actions/julia-downgrade-compat@v2 with: - token: ${{ secrets.GITHUB_TOKEN }} + skip: Pkg,TOML + mode: ${{ matrix.downgrade_mode }} project: ${{ matrix.project.path }} + - uses: julia-actions/julia-buildpkg@v1 with: project: ${{ matrix.project.path }} + - uses: julia-actions/julia-runtest@v1 with: - project: ${{ matrix.project.path }} - + project: ${{ matrix.project.path }} + allow-reresolve: false + env: + GROUP: ${{ matrix.group }} \ No newline at end of file From e7f5b3c76a6b24691891906baa68bd4562c959be Mon Sep 17 00:00:00 2001 From: MartinuzziFrancesco Date: Sun, 27 Jul 2025 16:22:04 +0200 Subject: [PATCH 13/14] docs: first pass at split docs --- .buildkite/documentation.yml | 17 ++++++++- .../docs/Project.toml | 1 + lib/ReservoirCellularAutomata/docs/make.jl | 34 ++++++++++-------- lib/ReservoirCellularAutomata/docs/pages.jl | 3 +- .../docs/src/assets/favicon.ico | Bin 0 -> 15406 bytes .../docs/src/assets/logo.png | Bin 0 -> 30773 bytes .../docs/src/index.md | 2 +- .../docs/src/references.md | 4 +++ .../docs/src/refs.bib | 7 ++++ 9 files changed, 51 insertions(+), 17 deletions(-) create mode 100644 lib/ReservoirCellularAutomata/docs/src/assets/favicon.ico create mode 100644 lib/ReservoirCellularAutomata/docs/src/assets/logo.png create mode 100644 lib/ReservoirCellularAutomata/docs/src/references.md diff --git a/.buildkite/documentation.yml b/.buildkite/documentation.yml index d0bad413..99ae35f5 100644 --- a/.buildkite/documentation.yml +++ b/.buildkite/documentation.yml @@ -1,5 +1,5 @@ steps: - - label: ":page_facing_up: Build and Deploy Documentation" + - label: ":page_facing_up: Build and Deploy ReservoirComputing Documentation" plugins: - JuliaCI/julia#v1: version: "1" @@ -20,6 +20,21 @@ steps: if: build.message !~ /\[skip docs\]/ && !build.pull_request.draft timeout_in_minutes: 1000 + - label: ":page_facing_up: Build & Deploy ReservoirCellularAutomata Documentation" + plugins: + - JuliaCI/julia#v1: + version: "1" + command: | + julia --project=lib/ReservoirCellularAutomata/docs -e ' + using Pkg; Pkg.instantiate() + include("make.jl") + ' + agents: + queue: "juliagpu" + cuda: "*" + if: build.message !~ /\[skip docs\]/ && !build.pull_request.draft + timeout_in_minutes: 1000 + env: JULIA_PKG_SERVER: "" # it often struggles with our large artifacts SECRET_DOCUMENTER_KEY: "qmrtZ2jy2W0e2h5zu3V7g+wxiz/1BHLsjKGHfosfjxel5nf6/s1mPA+4DEZcBUHwBFt7tfxoKOA6H1gk5PdbyJvFJA6xs4/PT8xvotzv9eYpxtJIoKLRQvjUCq78T+7/0DoicsMNk1uP3/JNkwm4TRLqVXs9QAe9HPnh6x+q/Sro0x9DXIUE2xbTQ3JP6ZUVhS04X7OCeuGTJbW8TdH8B+7V90+gJZcg5a7ctRP/V+PxDo++SOmdyryeqvwE+e6a8+czUWh9gaFQ4dXFRgoUAq+O/jRXSbQfWBXLGaubpMAodgZUmzVSOygELDdRVUhaENgfQfvnUpgpxX8UX/3Bcw==;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" \ No newline at end of file diff --git a/lib/ReservoirCellularAutomata/docs/Project.toml b/lib/ReservoirCellularAutomata/docs/Project.toml index 84a604af..eb247ef9 100644 --- a/lib/ReservoirCellularAutomata/docs/Project.toml +++ b/lib/ReservoirCellularAutomata/docs/Project.toml @@ -1,3 +1,4 @@ [deps] Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +DocumenterCitations = "daee34ce-89f3-4625-b898-19384cb65244" ReservoirCellularAutomata = "676858ad-c2be-42d3-9530-1b713c015f0f" diff --git a/lib/ReservoirCellularAutomata/docs/make.jl b/lib/ReservoirCellularAutomata/docs/make.jl index e4ba975c..dc4ae665 100644 --- a/lib/ReservoirCellularAutomata/docs/make.jl +++ b/lib/ReservoirCellularAutomata/docs/make.jl @@ -1,7 +1,7 @@ using Documenter, DocumenterCitations, ReservoirCellularAutomata -cp("./docs/Manifest.toml", "./docs/src/assets/Manifest.toml"; force = true) -cp("./docs/Project.toml", "./docs/src/assets/Project.toml"; force = true) +#cp("./docs/Manifest.toml", "./docs/src/assets/Manifest.toml"; force=true) +#cp("./docs/Project.toml", "./docs/src/assets/Project.toml"; force=true) ENV["PLOTS_TEST"] = "true" ENV["GKSwstype"] = "100" @@ -10,20 +10,26 @@ mathengine = Documenter.MathJax() bib = CitationBibliography( joinpath(@__DIR__, "src", "refs.bib"); - style = :authoryear + style=:authoryear ) -makedocs(; modules = [ReservoirCellularAutomata], - sitename = "ReservoirCellularAutomata.jl", - authors = "Francesco Martinuzzi", - clean = true, doctest = false, linkcheck = true, - plugins = [bib], - format = Documenter.HTML(; +makedocs(; modules=[ReservoirCellularAutomata], + sitename="ReservoirCellularAutomata.jl", + authors="Francesco Martinuzzi", + clean=true, doctest=false, linkcheck=true, + plugins=[bib], + format=Documenter.HTML(; mathengine, - assets = ["assets/favicon.ico"], - canonical = "https://docs.sciml.ai/ReservoirComputing/stable/"), - pages = pages + assets=["assets/favicon.ico"], + canonical="https://docs.sciml.ai/ReservoirComputing/ReservoirCellularAutomata/"), + pages=pages ) -deploydocs(; repo = "github.com/SciML/ReservoirComputing.jl.git", - push_preview = true) +deploydocs( + repo="github.com/SciML/ReservoirComputing.jl.git", + target="build", + branch="docs-reca", + devbranch="master", + tag_prefix="ReservoirCellularAutomata-", + push_preview=true, +) diff --git a/lib/ReservoirCellularAutomata/docs/pages.jl b/lib/ReservoirCellularAutomata/docs/pages.jl index 26e79593..eb2c9d18 100644 --- a/lib/ReservoirCellularAutomata/docs/pages.jl +++ b/lib/ReservoirCellularAutomata/docs/pages.jl @@ -1,5 +1,6 @@ pages = [ "ReservoirCellularAutomata.jl" => "index.md", "Solving the 5 bit memory task" => "reca_tutorials/fbmt.md", - "API Manual" => "api/reca.md" + "API Manual" => "api/reca.md", + "References" => "references.md" ] diff --git a/lib/ReservoirCellularAutomata/docs/src/assets/favicon.ico b/lib/ReservoirCellularAutomata/docs/src/assets/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..64226497aa8a8e1e1fe8247fb77dc2e9205b139b GIT binary patch literal 15406 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 literal 0 HcmV?d00001 diff --git a/lib/ReservoirCellularAutomata/docs/src/index.md b/lib/ReservoirCellularAutomata/docs/src/index.md index f47a304a..4000ee6d 100644 --- a/lib/ReservoirCellularAutomata/docs/src/index.md +++ b/lib/ReservoirCellularAutomata/docs/src/index.md @@ -4,7 +4,7 @@ CurrentModule = ReservoirCellularAutomata # ReservoirCellularAutomata -Documentation for [ReservoirCellularAutomata](https://github.com/MartinuzziFrancesco/ReservoirCellularAutomata.jl). +Documentation for ReservoirCellularAutomata. ```@index ``` diff --git a/lib/ReservoirCellularAutomata/docs/src/references.md b/lib/ReservoirCellularAutomata/docs/src/references.md new file mode 100644 index 00000000..78f29bc4 --- /dev/null +++ b/lib/ReservoirCellularAutomata/docs/src/references.md @@ -0,0 +1,4 @@ +# References + +```@bibliography +``` diff --git a/lib/ReservoirCellularAutomata/docs/src/refs.bib b/lib/ReservoirCellularAutomata/docs/src/refs.bib index 18cff664..6063c6bf 100644 --- a/lib/ReservoirCellularAutomata/docs/src/refs.bib +++ b/lib/ReservoirCellularAutomata/docs/src/refs.bib @@ -19,3 +19,10 @@ @misc{Nichele2017 year = {2017}, copyright = {arXiv.org perpetual, non-exclusive license} } + +@misc{Margem2017, + title={An experimental study on cellular automata reservoir in pathological sequence learning tasks}, + author={Margem, Mrwan and Yilmaz, Ozg{\"u}r}, + year={2017}, + publisher={Jul} +} From f964b52356d42031bd9de2aaf4fdf63deaf66722 Mon Sep 17 00:00:00 2001 From: MartinuzziFrancesco Date: Tue, 5 Aug 2025 19:44:50 +0200 Subject: [PATCH 14/14] chore: add reca to ext instead of lib --- Project.toml | 3 + .../RCCellularAutomataExt.jl | 74 +++++++++++------- lib/ReservoirCellularAutomata/.gitignore | 5 -- lib/ReservoirCellularAutomata/LICENSE | 21 ----- lib/ReservoirCellularAutomata/Project.toml | 28 ------- lib/ReservoirCellularAutomata/README.md | 7 -- .../docs/Project.toml | 4 - lib/ReservoirCellularAutomata/docs/make.jl | 35 --------- lib/ReservoirCellularAutomata/docs/pages.jl | 6 -- .../docs/src/api/reca.md | 13 --- .../docs/src/assets/favicon.ico | Bin 15406 -> 0 bytes .../docs/src/assets/logo.png | Bin 30773 -> 0 bytes .../docs/src/index.md | 14 ---- .../docs/src/reca_tutorials/5bitinput.txt | 4 - .../docs/src/reca_tutorials/5bitoutput.txt | 4 - .../docs/src/reca_tutorials/fbmt.md | 61 --------------- .../docs/src/references.md | 4 - .../docs/src/refs.bib | 28 ------- .../src/ReservoirCellularAutomata.jl | 22 ------ lib/ReservoirCellularAutomata/src/reca.jl | 61 --------------- lib/ReservoirCellularAutomata/test/qa.jl | 11 --- .../test/runtests.jl | 10 --- .../test/test_predictive.jl | 20 ----- src/ReservoirComputing.jl | 16 ++-- src/extensions/reca.jl | 56 +++++++++++++ 25 files changed, 116 insertions(+), 391 deletions(-) rename lib/ReservoirCellularAutomata/src/reca_input_encodings.jl => ext/RCCellularAutomataExt.jl (52%) delete mode 100644 lib/ReservoirCellularAutomata/.gitignore delete mode 100644 lib/ReservoirCellularAutomata/LICENSE delete mode 100644 lib/ReservoirCellularAutomata/Project.toml delete mode 100644 lib/ReservoirCellularAutomata/README.md delete mode 100644 lib/ReservoirCellularAutomata/docs/Project.toml delete mode 100644 lib/ReservoirCellularAutomata/docs/make.jl delete mode 100644 lib/ReservoirCellularAutomata/docs/pages.jl delete mode 100644 lib/ReservoirCellularAutomata/docs/src/api/reca.md delete mode 100644 lib/ReservoirCellularAutomata/docs/src/assets/favicon.ico delete mode 100644 lib/ReservoirCellularAutomata/docs/src/assets/logo.png delete mode 100644 lib/ReservoirCellularAutomata/docs/src/index.md delete mode 100644 lib/ReservoirCellularAutomata/docs/src/reca_tutorials/5bitinput.txt delete mode 100644 lib/ReservoirCellularAutomata/docs/src/reca_tutorials/5bitoutput.txt delete mode 100644 lib/ReservoirCellularAutomata/docs/src/reca_tutorials/fbmt.md delete mode 100644 lib/ReservoirCellularAutomata/docs/src/references.md delete mode 100644 lib/ReservoirCellularAutomata/docs/src/refs.bib delete mode 100644 lib/ReservoirCellularAutomata/src/ReservoirCellularAutomata.jl delete mode 100644 lib/ReservoirCellularAutomata/src/reca.jl delete mode 100644 lib/ReservoirCellularAutomata/test/qa.jl delete mode 100644 lib/ReservoirCellularAutomata/test/runtests.jl delete mode 100644 lib/ReservoirCellularAutomata/test/test_predictive.jl create mode 100644 src/extensions/reca.jl diff --git a/Project.toml b/Project.toml index 22030750..839d9ded 100644 --- a/Project.toml +++ b/Project.toml @@ -13,11 +13,13 @@ Reexport = "189a3867-3050-52da-a836-e630ba90ab69" WeightInitializers = "d49dbf32-c5c2-4618-8acc-27bb2598ef2d" [weakdeps] +CellularAutomata = "878138dc-5b27-11ea-1a71-cb95d38d6b29" LIBSVM = "b1bec4e5-fd48-53fe-b0cb-9723c09d164b" MLJLinearModels = "6ee0df7b-362f-4a72-a706-9e79364fb692" SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" [extensions] +RCCellularAutomataExt = "CellularAutomata" RCLIBSVMExt = "LIBSVM" RCMLJLinearModelsExt = "MLJLinearModels" RCSparseArraysExt = "SparseArrays" @@ -25,6 +27,7 @@ RCSparseArraysExt = "SparseArrays" [compat] Adapt = "4.1.1" Aqua = "0.8" +CellularAutomata = "0.0.6" Compat = "4.16.0" DifferentialEquations = "7.16.1" LIBSVM = "0.8" diff --git a/lib/ReservoirCellularAutomata/src/reca_input_encodings.jl b/ext/RCCellularAutomataExt.jl similarity index 52% rename from lib/ReservoirCellularAutomata/src/reca_input_encodings.jl rename to ext/RCCellularAutomataExt.jl index 33079900..cfc2ae62 100644 --- a/lib/ReservoirCellularAutomata/src/reca_input_encodings.jl +++ b/ext/RCCellularAutomataExt.jl @@ -1,36 +1,54 @@ -abstract type AbstractInputEncoding end -abstract type AbstractEncodingData end +module RCCellularAutomataExt +using ReservoirComputing: RECA, RandomMapping, RandomMaps +import ReservoirComputing: train, next_state_prediction!, AbstractOutputLayer, NLADefault, StandardStates +using CellularAutomata +using Random: randperm + +function RECA(train_data, + automata; + generations=8, + input_encoding=RandomMapping(), + nla_type=NLADefault(), + states_type=StandardStates()) + in_size = size(train_data, 1) + #res_size = obtain_res_size(input_encoding, generations) + state_encoding = create_encoding(input_encoding, train_data, generations) + states = reca_create_states(state_encoding, automata, train_data) + + return RECA(train_data, automata, state_encoding, nla_type, states, states_type) +end -struct RandomMapping{I, T} <: AbstractInputEncoding - permutations::I - expansion_size::T +#training dispatch +function train(reca::RECA, target_data, training_method=StandardRidge; kwargs...) + states_new = reca.states_type(reca.nla_type, reca.states, reca.train_data) + return train(training_method, Float32.(states_new), Float32.(target_data); kwargs...) end -""" - RandomMapping(permutations, expansion_size) - RandomMapping(permutations; expansion_size=40) - RandomMapping(;permutations=8, expansion_size=40) - -Random mapping of the input data directly in the reservoir. The `expansion_size` -determines the dimension of the single reservoir, and `permutations` determines the -number of total reservoirs that will be connected, each with a different mapping. -The detail of this implementation can be found in [Nichele2017](@cite). -""" -function RandomMapping(; permutations = 8, expansion_size = 40) - RandomMapping(permutations, expansion_size) +#predict dispatch +function (reca::RECA)(prediction, + output_layer::AbstractOutputLayer, + initial_conditions=output_layer.last_value, + last_state=zeros(reca.input_encoding.ca_size)) + return obtain_prediction(reca, prediction, last_state, output_layer; + initial_conditions=initial_conditions) end -function RandomMapping(permutations; expansion_size = 40) +function next_state_prediction!(reca::RECA, x, out, i, args...) + rm = reca.input_encoding + x = encoding(rm, out, x) + ca = CellularAutomaton(reca.automata, x, rm.generations + 1) + ca_states = ca.evolution[2:end, :] + x_new = reshape(transpose(ca_states), rm.states_size) + x = ca.evolution[end, :] + return x, x_new +end + +function RandomMapping(; permutations=8, expansion_size=40) RandomMapping(permutations, expansion_size) end -struct RandomMaps{T, E, G, M, S} <: AbstractEncodingData - permutations::T - expansion_size::E - generations::G - maps::M - states_size::S - ca_size::S +function RandomMapping(permutations; expansion_size=40) + RandomMapping(permutations, expansion_size) end function create_encoding(rm::RandomMapping, input_data, generations) @@ -63,9 +81,9 @@ function encoding(rm::RandomMaps, input_vector, tot_encoded_vector) new_tot_enc_vec = copy(tot_encoded_vector) for i in 1:(rm.permutations) - new_tot_enc_vec[((i - 1) * rm.expansion_size + 1):(i * rm.expansion_size)] = single_encoding( + new_tot_enc_vec[((i-1)*rm.expansion_size+1):(i*rm.expansion_size)] = single_encoding( input_vector, - new_tot_enc_vec[((i - 1) * rm.expansion_size + 1):(i * rm.expansion_size)], + new_tot_enc_vec[((i-1)*rm.expansion_size+1):(i*rm.expansion_size)], rm.maps[i, :]) end @@ -102,3 +120,5 @@ function mapping(input_size, mapped_vector_size) #sample(1:mapped_vector_size, input_size; replace=false) return randperm(mapped_vector_size)[1:input_size] end + +end #module diff --git a/lib/ReservoirCellularAutomata/.gitignore b/lib/ReservoirCellularAutomata/.gitignore deleted file mode 100644 index 4bd0c418..00000000 --- a/lib/ReservoirCellularAutomata/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -*.jl.*.cov -*.jl.cov -*.jl.mem -/docs/Manifest*.toml -/docs/build/ diff --git a/lib/ReservoirCellularAutomata/LICENSE b/lib/ReservoirCellularAutomata/LICENSE deleted file mode 100644 index aa0738c7..00000000 --- a/lib/ReservoirCellularAutomata/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2025 Francesco Martinuzzi - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/lib/ReservoirCellularAutomata/Project.toml b/lib/ReservoirCellularAutomata/Project.toml deleted file mode 100644 index a3afb13b..00000000 --- a/lib/ReservoirCellularAutomata/Project.toml +++ /dev/null @@ -1,28 +0,0 @@ -name = "ReservoirCellularAutomata" -uuid = "676858ad-c2be-42d3-9530-1b713c015f0f" -authors = ["Francesco Martinuzzi"] -version = "0.1.0" - -[deps] -CellularAutomata = "878138dc-5b27-11ea-1a71-cb95d38d6b29" -Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" -Reexport = "189a3867-3050-52da-a836-e630ba90ab69" -ReservoirComputing = "7c2d2b1e-3dd4-11ea-355a-8f6a8116e294" - -[compat] -Aqua = "0.8" -CellularAutomata = "0.0.2" -Random = "1.10" -Reexport = "1.2.2" -ReservoirComputing = "0.11.3" -SafeTestsets = "0.1" -Test = "1" -julia = "1.10" - -[extras] -Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" -SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" -Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[targets] -test = ["Aqua", "Test", "SafeTestsets"] diff --git a/lib/ReservoirCellularAutomata/README.md b/lib/ReservoirCellularAutomata/README.md deleted file mode 100644 index ab99db2f..00000000 --- a/lib/ReservoirCellularAutomata/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# ReservoirCellularAutomata - -[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://MartinuzziFrancesco.github.io/ReservoirCellularAutomata.jl/stable/) -[![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://MartinuzziFrancesco.github.io/ReservoirCellularAutomata.jl/dev/) -[![Build Status](https://github.com/MartinuzziFrancesco/ReservoirCellularAutomata.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/MartinuzziFrancesco/ReservoirCellularAutomata.jl/actions/workflows/CI.yml?query=branch%3Amain) -[![Coverage](https://codecov.io/gh/MartinuzziFrancesco/ReservoirCellularAutomata.jl/branch/main/graph/badge.svg)](https://codecov.io/gh/MartinuzziFrancesco/ReservoirCellularAutomata.jl) -[![Aqua](https://raw.githubusercontent.com/JuliaTesting/Aqua.jl/master/badge.svg)](https://github.com/JuliaTesting/Aqua.jl) diff --git a/lib/ReservoirCellularAutomata/docs/Project.toml b/lib/ReservoirCellularAutomata/docs/Project.toml deleted file mode 100644 index eb247ef9..00000000 --- a/lib/ReservoirCellularAutomata/docs/Project.toml +++ /dev/null @@ -1,4 +0,0 @@ -[deps] -Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -DocumenterCitations = "daee34ce-89f3-4625-b898-19384cb65244" -ReservoirCellularAutomata = "676858ad-c2be-42d3-9530-1b713c015f0f" diff --git a/lib/ReservoirCellularAutomata/docs/make.jl b/lib/ReservoirCellularAutomata/docs/make.jl deleted file mode 100644 index dc4ae665..00000000 --- a/lib/ReservoirCellularAutomata/docs/make.jl +++ /dev/null @@ -1,35 +0,0 @@ -using Documenter, DocumenterCitations, ReservoirCellularAutomata - -#cp("./docs/Manifest.toml", "./docs/src/assets/Manifest.toml"; force=true) -#cp("./docs/Project.toml", "./docs/src/assets/Project.toml"; force=true) - -ENV["PLOTS_TEST"] = "true" -ENV["GKSwstype"] = "100" -include("pages.jl") -mathengine = Documenter.MathJax() - -bib = CitationBibliography( - joinpath(@__DIR__, "src", "refs.bib"); - style=:authoryear -) - -makedocs(; modules=[ReservoirCellularAutomata], - sitename="ReservoirCellularAutomata.jl", - authors="Francesco Martinuzzi", - clean=true, doctest=false, linkcheck=true, - plugins=[bib], - format=Documenter.HTML(; - mathengine, - assets=["assets/favicon.ico"], - canonical="https://docs.sciml.ai/ReservoirComputing/ReservoirCellularAutomata/"), - pages=pages -) - -deploydocs( - repo="github.com/SciML/ReservoirComputing.jl.git", - target="build", - branch="docs-reca", - devbranch="master", - tag_prefix="ReservoirCellularAutomata-", - push_preview=true, -) diff --git a/lib/ReservoirCellularAutomata/docs/pages.jl b/lib/ReservoirCellularAutomata/docs/pages.jl deleted file mode 100644 index eb2c9d18..00000000 --- a/lib/ReservoirCellularAutomata/docs/pages.jl +++ /dev/null @@ -1,6 +0,0 @@ -pages = [ - "ReservoirCellularAutomata.jl" => "index.md", - "Solving the 5 bit memory task" => "reca_tutorials/fbmt.md", - "API Manual" => "api/reca.md", - "References" => "references.md" -] diff --git a/lib/ReservoirCellularAutomata/docs/src/api/reca.md b/lib/ReservoirCellularAutomata/docs/src/api/reca.md deleted file mode 100644 index 48f134dd..00000000 --- a/lib/ReservoirCellularAutomata/docs/src/api/reca.md +++ /dev/null @@ -1,13 +0,0 @@ -# Reservoir Computing with Cellular Automata - -```@docs - RECA -``` - -The input encodings are the equivalent of the input matrices of the ESNs. These are the available encodings: - -```@docs - RandomMapping -``` - -The training and prediction follow the same workflow as the ESN. It is important to note that currently we were unable to find any papers using these models with a `Generative` approach for the prediction, so full support is given only to the `Predictive` method. diff --git a/lib/ReservoirCellularAutomata/docs/src/assets/favicon.ico b/lib/ReservoirCellularAutomata/docs/src/assets/favicon.ico deleted file mode 100644 index 64226497aa8a8e1e1fe8247fb77dc2e9205b139b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15406 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 diff --git a/lib/ReservoirCellularAutomata/docs/src/index.md b/lib/ReservoirCellularAutomata/docs/src/index.md deleted file mode 100644 index 4000ee6d..00000000 --- a/lib/ReservoirCellularAutomata/docs/src/index.md +++ /dev/null @@ -1,14 +0,0 @@ -```@meta -CurrentModule = ReservoirCellularAutomata -``` - -# ReservoirCellularAutomata - -Documentation for ReservoirCellularAutomata. - -```@index -``` - -```@autodocs -Modules = [ReservoirCellularAutomata] -``` diff --git a/lib/ReservoirCellularAutomata/docs/src/reca_tutorials/5bitinput.txt b/lib/ReservoirCellularAutomata/docs/src/reca_tutorials/5bitinput.txt deleted file mode 100644 index 17f7d542..00000000 --- a/lib/ReservoirCellularAutomata/docs/src/reca_tutorials/5bitinput.txt +++ /dev/null @@ -1,4 +0,0 @@ -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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 diff --git a/lib/ReservoirCellularAutomata/docs/src/reca_tutorials/5bitoutput.txt b/lib/ReservoirCellularAutomata/docs/src/reca_tutorials/5bitoutput.txt deleted file mode 100644 index 1771405e..00000000 --- a/lib/ReservoirCellularAutomata/docs/src/reca_tutorials/5bitoutput.txt +++ /dev/null @@ -1,4 +0,0 @@ -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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/lib/ReservoirCellularAutomata/docs/src/reca_tutorials/fbmt.md b/lib/ReservoirCellularAutomata/docs/src/reca_tutorials/fbmt.md deleted file mode 100644 index 9938d905..00000000 --- a/lib/ReservoirCellularAutomata/docs/src/reca_tutorials/fbmt.md +++ /dev/null @@ -1,61 +0,0 @@ -# Reservoir Computing using Cellular Automata - -Reservoir Computing based on Cellular Automata ReCA -[Yilmaz2014](@cite) [Margem2017](@cite) proposes the advantage of storing the reservoir -states as binary data. Less parameter tuning represents another advantage of this model. -The architecture implemented in ReservoirCellularAutomata.jl follows [Nichele2017](@cite) -which builds on top of the original implementation, improving the results. -It is strongly suggested to go through the paper to get a solid understanding of the model -before delving into experimentation with the code. - -To showcase how to use these models, this page illustrates the performance of -ReCA in the 5 bit memory task. - -## 5 bit memory task - -The data can be read as follows: - -```@example reca -using DelimitedFiles - -input = readdlm("./5bitinput.txt", ',', Float64) -output = readdlm("./5bitoutput.txt", ',', Float64) -``` - -To use a ReCA model, it is necessary to define the rule one intends to use. To do so, -ReservoirCellularAutomata.jl leverages -[CellularAutomata.jl](https://github.com/MartinuzziFrancesco/CellularAutomata.jl). -All the functionalities of CellularAutomata.jl are reexported in ReservoirCellularAutomata. - -```@example reca -using ReservoirCellularAutomata - -ca = DCA(90) -``` - -To define the ReCA model, it suffices to call: - -```@example reca -reca = RECA(input, ca; - generations=16, - input_encoding=RandomMapping(16, 40)) -``` - -After this, the training can be performed with the chosen method. - -```@example reca -output_layer = train(reca, output, StandardRidge(0.00001)) -``` - -The prediction in this case will be a `Predictive()` with the input data -equal to the training data. In addition, to test the 5 bit memory task, -a conversion from Float to Bool is necessary -(at the moment, we are aware of a bug that doesn't allow boolean -input data to the RECA models): - -```@example reca -prediction = reca(Predictive(input), output_layer) -final_pred = convert(AbstractArray{Float32}, prediction .> 0.5) - -final_pred == output -``` diff --git a/lib/ReservoirCellularAutomata/docs/src/references.md b/lib/ReservoirCellularAutomata/docs/src/references.md deleted file mode 100644 index 78f29bc4..00000000 --- a/lib/ReservoirCellularAutomata/docs/src/references.md +++ /dev/null @@ -1,4 +0,0 @@ -# References - -```@bibliography -``` diff --git a/lib/ReservoirCellularAutomata/docs/src/refs.bib b/lib/ReservoirCellularAutomata/docs/src/refs.bib deleted file mode 100644 index 6063c6bf..00000000 --- a/lib/ReservoirCellularAutomata/docs/src/refs.bib +++ /dev/null @@ -1,28 +0,0 @@ -@misc{Yilmaz2014, - doi = {10.48550/ARXIV.1410.0162}, - url = {https://arxiv.org/abs/1410.0162}, - author = {Yilmaz, Ozgur}, - keywords = {Neural and Evolutionary Computing (cs.NE), FOS: Computer and information sciences, FOS: Computer and information sciences}, - title = {Reservoir Computing using Cellular Automata}, - publisher = {arXiv}, - year = {2014}, - copyright = {arXiv.org perpetual, non-exclusive license} -} - -@misc{Nichele2017, - doi = {10.48550/ARXIV.1703.02806}, - url = {https://arxiv.org/abs/1703.02806}, - author = {Nichele, Stefano and Molund, Andreas}, - keywords = {Neural and Evolutionary Computing (cs.NE), Emerging Technologies (cs.ET), FOS: Computer and information sciences, FOS: Computer and information sciences}, - title = {Deep Reservoir Computing Using Cellular Automata}, - publisher = {arXiv}, - year = {2017}, - copyright = {arXiv.org perpetual, non-exclusive license} -} - -@misc{Margem2017, - title={An experimental study on cellular automata reservoir in pathological sequence learning tasks}, - author={Margem, Mrwan and Yilmaz, Ozg{\"u}r}, - year={2017}, - publisher={Jul} -} diff --git a/lib/ReservoirCellularAutomata/src/ReservoirCellularAutomata.jl b/lib/ReservoirCellularAutomata/src/ReservoirCellularAutomata.jl deleted file mode 100644 index e9a1e328..00000000 --- a/lib/ReservoirCellularAutomata/src/ReservoirCellularAutomata.jl +++ /dev/null @@ -1,22 +0,0 @@ -module ReservoirCellularAutomata - -using Random: randperm -using Reexport: @reexport -using ReservoirComputing -@reexport import CellularAutomata: CellularAutomaton, DCA, CCA, TCA, Life -@reexport import ReservoirComputing: NLADefault, NLAT1, NLAT2, NLAT3, PartialSquare, - ExtendedSquare, - StandardStates, ExtendedStates, PaddedStates, - PaddedExtendedStates, StandardRidge, Generative, - Predictive, OutputLayer -import ReservoirComputing: train, AbstractReservoirComputer, AbstractOutputLayer, - obtain_prediction, next_state_prediction! - -include("reca.jl") -include("reca_input_encodings.jl") - -export RECA -export RandomMapping, RandomMaps -export train - -end diff --git a/lib/ReservoirCellularAutomata/src/reca.jl b/lib/ReservoirCellularAutomata/src/reca.jl deleted file mode 100644 index 483dce30..00000000 --- a/lib/ReservoirCellularAutomata/src/reca.jl +++ /dev/null @@ -1,61 +0,0 @@ -abstract type AbstractReca <: AbstractReservoirComputer end - -struct RECA{S, R, E, T, Q} <: AbstractReca - #res_size::I - train_data::S - automata::R - input_encoding::E - nla_type::ReservoirComputing.NonLinearAlgorithm - states::T - states_type::Q -end - -""" - RECA(train_data, - automata; - generations = 8, - input_encoding=RandomMapping(), - nla_type = NLADefault(), - states_type = StandardStates()) - -Builds a Resercoir Computing model with cellular automata [Yilmaz2014](@cite) -[Nichele2017](@cite). -""" -function RECA(train_data, - automata; - generations = 8, - input_encoding = RandomMapping(), - nla_type = NLADefault(), - states_type = StandardStates()) - in_size = size(train_data, 1) - #res_size = obtain_res_size(input_encoding, generations) - state_encoding = create_encoding(input_encoding, train_data, generations) - states = reca_create_states(state_encoding, automata, train_data) - - return RECA(train_data, automata, state_encoding, nla_type, states, states_type) -end - -#training dispatch -function train(reca::AbstractReca, target_data, training_method = StandardRidge; kwargs...) - states_new = reca.states_type(reca.nla_type, reca.states, reca.train_data) - return train(training_method, Float32.(states_new), Float32.(target_data); kwargs...) -end - -#predict dispatch -function (reca::RECA)(prediction, - output_layer::AbstractOutputLayer, - initial_conditions = output_layer.last_value, - last_state = zeros(reca.input_encoding.ca_size)) - return obtain_prediction(reca, prediction, last_state, output_layer; - initial_conditions = initial_conditions) -end - -function next_state_prediction!(reca::RECA, x, out, i, args...) - rm = reca.input_encoding - x = encoding(rm, out, x) - ca = CellularAutomaton(reca.automata, x, rm.generations + 1) - ca_states = ca.evolution[2:end, :] - x_new = reshape(transpose(ca_states), rm.states_size) - x = ca.evolution[end, :] - return x, x_new -end diff --git a/lib/ReservoirCellularAutomata/test/qa.jl b/lib/ReservoirCellularAutomata/test/qa.jl deleted file mode 100644 index fa53c976..00000000 --- a/lib/ReservoirCellularAutomata/test/qa.jl +++ /dev/null @@ -1,11 +0,0 @@ -using ReservoirCellularAutomata, Aqua -@testset "Aqua" begin - Aqua.find_persistent_tasks_deps(ReservoirCellularAutomata) - Aqua.test_ambiguities(ReservoirCellularAutomata; recursive = false) - Aqua.test_deps_compat(ReservoirCellularAutomata) - Aqua.test_piracies(ReservoirCellularAutomata) - Aqua.test_project_extras(ReservoirCellularAutomata) - Aqua.test_stale_deps(ReservoirCellularAutomata) - Aqua.test_unbound_args(ReservoirCellularAutomata) - Aqua.test_undefined_exports(ReservoirCellularAutomata) -end diff --git a/lib/ReservoirCellularAutomata/test/runtests.jl b/lib/ReservoirCellularAutomata/test/runtests.jl deleted file mode 100644 index 8d78160f..00000000 --- a/lib/ReservoirCellularAutomata/test/runtests.jl +++ /dev/null @@ -1,10 +0,0 @@ -using SafeTestsets -using Test - -@testset "Common Utilities" begin - @safetestset "Quality Assurance" include("qa.jl") -end - -@testset "CA based Reservoirs" begin - @safetestset "RECA" include("test_predictive.jl") -end diff --git a/lib/ReservoirCellularAutomata/test/test_predictive.jl b/lib/ReservoirCellularAutomata/test/test_predictive.jl deleted file mode 100644 index ef00ea8b..00000000 --- a/lib/ReservoirCellularAutomata/test/test_predictive.jl +++ /dev/null @@ -1,20 +0,0 @@ -using ReservoirCellularAutomata - -const input = ones(2, 10) -const output = zeros(2, 10) -const g = 6 -const rule = 90 - -reca = RECA(input, DCA(rule); - generations = g, - input_encoding = RandomMapping(6, 10)) - -output_layer = train(reca, output, StandardRidge(0.001)) -prediction = reca(Predictive(input), output_layer) -final_pred = convert(AbstractArray{Int}, prediction .> 0.5) -@test final_pred == output - -rm1 = RandomMapping(6, 10) -rm2 = RandomMapping(6; expansion_size = 10) -rm3 = RandomMapping(; permutations = 6, expansion_size = 10) -@test rm1 == rm2 == rm3 diff --git a/src/ReservoirComputing.jl b/src/ReservoirComputing.jl index 4181742b..8470d2df 100644 --- a/src/ReservoirComputing.jl +++ b/src/ReservoirComputing.jl @@ -17,7 +17,8 @@ abstract type AbstractReservoirComputer end include("generics/states.jl") include("generics/predict.jl") include("generics/linear_regression.jl") - +#extensions +include("extensions/reca.jl") #esn include("inits/inits_components.jl") include("inits/esn_inits.jl") @@ -31,16 +32,19 @@ export NLADefault, NLAT1, NLAT2, NLAT3, PartialSquare, ExtendedSquare export StandardStates, ExtendedStates, PaddedStates, PaddedExtendedStates export StandardRidge export chebyshev_mapping, informed_init, logistic_mapping, minimal_init, - modified_lm, scaled_rand, weighted_init, weighted_minimal + modified_lm, scaled_rand, weighted_init, weighted_minimal export block_diagonal, chaotic_init, cycle_jumps, delay_line, delay_line_backward, - double_cycle, forward_connection, low_connectivity, pseudo_svd, rand_sparse, - selfloop_cycle, selfloop_delayline_backward, selfloop_feedback_cycle, - selfloop_forward_connection, simple_cycle, true_double_cycle + double_cycle, forward_connection, low_connectivity, pseudo_svd, rand_sparse, + selfloop_cycle, selfloop_delayline_backward, selfloop_feedback_cycle, + selfloop_forward_connection, simple_cycle, true_double_cycle export add_jumps!, backward_connection!, delay_line!, reverse_simple_cycle!, - scale_radius!, self_loop!, simple_cycle! + scale_radius!, self_loop!, simple_cycle! export RNN, MRNN, GRU, GRUParams, FullyGated, Minimal export train export ESN, HybridESN, KnowledgeModel, DeepESN export Generative, Predictive, OutputLayer +#reca +export RECA +export RandomMapping, RandomMaps end #module diff --git a/src/extensions/reca.jl b/src/extensions/reca.jl new file mode 100644 index 00000000..82c59e23 --- /dev/null +++ b/src/extensions/reca.jl @@ -0,0 +1,56 @@ +abstract type AbstractInputEncoding end +abstract type AbstractEncodingData end + +""" + RandomMapping(permutations, expansion_size) + RandomMapping(permutations; expansion_size=40) + RandomMapping(;permutations=8, expansion_size=40) + +Random mapping of the input data directly in the reservoir. The `expansion_size` +determines the dimension of the single reservoir, and `permutations` determines the +number of total reservoirs that will be connected, each with a different mapping. +The detail of this implementation can be found in [1]. + +[1] Nichele, Stefano, and Andreas Molund. “Deep reservoir computing using cellular +automata.” arXiv preprint arXiv:1703.02806 (2017). +""" +struct RandomMapping{I,T} <: AbstractInputEncoding + permutations::I + expansion_size::T +end + +struct RandomMaps{T,E,G,M,S} <: AbstractEncodingData + permutations::T + expansion_size::E + generations::G + maps::M + states_size::S + ca_size::S +end + + +abstract type AbstractReca <: AbstractReservoirComputer end + +""" + RECA(train_data, + automata; + generations = 8, + input_encoding=RandomMapping(), + nla_type = NLADefault(), + states_type = StandardStates()) + +[1] Yilmaz, Ozgur. “_Reservoir computing using cellular automata._” +arXiv preprint arXiv:1410.0162 (2014). + +[2] Nichele, Stefano, and Andreas Molund. “_Deep reservoir computing using cellular +automata._” arXiv preprint arXiv:1703.02806 (2017). +""" +struct RECA{S,R,E,T,Q} <: AbstractReca + #res_size::I + train_data::S + automata::R + input_encoding::E + nla_type::ReservoirComputing.NonLinearAlgorithm + states::T + states_type::Q +end